How to wait for page load to complete in Chrome browser - selenium-webdriver

What is the command in webdriver to wait for page to load fully before performing action on the page in CHROME browser?
PageLoadTimeOut is not waiting for the page load to complete in Chrome whereas it is working fine in firefox.
In Chrome, if webelement is there on the page, webdriver is performing the action on webelement while page is getting loaded. This is causing scripts to fail randomly with exception 'element is not clickable'.
Please let me know if there is any solution for this.
Thanks

You can use custom wait methods for an element to be enable or visible on the page.
For Example create a custom method isElementEnable using following code:
driver.findElement(locator).isEnabled();
Or use the following code to check if the element is visible on page:
driver.findElement(locator).isDisplayed();
pass your element locator as input parameter to the method.
Or Alternatively use implicit wait:
driver.manage().timeouts().implicitlyWait(number_of_seconds, TimeUnit.SECONDS);
Hope this will help.

You can use the JavaScriptExecuter.executeScript to get document.readyState,to compare it to complete,as a condition to WebDriverWait.Like this:
WebDriverWait wait = new ...;
wait.until(new ExpectedCondition<Boolean>(){
public Boolean apply(WebDriver driver) {
return (JavaScriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
});
Unfortunately, with Chrome if you have a alert on page,you will get a UnhandledAlertException.And this will not occur for Firefox

It's a really old question, but anyone having the same question might find this useful:
For chromedriver, it is best to use sleep method:
import time
# some of your code
time.sleep(2)
# here your program will wait for two seconds
# rest of your code
You can find an appropriate time span that will ensure your page loads and pass that time as parameter. But using too big time will make program slower.

Related

Non-angular page opened with click - angular not defined using ignoreSynchronization or waiting for Angular without

After a lot of research, and tinkering, I can't seem to actually get my Protractor test to do anything else other than have an Angular related error, even though I am using browser to avoid Angular being detected at all.
The test involves an Angular app, opening a dropdown in it, and clicking on the link for the console; the console opens a non-Angular admin page in a separate window.
So based on the many informative SO posts I found, I first used this...
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
//expect for new window here
});
});
Which appeared to work, as I could get to the window through repl pretty easily.
The issue is when either of the following were added...
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
expect(browser.getLocationAbsUrl()).toContain('/console/login.jsp');
expect(browser.driver.findElement(By.css('th.login')).getText()).toEqual('Login');
});
});
One expect check the URL and the other checks for the header element on the page, which is a table header. When I run this, I get the following:
Error while waiting for Protractor to sync with the page: "angular could not be found on the window"
When I decide to use browser.ignoreSynchronization = true, both in the function, or in a beforeEach, with or without a following afterEach setting it to false, I get the following:
JavascriptError: angular is not defined
I can't seem to get any "useful" errors to help me debug it, and trying it in repl does not help, as I get the same issue.
To be comprehensive, trying my URL expect without getting the second window will give me the root, and the other will fail.
Just doing one or the other will cause the same problem.
Changing to regular syntax (element(by.css...)) does not change things.
So much for my first question...
It appears that my use of browser.getLocationAbsUrl() is meant to be used for an Angular page, and was causing my issue...
Essentially, even though I believed I was using pure Webdriver calls, that call still required Angular on the page to work...
As stated in another post, the use of browser.driver.getCurrentUrl() is a non-Angular call using Webdriver, and fixed the problem. Thus, the final code is the following...
browser.sleep(1000); //to wait for the page to load
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
expect(browser.driver.getCurrentUrl()).toContain('/console/login.jsp');
expect(browser.driver.findElement(By.css('th.login')).getText()).toEqual('Login');
});
});
This works without setting ignoreSynchronization, BTW.
I realized it would probably be something relatively simple to fix it, just didn't expect I'd get it that quickly (I intended on submitting the question last night, but posted it this morning instead).
In any case, I hope this will at least be a good reference for anyone else facing the same issue.
Seems like getLocationAbsUrl is angular abs url.
Try using the native driver getCurrentUrl instead.
-- expect(browser.getLocationAbsUrl()).toContain('/console/login.jsp');
++ expect(browser.driver.getCurrentUrl() ...

CefSharp3 Can't navigate back

I am currently using CefSharp.MinimalExample.Wpf (CEF branch 1750 and CefSharp 33.0.0) to evaluate my issue. I just added a button to the MainView.xaml like this <Button Command="{Binding WebBrowser.BackCommand}">Back</Button>. The buttons enable state is updated on loading a site (once the site is loaded it is pressable). But clicking on it doesn't work to navigate back.
My second approach was to execute a java script snippet on click browser.ExecuteScriptAsync("history.back()"); But this doesn't work either.
Any ideas?
I have the same problem, but your answer gave me an idea, I hope my solution works for you.
The first page showed by the browser is like a blank page, so, when this blank page is loaded, I assign the URL, through FrameLoadEnd event of the browser.
I have a flag to avoid assign the URL more than one time.
Browser.FrameLoadEnd += delegate
{
if (!flag)
{
Browser.Address = "http://www.google.com.mx";
flag = true;
}
};
Looks like with this the problem is solved.
My investigation result is that if you set the URL too early - on creation of the browser object ChromiumWebBrowser until up to about 250ms (try&error value on my machine) - at least the back-function and JavaScript-injection won't work. The Initialized event is not a solution because it is too early. Apart from this the site will be rendered fine and you can browse the web. This was the part which distracted me and let me search elsewhere.

How to handle Spinners using Protractor

In my AngularJS application, for any page to load, there are two things which are loading
First the content of the page and secondly some back-end resources.
While back-end resources are loading, a spinner comes in the front and user is not able to do anything on the page contents.
Now while I am writing the automation test suites of the application using Protractor, I am not able to find a technique, to wait for the spinner to disappear from the screen before starting the test.
Please help me in this.
IsDisplayed as you mentioned in Andres D's comment should be the right one to use for your situation. However, it returns a promise so you cant just use
return !$('.spinner').isDisplayed()
since that will just always return false.
Try the below and see if it works.
browser.wait(function() {
return $('.spinner').isDisplayed().then(function(result){return !result});
}, 20000);
If you are waiting for something to happen you can use browsser.wait()
For example, if the spinner has the class name "spinner"
browser.wait(function() {
// return a boolean here. Wait for spinner to be gone.
return !browser.isElementPresent(by.css(".spinner"));
}, 20000);
The 20000 is the timeout in milliseconds.
Your test will wait until the condition is met.
For those dealing with non-angular apps:
browser.wait(
EC.invisibilityOf(element(by.css(selector))),
5000,
`Timed out waiting for ${selector} to not be visible.`
)
https://www.protractortest.org/#/api?view=ProtractorExpectedConditions.prototype.invisibilityOf

can not click on none visible element

I'm trying to test my angularjs app with protractorjs. I have set up selenium and got the server and runner working. My issue is that when I run my test I get the ElementNotVisibleError. I know that the element I am trying to select is hidden until certain fields have been filled in and this is how I would like this to be kept.
My question is, are there any workarounds to the issue via a call to wait or sleep. I have tried many variations of wait and sleep but with no luck.
My test code is
it('navigates the user to the login page', function(){
ptor = protractor.getInstance();
ptor.get('http://localhost:2222/#/page');
ptor.findElement(protractor.By.input('input.type1')).sendKeys('one');
ptor.findElement(protractor.By.input('input.type2')).sendKeys('two');
ptor.findElement(protractor.By.input('input.type3')).sendKeys('three');
ptor.findElement(protractor.By.input('input.type4')).sendKeys('four');
ptor.findElement(protractor.By.input('input.type5')).sendKeys('five');
ptor.findElement(protractor.By.input('input.type6')).sendKeys('six');
ptor.sleep(5000);
ptor.findElement(protractor.By.id('clickableBtn')).click();//not visible until above fields populated
}, 1000000);
Message from protractor is
Message:
ElementNotVisibleError: element not visible
If the element is not visible until you have input in all of the fields, it is because of Javascript. You may have to kick off that Javascript by typing Tab or Enter after typing that last field:
ptor.findElement(protractor.By.input('input.type6')).sendKeys(Keys.Tab);
Using javascript I was able to click
var linkToClick = ptor.driver.findElement(protractor.By.id('clickableBtn'));
ptor.executeScript("arguments[0].click();", linkToClick );
yes, WebDriver allows you to execute javascript on elements directly so simply do a javascript .click. You would need to convert to your own language but here is how I did it using C#
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
js.ExecuteScript("arguments[0].click()", element);
Browser.WaitForPageLoad(driver);
I actually created an extender method so that I simply type element.InvisibleClick(driver) and it clicks on it for me. More on that can be found documented HERE.
You can always give it opacity:0
-moz-opacity: 0.00; opacity:.00; filter: alpha(opacity=00);
This should work for all browsers.

selenium firefoxdriver - wait for ajax

When testing an ajax page there is a challenge how to wait till the page is loaded.
The way i found in the web is to wait explicitly for a certain element to load.
There is another way in htmlunit, which is to convert all asynchronous javascript to synchronous javascript.
client.setAjaxController(new NicelyResynchronizingAjaxController());
This is more generic, as we don't need to know exactly for which element to wait.
Is there a way to implement this with the firefoxdriver.
This is how you could wait for a specific element that is loaded in the DOM after a Ajax Request.
Suppose you have the following:
<div id="postAjaxRequest">This only appears after something request me!</div>
The all you had to do is with a started WebDriver and WebDriverWait element is the following:
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10); // Starts a wait of a maximum 10 seconds.
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("postAjaxRequest")));
driver.findElement(By.id("postAjaxRequest")).click(); // or any other action
This is the simplest i could explain.

Resources