i have the following issue, after perform the login, the system load the main page, its like 5 seconds doing it, so after that, the script should type over 3 fields and perform a tab to get more info, but the thing is that sometimes is working and sometimes does not, in 5 chances, only one worked, i do not know if its something about the time to get all fields or something like that, am using IE 9 cause the app only works on IE
HereĀ“s the code:
`
System.setProperty("webdriver.ie.driver","C:\\Apps\\eclipse\\IEDriverServer.ex;
WebDriver driver = new InternetExplorerDriver();
driver.get("http://15.192.41.95/Cabina/asp/Login.asp");
WebElement text1 = driver.findElement(By.id("text1"));
text1.sendKeys("xxxx");
WebElement password1 = driver.findElement(By.id("password1"));
password1.sendKeys("xxxx");
WebElement aceptar = driver.findElement(By.id("ok1"));
aceptar.click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.switchTo().frame(driver.findElement(By.name("menu")));
WebElement txtNumPolSol = driver.findElement (By.id("txtNumPolSol"));
txtNumPolSol.sendKeys("877885");
WebElement Text8 = driver.findElement(By.name("txtNumofic"));
Text8.sendKeys("228");
WebElement txtCveInc = driver.findElement(By.name("txtCveInc"));
txtCveInc.sendKeys("1");
WebElement clave = driver.findElement(By.id("txtCveInc"));
clave.sendKeys(Keys.TAB);
driver.switchTo().frame(driver.findElement(By.name("dest")));
WebElement txtNomrepo = driver.findElement(By.id("txtNomrepo"));
txtNomrepo.sendKeys("Jorge Villarreal");
driver.findElement(By.id("txtRelacion")).sendKeys("Conductor");
WebElement txtTelrepo = driver.findElement(By.id("txtTelrepo"));
txtTelrepo.sendKeys("83029090");`
Here the different issues i got:
1) Unable to find element with name == txtOficina
2) Element is no longer valid
3) Unable to find element with id == txtCveInc (the field is there)
4) Unable to find element with name == txtCveInc (the field is there)
The steps that the system to get the issues are:
1) Log in (so far so good)
2) The system load the main page (the page has frames and gets all fields in 5 secs...)
3) The script type over the txtNumPolSol, txtNumofic and txtCveInc (most of the issues are in the last two fields)
4) The script performs a tab
5) The system load the some information regarding the record and the script continue...
Note: Almost all the issues occur on step 3...
Thanks for your feedback!
This sounds like a timing problem. Your simulated user is proceeding faster than the page becomes ready. Depending on the timing of the page loading, different problems occur.
The solution is to add a wait after steps that trigger a DOM change than influences your next step, but doesn't cause WebDriver to wait before returning. Google 'webdriver wait for element' to get lots of ways to do it.
I was also facing the similar kind of problem but i tried to find the elements with Css_Selectors and X paths instead of ids, that worked for me
The key here is to add atleast 1 second of implicit wait after every action, i.e. send keys etc. It will allow 'driver.findElement' enough time to find the element. Though I would suggest keeping this code in a testBase or a reusable method.
driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
It will help in making your webtests less flaky.
Related
It might be something obvious I've missed, but I've been staring at it for so long now that I decided to post it here_
I have this snipppet of markup for a submit button:
<button class="hb-knapp hb-knapp--standard" id="lastOpp_SOSIALE_UTFORDRINGER_03077000045_soker__"
type="button" data-e2e-selector="lastOpp_SOSIALE_UTFORDRINGER_03077000045_soker__"><!----><hb-ikon
class="hb-knapp-ikon" _nghost-rmd-c56=""><span _ngcontent-rmd-c56="" class="hb-ikon hb-ikon--
focusable="false"></span><!----></hb-ikon><!----><!----><span translate="" class="hb-knapp-
tekst">Last opp vedlegg<!----></span><!----><!----></button>
I'm trying to verify the visibility of the button by using "beginning with", since the number towards the end of the id and data-e2e-selector is dynamic.
So I'm trying this:
return driver.findElement(By.cssSelector("[id^=lastOpp_SOSIALE_UTFORDRINGER_]")).isDisplayed();
and this:
return driver.findElement(By.cssSelector("[data-e2e-selector^=lastOpp_SOSIALE_UTFORDRINGER_]")).isDisplayed();
Both yields the "Unable to locate element" error:
Unable to locate element: {"method":"css selector","selector":"[id^=lastOpp_SOSIALE_UTFORDRINGER_]"}
What on earth am I not seeing here? As far as I can see, I'm looking for the exact same locator(s) that are plainly visible in the markup?
EDIT:
I also tried using xpath, like this
return driver.findElement(By.xpath("//*[contains(#data-e2e-selector, 'lastOpp_SOSIALE_UTFORDRINGER_')]")).isDisplayed();
and this
return driver.findElement(By.xpath("//*[contains(#dataid, 'lastOpp_SOSIALE_UTFORDRINGER_')]")).isDisplayed();
with the exact same result. This seems completely bonkers.
EDIT2:
An also, of course, as a last test: The exact id:
boolean is = driver.findElement(By.id("lastOpp_SOSIALE_UTFORDRINGER_28037800130_soker__")).isDisplayed();
also returns "element not found".
The strange thing is - other elements on the same page are both visible and interactable.
EDIT3:
Tried adding a manual WebDriverWait, but even then Selenium insists on not finding the element:
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("lastOpp_SOSIALE_UTFORDRINGER_28037800130_soker__")));
or
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='lastOpp_SOSIALE_UTFORDRINGER_13108100073_soker__']")));
(The xpath is copied directly from the browser - Chrome.)
Result:
Expected condition failed: waiting for visibility of element located by By.id: lastOpp_SOSIALE_UTFORDRINGER_28037800130_soker__ (tried for 5 second(s) with 500 milliseconds interval)
And I'm watching the page, staring at the element in question, as the wait times out.
EDIT4: Snapshot of the html markup
Based on https://sqa.stackexchange.com/a/7889 and https://stackoverflow.com/a/39594489, I think the problem is that you need specify that you're looking for a button.
Try the following:
driver.findElement(By.cssSelector("button[id^=lastOpp_SOSIALE_UTFORDRINGER_]"))
I have to test an e-shop. The users can add items to their cart.
When the cart is empty, a special section with id "empty-basket" is created. If the cart is not empty, this section's id becomes "basket".
I use Java and Selenium 3.9
These are my two selectors
#FindBy(how = How.CSS, using = "#empty-basket > section")
private WebElement conteneur_panier_vide;
#FindBy(how = How.CSS, using = "#basket > section:nth-child(1)")
private WebElement conteneur_panier_non_vide;
To check if the bloc containing the elements is well formed, I check if there is one of the sections described above. I use this piece of code to do so:
this.wait.until(
ExpectedConditions.or(
ExpectedConditions.visibilityOf(conteneur_panier_vide),
ExpectedConditions.visibilityOf(conteneur_panier_non_vide)
)
);
However, this gives me an error
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for at least one condition to be
valid
Surprised, I tried this:
this.wait.until(ExpectedConditions.visibilityOf(conteneur_panier_vide))
on a page with an empty basket. It works, the WebElement is found.
I then tried this:
this.wait.until(
ExpectedConditions.or(
ExpectedConditions.visibilityOf(conteneur_panier_vide),
)
);
And it works as well. It means that adding a non-existing element to the 'or' breaks it, which is exactly the opposite of what it should be.
Does anyone have an idea of why my code is not working?
Edit: SOLVED!
The problem was that the element I was looking for was not on the page when the or function is called, resulting in the malfunctioning mentioned above.
I simply put
this.wait.until(ExpectedConditions.urlContains(MY_CART_URL));
which ensures the presence of one of the two sections.
There are two things you can do to clean this up:
Create a CSS selector that matches both elements
Use ExpectedConditions.visibilityOfElementLocated(By.css(...)) instead of the more complicated or
// CSS selectors can be separated by a comma (,)
String cssSelector = "#empty-basket > section, #basket > section:nth-child(1)";
this.wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector));
Your original problem was that using the conteneur_panier_vide and conteneur_panier_non_vide attributes was causing Selenium to attempt to fetch them. You just need to wait for the appearance of either element.
Have you instantiated your wait object? You didn't specify your environment but here's what I do in
C#
var wait = new WebDriverWait( Driver, TimeSpan.FromSeconds( 10 ) );
Java
WebDriverWait wait = new WebDriverWait(driver, 20);
I did solve the problem, and edited the question to let people know.
TL;DR:
I needed some delay before calling the or function, and did so by waiting for the URL to be the right one.
I am new to selenium (but experienced java developer).
I am using something like below:
WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));
WebElement searchproduct = pDriver.findElement(By.xpath("//a[contains(.,'Search a product')]"));
//if search an agreement is not show up, then click on other menu, then click it back
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]")).click();
// click on search an agreement
try {
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
action = new Actions(pDriver);
action.moveToElement(searchBasket).build().perform();
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search a product')]")));
searchproduct.click();
} catch (TimeoutException e) {
}
where pWait is:
WebDriverWait wait = new WebDriverWait(driver, 15);
however when I run the test case I get below error:
Unable to locate element: {"method":"xpath","selector":"//a[contains(.,'Search&Baskets')]"}
Command duration or timeout: 4 milliseconds
I thought it should have wait atleast 15 seconds before throwing this exception. From the log above it looks like it threw exception only in 4ms.
and i could see on console that as soon as it hit that line, it threw exception.
I have implicit waiting set as 0 and using explicit wait.
Am i missing anything here.
Also, in explicit and implicit wait, is it upto that much time OR exact that much time,
example if I set implicit wait as 10 sec, then does it mean wait for exact 10 sec OR wait upto 10 sec (if element found then proceed, even if element founf on 6th second)
is above same for explicit wait as well?
Please help
Let us analyze what is happening in our code.
We have defined two WebElements searchBasket and searchproduct as follows :
WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));
WebElement searchproduct = pDriver.findElement(By.xpath("//a[contains(.,'Search a product')]"));
We havn't tried to use those WebElements in our code at immediate basis, so had No Impact.
Next, we tried WebDriverWait for an WebElement as follows :
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
Again we didn't capture the return type of the result, so had No Impact.
Now, within the try{} block we have again tried WebDriverWait:
pWait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
But again we havn't captured/acted on the return type of the result. That's why moving ahead when we did :
action.moveToElement(searchBasket).build().perform();
searchBasket referred to the WebElement which we have stored earlier as :
WebElement searchBasket = pDriver.findElement(By.xpath("//a[contains(.,'Search&Baskets')]"));
As this first search result (which was without WebDriverWait) may not have returned any WebElement at all and have returned Null.
Finally, the most important factor for the error Unable to locate element: {"method":"xpath","selector":"//a[contains(.,'Search&Baskets')]"} is, the
WebDriverWait instance was wait. Instead of using wait we have always tried to use pWait
So for all these reasons, WebDriverWait was never implemented properly in our code.
Mixing up ImplicitWait & ExplicitWait
The Selenium Documentation clearly mentions the following :
WARNING: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
ExpectedConditions.elementToBeClickable invokes isDisplayed() and isEnabled() methods on EXISTING WebElement.
You are providing By as a parameter which means, the driver has to find your element first. It failed to do this.
Make sure your element is present by using wait until presenceOfElementLocatedBy(By by).
Example:
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfElementLocatedBy(By.xpath("//a[contains(.,'Search&Baskets')]")));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[contains(.,'Search&Baskets')]")));
I created few test cases on Selenium using Java. Unfortunately when I click an element on the page, before I could move on to any other action, I have to wait till the page loads.
I have tried driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);. Unfortunately this creates another problem. Even if the page loads, it waits 30 seconds before it started testing on the page.
What I found the best way is to send ESCAPE key to stop page load.
Is there anyway I could check if an element exists and when it does, send ESCAPE key to the browser to stop page load?
This part is bugging my mind as I have to wait till page loads before Java reads the next line of the code so I can't send ESCAPE key to browser till the page actually stops loading.
Edit
I have just tried using a new thread to do the job but it seems driver is completely locked out, can't do any process on it before page stops loading.
I'm out of ideas for the moment but I believe there should be a way.
Using timeouts() is causing whole test case to stop.
First I'd like to say this isn't a best practice. The selenium click method states that if the click triggers a page load, selenium will do its best to block until the page is loaded. Instead of clicking via the click method you could try sending the click event via JavaScript. Then wait for the element like normal.
You can try driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS); It is supposed to throw an error after timeout is over. I have never used it but maybe you can try and catch this error and continue with your test. But your page could end up in an unstable state with everything not loading and test interacts with elements.
I did it in C#, scenario is the same elsewhere.
Define driver like this:
var firefoxOptions = new FirefoxOptions();
firefoxOptions.PageLoadStrategy = PageLoadStrategy.None;
driver = new FirefoxDriver(firefoxOptions);
PageLoadStrategy.None means when open a URL, continue to next line regardless of the results and do not wait to load the page.
Usually, it takes some seconds to load a page and element appears, suppose I'm waiting for email_user element to appears:
int user_emailID = 0, popupAlert = 0;
do
{
float timeToWait = 0;
driver.Navigate().GoToUrl("https://stackoverflow.com");
do
{
await Task.Delay(500);
timeToWait += 0.5F;
user_emailID = driver.FindElements(By.XPath("//input[#id=\'user_email\']")).Count;
}
while (user_emailID == 0 && timeToWait < 10);
if (user_emailID == 1)
{
//Element exists now!do something and don't wait for page to load completely
}
}
while (user_emailID != 1);
More explanation: when open a URL, first loop check the presence of element every 0.5 second, if it appears, the loop stops. If after 10 seconds it couldn't find the element, the page will reloaded !!
Hope this get you the idea.
Remember, exception must not happen in your codes !!
I'm using webdriver(java) for a unique test where a page reloads itself when you log on, I've been unable to wait for the element to load because it is already there before the reload. So far the only way I've been able to get it to work is to use a thread.sleep, is there a way to listen for a page refresh?
One way to solve this is, to get a reference to the element you need, that appears both on the login-page and the reloaded page.
Then you can use the ExpectedConditions.stalenessOf to occur, and then you can be sure, that the element is removed from the DOM and a new element is created. Well, the last part is not guaranteed by this method, but at least you know that the old element is gone.
The code could look something like this:
WebElement elementOldPage = driver.findElement(By.id("yourid"));
... do login etc ...
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.stalenessOf(elementOldPage));
WebElement elementNewPage = driver.findElement(By.id("yourid"));
Building upon the accepted answer from Kim Schiller one might be interested in the following piece of code. It is surely not perfect due to the sleeps, so be free to suggest improvements to make it more bulletproof. Also note I'm no expert with selenium.
The if branch waits for the top level node in the html to go stale in case of a page reload. The else branch simply waits until the drivers url matches the request url in case we load a different page.
def safe_page_load(url):
if driver.current_url == url:
tmp = driver.find_element_by_xpath('/html')
driver.get(url)
WebDriverWait(driver, 2).until(ExpectedConditions.staleness_of(tmp))
else:
driver.get(url)
while(driver.current_url) != url:
sleep(0.3)
sleep(0.3)
Happy if I could help someone.