Selenium tests hang on CI while loading content - selenium

I'm trying to debug some Selenium tests but I cannot reproduce the issue locally. On the CI, after selecting some check boxes, the page reloads (a loading animation is displayed), and on the Jenkins agent it hangs for hours. I tried using these options, which I've added in the class constructor of the page:
driver.manage().timeouts().implicitlyWait(8, SECONDS);
driver.manage().timeouts().pageLoadTimeout(8, SECONDS);
Also I tried
public static void waitForLoadingPopUpToBecomeInvisible() {
try {
WebdriverWait wait = new WebDriverWait(driver, 20);
wait.until(invisibilityOfElementLocated(By.className("loading")));
} catch (Exception e) {
driver.navigate().refresh()
}
}
I want to refresh the page if the loading animation is visible for more than X seconds, or to force kill the test if it has been running for more than Y minutes.
Can you please suggest any better ideas?

Related

After login Home page loads and then gets refreshed not able to identify the locators due to refresh

I'm automating the salesforce web application. After logging into the application the home page loads and then gets refreshed not able to identify the locators due to the refresh happens after 2 to 3 sec. Refresh is happing to load the dashboards.
Getting an Exception:org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element
I had tried with webdriverwait, Thread.sleep and Implicitwait and none of these options worked out for me.
public void validatedashboard() throws InterruptedException{
new WebDriverWait(driver, 15).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//button[contains(text(),'Open')]")));
String actualdashboard = dashboard.getText();
BasePage.Log.info(actualdashboard);
String ExpectedText0= "Territory Overview";
if(actualdashboard.contentEquals(ExpectedText0))
{
BasePage.Log.info("Territory Overview dashboard is present");
}
else
{
BasePage.Log.info("Territory Overview dashboard is not present");
}

Selenium in multi-step iframes (paypal)

I want to test paypal payment with selenium/selenide.
I am waiting for the embedded frame to be loaded, then switch to it, fill out the login form and click the login button.
but how can I wait from there for the next step to be loaded? (there is a significant load-time between the steps that happens after the iframe was initially loaded, so the waitForLoad doesn't catch it)
I have tried waitForLoad(confirmButton), but it timeouts. (I'm still in the iframe focus).
how can I do this?
thanks
Use wait command:
public void waitForElementPresent() {
WebDriverWait wait = new WebDriverWait(driver, 20);
wait.until(ExpectedConditions
.visibilityOfElementLocated(By.id("");
}

SafarDriver Selenium Page title is incorrect after loading new page

I have a Selenium 2 test that uses a login form and then asserts that the login has succeeded by verifying the page title has changed.
The test is written in Java/JUnit, WebDriver and Fluent Selenium
fwd.title().within(secs(5)).shouldContain(partialTitle);
The tests work on Firefox and Chrome.
On Safari the page title is still the old login page title.
The screencast we have generated shows that the URL after a successful login has changed, but the title hasn't.
I think the SafariDriver is not waiting for the page load event to complete before the assertion.
I have the same issue!!!
My test fail because title is used for checking test "Step".
With Firefox and Chrome no problem; with Safari it's a problem!!!
I found this "hack" that work, but it's necessary to manually check the title after each "click":
def static void waitForPage(driver, String title) {
//Hack to make login working on Safari&IE
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.getTitle().startsWith(title);
}
});
}
I use GEB + SPOCK and with safari driver there is a "know issue" about implicit/explicit wait (ref. https://code.google.com/p/selenium/issues/detail?id=5860).
So, a nice workaround for make test runnable on Safari browser is to wait for page title:
static at = {
waitFor { title == "Homepage" }
}
This will force the driver to wait until title change (the timeout is configurable).

Selenium Force Close Firefox

ProfilesIni profile = new ProfilesIni();
FirefoxProfile ff = profile.getProfile("ScreenCapture");
WebDriver driver = new FirefoxDriver(ff);
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get(url);
Thread.sleep(8000);
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
driver.quit();
Shouldn't driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); force a close of the selenium generated Firefox browser after 15 seconds? The browser just sits and says its transferring data for an hour+. Basically just hangs saying its transferring...
I am capturing ajax heavy pages which is why Im asking everything to wait for 8 seconds after page loads. But that should have nothing to do with the driver forcing a close after 15 seconds.
Where am I going wrong?
Details: Centos x64 6.4 with Firefox 10.0.12 and latest Selenium as of 10 min ago.
Is there something I can do in Java to go around this?
Question: How can I force close the Selenium generated Firefox window after N seconds?
If you use Junit along with Java, then some thing like this :-
#After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
Note :-
To get a full skeleton of how it should be written just download the selenium IDE for FF and export some test case to Java /jUnit.
My linux knowledge is limited, but you can kill a process by running the linux command pkill.
driver.quit();
Thread.sleep(15000); //use a poll loop instead to check process running every 1 sec
Runtime rt = Runtime.getRuntime();
rt.exec("pkill firefox");
I think that the java process will need to have enough permissions to kill a process, but haven't tried it.
To follow up on Ardesco's comment, an example would look as follows:
ProfilesIni profile = new ProfilesIni();
FirefoxProfile ff = profile.getProfile("ScreenCapture");
WebDriver driver = new FirefoxDriver(ff);
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
try {
driver.get(url);
} catch (TimeoutException e) {
System.out.println("15 seconds were over, force continue!");
} finally {
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
driver.quit();
}
The try part will run the request but when the timeout time set with pageLoadTimeout has been exceeded an exception is thrown which we catch. The finally part will be run regardless if the requested page was loaded properly in less than 15 seconds or whether an exception was thrown.
Implicit waits will not force a close of a browser after 15 seconds.
Implicit waits are used when trying to find elements in the DOM, they are not used when trying to load a page. If you want Selenium to stop trying to load a page after 15 seconds you will need to set a pageLoadTimeout, it's used like this:
driver.manage().timeouts().pageLoadTimeout(15, TimeUnit.SECONDS);
The default page load timeout is 0 (which means wait indefinitely), hence the behaviour that you are seeing.
(There is obviously an assumption here that the driver binary you are using has implemented this method.)
The JavaDoc for timeouts in Selenium is available Here

Handling Browser Authentication using Selenium

Does anyone know about handling Browser Authentication using Selenium or any other tool during automation?
EDIT in 2015:
This answer is outdated. WebDriver nowadays supports authentication! See How to handle authentication popup with Selenium WebDriver using Java
Original answer:
This is not handled very well by Selenium.
You can try using http://username:password#example.com/yourpage
instead of just http://example.com/yourpage
However, as far as I know, Firefox will still pop up a browser dialog requesting a confirmation.
You can try Robot if you're using Java (or any similar tool like AutoIt).
You could use driver.manage().addCookie() if you're using WebDriver.
Or a custom FirefoxProfile that has already passed the authentication once.
I spent days on this - literally.
Trying to get past browser level authentication within my company network to hit an application.
The solution was to use the 'unsername:password#' component within the URL, BUT to add a forward slash at the end of the login URL.
So total login URL looks like this (note the '/' after yourpage):
http://username:password#example.com/yourpage/
Works with Watir, Capybara and Selenium Webdriver.
Everything I have read on the Web didn't help me. So before making a request, like this:
driver.get(url);
you have to run a new thread like this:
RunScript runScript = new RunScript();
runScript.start();
In this case you are free to input login and password on another thread of follwing class
public class RunScript extends Thread {
#Override
public void run() {
try {
File file = new File("D:\\jacob-1.18-x86.dll");
System.setProperty(LibraryLoader.JACOB_DLL_PATH, file.getAbsolutePath());
AutoItX autoIt = new AutoItX();
Thread.sleep(2000);
autoIt.winActivate("yourWindowName", "");
autoIt.winWaitActive("yourWindowName");
if (autoIt.winExists("yourWindowName")) {
autoIt.send("username{TAB}", false);
autoIt.send("password{Enter}", false);
}
}
} catch (InterruptedException ex) {
//
}
}
}
All the hacks via auto-it, sikuli, etc. just wasting your time when you'll run it in your CI solution, using several browser types / OS / Version / Resolutions etc.
The way to do it correctly is to identify the authentication actual method and perform a login using Rest protocol for instance.
I used it to get the JSESIONID cookie and insert it to the selenium driver.
hint on that: go to a non-exiting url of the domian first, then set the cookie, then go to the required url - you are logged-in.
use: rest client authentication to get the JSESSION ID
and With this information:
browser().navigate(foo.getUrl()+"non-exiting-url");
//the information got from the rest client login:
Cookie cookie = new Cookie(name, value, domain, path, expiry, isSecure, isHttpOnly);
try {
driver.manage().addCookie(cookie);
} catch (Exception e) {
System.out.println(e.toString());
}
browser().navigate(foo.getUrl());
you can use auto IT script to handle this problem
WinWaitActive("[CLASS:Chrome_WidgetWin_1]", "", time)
Send("user")
Send("{TAB}")
Send("pass")
Send("{ENTER}")
with Chrome 70 and other versions :
http://username:password#example.com/yourpage
You can use Java Robot class with Selenium 2 /Selenium WebDriver using Firefox
WebDriver driver = new FirefoxDriver();
driver.get("http://localhost:9990");
WebElement myDynamicElement = driver.findElement(By.id("app"));
Alert alert = driver.switchTo().alert();
try {
Robot robot = new Robot();
alert.sendKeys("username");
robot.keyPress(KeyEvent.VK_TAB);//go to password feild
robot.keyPress(KeyEvent.VK_P);
robot.keyPress(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_S);
robot.keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
}
}
Using Selenium with Robot
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Robot.html