Selenium: why is sleep apparently needed before clicking? - selenium-webdriver

Selenium 2.25, Firefox, OSX ML.
I have Selenium click a button that has an Ajax impact.
Then I want to interact with the results. Without the sleep below, I get an error that the click fails because it cannot scroll the click target into view. I don't get it. What's going on?
WebElement sampleComboInput = driver.findElement(By.id("sampleCombo-inputEl"));
sampleComboInput.click();
sampleComboInput.sendKeys("English-03.txt");
sampleComboInput.sendKeys(Keys.TAB, Keys.TAB);
WebElement goButton = driver.findElement(By.id("inputDialogGoButton-btnInnerEl"));
goButton.click();
WebElement resultsSpan = driver.findElement(By.cssSelector("span.ne-type-node.PERSON"));
assertTrue(resultsSpan.isDisplayed());
assertEquals("PERSON (3)", resultsSpan.getText());
WebElement parent = resultsSpan.findElement(By.xpath(".."));
Thread.sleep(5000); // without sleep, get error unable to scroll
Actions action = new Actions(driver);
action.doubleClick(parent);
action.perform();

it needs to wait for the element to load, have you tried waitForVisible instead? It might be more efficent also using Sleep may cause your code to not function on other machines where the wait time can be longer

You should try to avoid using Thread.Sleep as it will work inconsistently. Space ranger is right that it needs to wait for the element to load.
The c# version has the "WebDriverWait" class and the "Until" method. Using these two you can wait for elements to load.
Look at the answer by Loudenvier to this post:
Selenium c# Webdriver: Wait Until Element is Present
This is the way I prefer. Simple to use, easily reusable, and avoids issues related to Thread.Sleep.

Related

Why explicit wait is waiting for entire wait time even though element is visible/clickable before the wait time is over

I have given a wait time for 60 sec, and i am using wait until element to be clickable/visible but script is waiting for whole 30 secs even though the element is visible on UI and also clickable?
I tried using latest selenium version, tried using different waits also using different locators. but it did not work
The reasons could be in:
The element belongs to iframe so you need to switch to the iframe prior to attempting locating anything inside it
The element belongs to Shadow DOM so you need to locate ShadowRoot object, cast it to the WebElement and find the sub-element you want to click
Your locator is not correct, try getting the page source and saving it to a file. Once done use your favourite browser developer tools to locate the elemen
The syntax of your Explicit Wait is not correct. Check out Explicit Waits and How to use Selenium to test web applications using AJAX technology for code examples
Going forward consider adding page source and your code to your question as the chance you will get the comprehensive answer will be much higher, otherwise we have to go for "blind shots"

Random Popups While Automating the Webpage

I was attending an interview and he gave me the following scenarios . If I could get an hint as I could not answer the questions.
Assume that there is an application and popups keep coming up all the time. These are not times, its just random. You never know when they are going to come. How to deal with it?
Assume that the script you wrote is fine. But due to network issues the objects in the page are really slow to load or the page itself is taking long time. How do you deal with such a scenario?
Assume that I have 5-6 pages in the application. In all the pages we have certain text fields. In page 1 and Page 5 there is an object which is a text box. I see that what ever whatever identification method (css, xpath, id etc) you take, the values are same. That is duplicates. How do you deal with this scenario?
What is the basic purpose of "data provider" annotation in TestNG. In genral, what is the purpose of testng annotations?
Thanks.
Assume that the script you wrote is fine. But due to network issues the objects in the page are really slow to load or the page itself is taking long time.
How do you deal with such a scenario. In such situation, You should Wait property of Selenium. Implicit Wait or Explicit wait.
Implicit Wait -- Used for setting Timeout for Webpage loading
Driverobject.manage().timeouts().PageLoadtimeOut(units,TimeUnit.SECONDS);
Explicit Wait-- Used for setting Timeout for particular
Webelement FirefoxDriver f = new FirefoxDriver();
WebDriverWait ww = new WebDriverWait(f,Units);
ww.until(ExpectedConditions.CONDITION);
For second question, Anubhav has answered it.
For third, even if elements are same for the page1 and page5, they can be differentiated. First, switch to page to, whose text field you want to interact with, and then interact with that text field.
For forth, dataprovider is an annotation in TestNG using which you can do data driven testing and using TestNG annotations, you can manage test execution flow of your tests. For more details of dataprovider and TestNG annotation, please go here
For third, If you open 5-6 the pages in different tabs of single browser you will get such a duplication problem. That time only one page is visible to the end user. So we can differentiate that element by visibility and can interact with that element using webdriver
List<WebElement> el=driver.findElements(By.xpath("xpath of that text element"));//you can use other than xpath too to identify the elements
for(int i=0;i<el.size();i++)
{
if(el.get(i).isDisplayed())
el.get(i).sendKeys("text you want to send");//any other action you want to perform
break;
}

how to resolve race conditions in webdriver

I have an app that uses a mixture of angular and asp.net. My issue is that the home page is redirected by setting window.location and then the required data and page is requested form the server.
Previously this was not the case and all routing was done via the angular app. However due to requirements the applications routing had to be changed to what it is now.
Now because the application requires a server side request/response (I believe) this is causing a race condition in my tests as I only receive the expected result once in every 5 tests.
At present I am not able to provide code to explain my situation. However, I will be albe to provide some code in a edit later today.
The only code I can provide for now would be the test that is being run. Although I do not believe this would help without the code running the application.
Recent frameworks have this feature where it sets the document.readState of browser to complete and the content is loaded afterwards. Due to this the test may fails as we will be expecting an element to be present.
For such conditions you have to use explicit wait for the element to be present for which you want to take an action after the page is loaded or changed.
Here is an example how we wait for elements in our project (The application is also angularjs, we use Java for webdriver):
In our Webdriver implementation we added:
private WebDriverWait iWait(int timeoutInSeconds) {
return new WebDriverWait(webDriver, timeoutInSeconds);
}
we want to wait for an element to be visible ("Visibility means that the element is not only displayed but also has a height and width that is greater than 0"):
public void waitForElementToAppear(By by, int timeoutInSeconds) {
iWait(timeoutInSeconds).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.visibilityOfElementLocated(by));
}
the ExpectedConditions class provides many other out of the box condition, here are some:
elementToBeClickable
textToBePresentInElement
titleContains
elementSelectionStateToBe
for more, please look at the ExpectedConditions Javadoc
if you need to create your own conditions, you can use ExoectedCondition (no 's') class
ExpectedCondition Javadoc

How do I reliably check the current page after navigation in Selenium WebDriver?

In my web tests using Selenium WebDriver and IEDriverServer.exe 2.32.3.0, I need to check the title of the current page after navigating to a certain URL. Here's the code:
_webDriver.Navigate().GoToUrl("...");
Assert.That(_webDriver.Title, Is.EqualTo("..."));
This sometimes works, but sporadically breaks - the title is not as expected (but still the one from the page before).
I've read on StackOverflow (C# Webdriver - Page Title assert fails before page loads) that IWebDriver.Title property does not auto-wait for navigation to complete (why doesn't it?), but instead you need to manually wait using the WebDriverWait API.
I implemented manual waiting for the title:
var wait = new WebDriverWait(_webDriver, TimeSpan.FromSeconds (3.0));
wait.Until(d => d.Title == expectedTitle);
However, this sometimes waits for 3 seconds, then throws a WebDriverTimeoutException. The build agent running the code is quite fast and the web site I'm testing is trivial (just starting development), so I'm quite sure that it can't really take 3 seconds to navigate. I noticed that on the other StackOverflow question, the original poster also got the WebDriverTimeoutException and just caught and ignored it.
I found that solution a little flaky, so I tried a different workaround. I gave the <title> attribute an ID in my HTML and used IWebDriver.FindElement, which is supposed to wait for the page to complete:
Assert.That(_webDriver.FindElement(By.Id(ViewIDs.Shared._Layout.Title)).Text, Is.EqualTo(page.ExpectedTitle));
At first, that seemed to work. However, it doesn't reliably, it sometimes throws:
OpenQA.Selenium.NoSuchElementException : Unable to find element with id == _Layout-title
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElement(String mechanism, String value)
at OpenQA.Selenium.By.FindElement(ISearchContext context)
at ...
(I also tried upgrading to WebDriver/IEDriverServer 2.33.0.0; but in that version, the text of the <title> tag is always empty...)
Hence my question. How do I reliably check the current page after navigation in Selenium WebDriver? Is there a good pattern that works?
I just solved it with stuff I derived from something I found on CodeProject:
private void WaitUntilLoaded()
{
var wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(%));
wait.Until(x =>
{
return ((IJavaScriptExecutor)this.driver)
.ExecuteScript("return document.readyState").Equals("complete");
});
}
According to w3schools it works for most popular browsers.
As I presently test on Firefox I ended up on Mozilla's own page about how to recognise a page as loaded. IMHO read worth to avoid dragons.
That gave me
wait.Until(p => p.FindElement(
By.Id("somethingThatIsDisplayedWhenMyAsyncronousStuffIsFinished")
).Displayed);
which saved my day.
I have run into very similar issues. I still have not been able to tell why but often if you try to use an element without doing a isElementPresent check it will fail occasionally. My solution is mildly "expensive" but I have not found a reliable alternative as yet.
My example is in java, shouldn't be hard to translate but I don't have the libraries.
waitForElement("_Layout-title", 45);
then continue with your code
Assert.That(_webDriver.FindElement(By.Id(ViewIDs.Shared._Layout.Title)).Text, Is.EqualTo(page.ExpectedTitle));
This tries a set number of times, in this case 45, to find the element. Once id=_Layout-title is present it will continue to the next line of code and do the assert. While it isn't perfect, it did make my test much more stable.

Unable to find element using selenium webdriver

I am executing 1000 tests using selenium webdriver.
for each test case I need to click "ID" element on the webpage.
I used WebElement x = driver.findElement(By.xpath("//*[#id='TEST']").click(); event.
But unfortunately for couple of test scenarios (2 or 3 out of 1000) it is throwing an error saying that "Unable to find an element". for the remaining test cases it is executing as usual.
I tried to use Try & Catch methods & Refresh the page but functionality is working as usual but performance is too slow.
Have you tried using the ExpectedConditions class ( http://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/support/ui/ExpectedConditions.html )
Should be enough to just add some wait for the elementToBeClickable before clicking it.
What do you mean by "Try & Catch methods & Refresh methods".
Selenium imitates a web browser itself, thus it is sometimes unstable.
1000 tests takes a lot of time, so make sure your computer doesn't fall asleep and don't disturb it's test process untill it is done.
Some tests will fail if you minimize the browser.
I would recommend possibly increasing your implicit wait. Something like
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);

Resources