Script hangs because page loads too quickly? - selenium-webdriver

I am seeing a problem with either Robot Framework or Selenium Webdriver in cases where a link or element is clicked that results in a page transition. The script hangs & stops running as if it's trying & failing to click the requested element/link even though the window successfully processed the click. Manually refreshing the Webdriver window to reload the page kick-starts the script and it resumes from there.
The only thing I can think is there is a delay between when Selenium or Robot executes the command and when it's able to listen for an HTTP response from the browser, and the page is loading before Selenium is ready to listen for it. This is running on an intranet and so the page load times are pretty quick. I've never seen the issue happen when running the same script on a SauceLabs VM since the tunnel between us & them adds a lot of latency.
Assuming my theory is correct, what do I do about it (apart from the obvious running over a slower connection)? Setting a delay in Selenium only slows down the execution and doesn't really affect the problem.

You can try fluent wait...
public static WebElement fluentWait(final By locator, RemoteWebDriver rwd){
Wait<WebDriver> wait = new FluentWait<WebDriver>(rwd)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(2, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo;
};
This will poll every 2 seconds and wait a maximum of 30 seconds
in your Test you then wait for an element eg fluentWait(By.className("home"), driver);
before you can click or verify text etc

Try:
Set Selenium Implicit Wait 60
Set Browser Implicit Wait 60
The number 60 is the seconds to wait by default for both selenium/browser.

Related

Jmeter WebDriverSampler fail with Chromedriver headless

I have some tests with WebDriverSampler in Jmeter that work correctly with chromedriver. It is a selenium script that opens a web page and checks that it contains a series of elements. Everything works right until I've tried with the chromedriver headless option.
In this case I get the exception "Expected condition failed: waiting for presence of element located by: By.xpath: ..." as if that element did not exist yet to be loaded. I do not know what can happen, because if I stop using the headless option, if everything works correctly and find the element that really exists.
This is an example of code used(it works without the headless option):
var wait = new support_ui.WebDriverWait(WDS.browser, 30);
var conditions = org.openqa.selenium.support.ui.ExpectedConditions
WDS.sampleResult.sampleStart();
WDS.sampleResult.getLatency();
WDS.browser.get('http://mi-app/');
try{
wait.until(conditions.presenceOfElementLocated(pkg.By.xpath('/ruta_de elemento_existente')));
WDS.log.info('OK')
}catch(e){
WDS.sampleResult.setSuccessful(false);
WDS.sampleResult.setResponseMessage('Fail');
WDS.log.error(e.message)
}
try{
wait.until(conditions.presenceOfElementLocated(pkg.By.xpath('/ruta_de elemento2_existente')));
WDS.log.info('OK2')
}catch(e){
WDS.sampleResult.setSuccessful(false);
WDS.sampleResult.setResponseMessage('Fail2');
WDS.log.error(e.message)
}
WDS.sampleResult.sampleEnd();
I hope someone can help me with this problem, because I need to use the headless option. Thank you very much for your time.
You can print the page source to jmeter.log file by using the following function:
WDS.log.info(WDS.browser.getPageSource())
Or even save it into a separate file like:
org.apache.commons.io.FileUtils.writeStringToFile(new java.io.File('test.html'), WDS.browser.getPageSource())
Or take screenshot on failure like:
WDS.browser.getScreenshotAs(org.openqa.selenium.OutputType.FILE).renameTo(new java.io.File('test.png'))
Check out The WebDriver Sampler: Your Top 10 Questions Answered article for more information.
Also be aware that if the machine where you run your Selenium tests doesn't have GUI you can still normally launch browsers using i.e. Xvfb on Linux or under Local System account on Windows

How to make selenium 3.4.0 wait for page load?

I am using selenium web driver 3.4.0 to find the response time of a website..In earlier version , I have used
WebDriver wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myId"))); to find the page loaded.
But these two lines of code not working for version 3.4.0. is there any other way to calculate the load time of a page? Or wait until the page gets loaded? Also I need to detect the modal dialog which will be loaded on button click.
I am implementing using dynamic web project in eclipse IDE.
I also need to wait for some moment until some click event finished loading Dom element. Wait.until() is not working for selenium 3.4.0. how to make selenium wait until some element is visible ?
You can use JavascriptExecutor to get the ready state of the page, and pass it as an expected condition to your wait.until()
Here is the reference code for this,
ExpectedCondition<Boolean> expectation = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete");
}
};
try {
Thread.sleep(1000);
WebDriverWait wait = new WebDriverWait(LocalDriverManager.getDriver(), 30);
wait.until(expectation);
} catch (Throwable error) {
Assert.fail("Timeout waiting for Page Load Request to complete.");
}

Selenium Web-Driver Popup

I am unable to write on this popup message using selenium.
Please feel free to help me in this case.
My Code is:-
public static void main(String[] args)
{
System.setProperty("webdriver.gecko.driver", "F:\\gecko_driver\\geckodriver-
v0.16.1-win64\\geckodriver.exe");
WebDriver driver= new FirefoxDriver();
driver.get("https://www.heycare.com");
driver.findElement(By.xpath("html/body/div[2]/header/div/nav/div/a")).click();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
System.out.println("hello world-----1");
driver.switchTo().frame(0);
driver.findElement(By.id("mobile")).sendKeys("7015273543");
System.out.println("hello world-----2");
//Driver.findElement(By.id("mobile")).sendKeys("7015273543");
driver.findElement(By.id("Pass")).sendKeys("123456");
}
Error:-
Exception in thread "main" org.openqa.selenium.NoSuchElementException: Unable to locate element: *[name='mobile']
Code is working fine till:-
driver.findElement(By.xpath("html/body/div[2]/header/div/nav/div/a")).click();
Unable to write on that popup form that comes after clicking on the login button..
I navigated to that website and successfully targetted the mobile number field using this css selector #mobile which targets the id attribute. You're doing this for your password field. Try having your test use this:
Driver.findElement(By.id("mobile")).sendKeys("7015273543");
See if that helps...
Edit: I'm not sure that the unformatted code block you're showing that switches frames is necessary. Unless you're working with iframes, I didn't see any in the minute I was looking around.
Edit2:
WebDriver driver = new FirefoxDriver();
driver.get("https://www.heycare.com");
System.out.println("hello world");
driver.findElement(By.className("log-pop")).click();
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.elementToBeClickable(By.name("mobile")));
driver.findElement(By.name("mobile")).sendKeys("7015273543");
driver.findElement(By.id("Pass")).sendKeys("123456");
You could try something like this, I added in a call to WebDriverWait to account for the possible delay between clicking the login button, and waiting for the login prompt popup to finish it's animation prior to be allowed to be clicked. I'm not sure if this will work in your case, but it's a possibility I sniffed out when I was observing the site's behavior.
(I didn't test any of this code, it's freehand written. So take it with a grain of salt. It might not work flawlessly as is.
Bit of java nit, you should make your object references lowercase, save capitalized symbols for class names. I had a moment of trying to figure out why you were calling static methods of a class called Driver instead of an instance of the class WebDriver

How do I get Selenium to wait for a page to load fully before executing the click() command

My problem:
I am running phpunit with Selenium to test a website on a server that is on the other side of the world. So, there is a delay of a few seconds for things like clicking on a tab or a new page. I start Selenium Server with Chromedriver.
eg.
public function setUp()
{
$this->setHost('localhost'); // Set the hostname for the connection to the Selenium server.
$this->setPort(4444); // set port # for connection to selenium server
$this->setBrowser('chrome'); // set the browser to be used
$this->setBrowserUrl('https://www.*.com'); // set base URL for tests
$this->prepareSession()->currentWindow()->maximize(); // Maximize the window when the test starts
$this->timeouts()->implicitWait(30000); // Wait up to 30 seconds for all elements to appear
}
public function testLoginToeSeaCare(){
$this->timeouts()->implicitWait(10000); // Wait up to 10 seconds for all elements to appear
$url = 'https://www.*.com';
$loginName = 'Ned';
$loginPassword = 'Flanders';
$this->url($url); // Load this url
$this->timeouts()->implicitWait(30000); // Wait up to 30 seconds for all elements to appear
$username = $this->byId('username'); // Search page for input that has an id = 'username' and assign it to $username
$password = $this->byId('password'); // Search page for input that has an id = 'password' and assign it to $password
$this->byId('username')->value($loginName); // Enter the $loginName text in username field
$this->byId('password')->value($loginPassword); // Enter the $loginPassword in password field
$this->byCssSelector('form')->submit(); // submit the form
$tab1Link = $this->byLinkText("Tab1"); // Search for the textlink Tab1
$this->assertEquals('Tab1', $tab1Link->text()); // assert tab text is present
$this->timeouts()->implicitWait(10000); // Wait up to 10 seconds for all elements to appear
$tab2Link = $this->byLinkText("Tab2");
$tab2Link->click(); // Click 'Tab2' tab
}
There is an error reported when the above is run and I capture it in an xml file:
********::testSearch PHPUnit_Extensions_Selenium2TestCase_WebDriverException: unknown error: Element ... is not clickable at point (430, 139). Other element would receive the click: (Session info: chrome=57.0.2987.133) (Driver info: chromedriver=2.29.461591 (62ebf098771772160f391d75e589dc567915b233)
What I am trying to do is to wait for the DOM to be completely loaded before clicking on a button. But I get the above error intermittently. Does anyone know a way around this?? Its driving me nuts!!
Try the Explicit Waits.
"An explicit wait is the code you define to wait for a certain condition to occur before proceeding further in the code. There are some convenience methods provided that help you write code that will wait only as long as required. WebDriverWait in combination with ExpectedCondition is one way this can be accomplished."
For example,
// Wait for the page title to be 'My Page'.
// Default wait (= 30 sec)
$driver->wait()->until(WebDriverExpectedCondition::titleIs('My Page'));
// Wait for at most 10s and retry every 500ms if it the title is not correct.
$driver->wait(10, 500)->until(WebDriverExpectedCondition::titleIs('My Page'));
There are many prepared conditions you can pass to the until() method. All of them subclass WebDriverExpectedCondition, including elementToBeClickable() (https://github.com/facebook/php-webdriver/wiki/HowTo-Wait).
I don't know if this will help you
but in java there is a method to wait for a certain item to be visible
Here is how it is written
WebDriverWait Wait=new WebDriverWait(Driver, 10);
Wait.until(ExpectedConditions.visibilityOf(Driver.findElement(By.//your element locator)));
Sorry I don't know how to write it in PHP

Are there situations where an ExplictWait is not working?

I know about the three different types of waiting you can use in Selenium. I know why Thread.Sleep and ImplicitWait are never a good choice. So I'm always using ExplicitWaits, for instance to wait till a button is clickable. However, from time to time one or two tests in a collection of hundred tests fails because the Explictwait seems to fail.
I read the very interesting article: https://bocoup.com/weblog/a-day-at-the-races
about the reason why tests can fail from time to time and Explicit wait as the solution for this intermittent failures. This made me even more convinced about using ExplictWaits.
So I wonder is there anybody who knows situations were an Explicitwait is not doing the right job.
This is my C# code for waiting till a Webelement is clickable:
public static Boolean waitElementToBeClickable(IWebDriver driver, int seconds, IWebElement webelement)
{
Boolean clickable = true;
try
{
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(seconds));
wait.Until(ExpectedConditions.ElementToBeClickable(webelement));
}
catch
{
clickable = false;
}
return clickable;
}

Resources