Java and Selenium: Selenium refuses to see visible element - java

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_]"))

Related

Getting error for choosing radio button(Element is not clickable at point (286,871) because another element ) [duplicate]

I see this only in Chrome.
The full error message reads:
"org.openqa.selenium.WebDriverException: Element is not clickable at point (411, 675). Other element would receive the click: ..."
The element that 'would receive the click' is to the side of the element in question, not on top of it and not overlapping it, not moving around the page.
I have tried adding an offset, but that does not work either. The item is on the displayed window without any need for scrolling.
This is caused by following 3 types:
1.The element is not visible to click.
Use Actions or JavascriptExecutor for making it to click.
By Actions:
WebElement element = driver.findElement(By("element_path"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().perform();
By JavascriptExecutor:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("scroll(250, 0)"); // if the element is on top.
jse.executeScript("scroll(0, 250)"); // if the element is on bottom.
or
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("arguments[0].scrollIntoView()", Webelement);
Then click on the element.
2.The page is getting refreshed before it is clicking the element.
For this, make the page to wait for few seconds.
3. The element is clickable but there is a spinner/overlay on top of it
The below code will wait until the overlay disppears
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
Then click on the element.
You can also use JavaScript click and scrolling would be not required then.
IJavaScriptExecutor ex = (IJavaScriptExecutor)Driver;
ex.ExecuteScript("arguments[0].click();", elementToClick);
There seems to be a bug in chromedriver for that (the problem is that it's marked as won't fix)
--> GitHub Link
(place a bounty on FreedomSponsors perhaps?)
There's a workaround suggested at comment #27.
Maybe it'll work for you-
I had the same issue, tried all offered solutions but they did not work for me.
eventually I used this:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("var evt = document.createEvent('MouseEvents');" + "evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" + "arguments[0].dispatchEvent(evt);", findElement(element));
Hope this helps
Wow, a lot of answers here, and many good ones.
I hope I'll add something to this from my experience.
Well guys, in my case there was a cookie overlay hiding the element occasionally.
Scrolling to the element also works; but in my humble opinion (for my case, not a panacea for everyone) the simplest solution is just to go full screen (I was running my scripts on a 3/4 of the screen window)! So here we go:
driver.manage().window().maximize();
Hope that helps!
You need to use focus or scroll on that element. You also might have to use explict wait.
WebElement firstbutton= driver.findElement(By.xpath("Your Element"));
Actions actions = new Actions(driver);
actions.moveToElement(element);
actions.perform();
OR
The element is not clickable because of a Spinner/Overlay on top of it:
By loadingImage = By.id("loading image ID");
WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));
OR
Point p= element.getLocation();
Actions actions = new Actions(driver);
actions.moveToElement(element).movebyoffset(p.x,p.y).click().perform();
OR
If still not work use JavascriptExecutor
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", firstbutton);
I have seen this in the situation when the selenium driven Chrome window was opened too small. The element to be clicked on was out of the viewport and therefore it was failing.
That sounds logical... real user would have to either resize the window or scroll so that it is possible to see the element and in fact click on it.
After instructing the selenium driver to set the window size appropriately this issues went away for me. The webdriver API is decribed here.
I was getting this error when running tests headless with xvfb-run. They were working flawlessly locally. Using chrome, versions of webdriver / chromedriver / chrome / java etc all identical.
The ‘won’t fix’ bug in chromedriver - GitHub Link pointed out by Tony Lâmpada suggested this may be related to what is / isn't visible on the screen.
Help message for xvfb-run shows the following:
-s ARGS --server-args=ARGS arguments (other than server number and
"-nolisten tcp") to pass to the Xvfb server
(default: "-screen 0 640x480x8")
Changing the resolution for xvfb made the error go away:
xvfb-run -s "-screen 0 1280x1024x16" ...
ruby/watir-webdriver/chrome
I use the following trick and seems like it works:
#scroll to myelement
#browser.execute_script "window.scrollTo(#{myelement.element.wd.location[0]},#{myelement.element.wd.location[1]})"
# click myelement
myelement.when_present.fire_event("click")
I, too, wrestled with this problem. Code works fine in FF, fails on Chrome. What I was trying to do was to click a tickbox - if it wasn't in view, I'd scroll to view and then click. Even scrolling into view works in Chrome, only the bottom few pixels of the tickbox wasn't visible so webdriver refused to click on it.
My workaround is this:
WebElement element = _sectorPopup.findElement(...);
((Locatable) element).getCoordinates().inViewPort();
try {
element.click();
} catch (Exception e) {
new Actions(getWebDriver()).sendKeys(Keys.PAGE_DOWN).perform();
element.click();
}
Chrome also has issues with sendKeys, using Actions is sometimes necessary. Obviously, you need to know which direction and how much you need to go so your mileage may vary. But I prefer this to the javascript hack, so I'm posting it here in case someone else will find it useful.
First, try to get the latest Chrome driver and check if it solves the issue.
In my case, it didn't fix the issue. But, the following solution worked for me so far. The following is C# code but you can follow same logic in your specific language. What we do here is,
Step 1: Focus on the element using the Selenium Actions object,
Step 2: Then do a click on the element
Step 3: If there's an exception, then we trigger a javascript "Click" event on the element by executing the javascript script through the Selenium browser driver's "ExecuteScript" method.
You can also skip step 1 and 2 and try only step 3 too. Step 3 would work on it's own but I noticed some strange behavior in one scenario in which step 3, even though it successfully clicked the element, caused unexpected behavior in other parts of my code after clicking the element.
try
{
//Setup the driver and navigate to the web page...
var driver = new ChromeDriver("folder path to the Chrome driver");
driver.Navigate().GoToUrl("UrlToThePage");
//Find the element...
var element = driver.FindElement(By.Id("elementHtmlId"));
//Step 1
new Actions(driver).MoveToElement(element).Perform();
//Step 2
element.Click();
}
catch (Exception)
{
//Step 3
driver.ExecuteScript("document.getElementById('elementHtmlId').click();");
}
I was getting the same issue while running selenium script in python. Here is what I used to click on the element:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).click(element).perform()
When using Protractor this helped me:
var elm = element(by.css('.your-css-class'));
browser.executeScript("arguments[0].scrollIntoView();", elm.getWebElement());
elm.click();
I made this method based on a comment from Tony Lâmpada's answer. It works very well.
def scroll_to(element)
page.execute_script("window.scrollTo(#{element.native.location.x}, #{element.native.location.y})")
end
Today I got the same kind of issue. You don't believe me if i say how i solved the issue.
By maximizing the browser size
Yes, it is a pointer issue that means the size of the browser. For that, you just need to maximize the window size manually or through the code.
I was facing a similar problem whre i have to check two check boxes one after the other.But i was getting the same above error.hence i added wait in between my steps for checking the checkboxes....its working fine and great.here are the steps:-
When I visit /administrator/user_profiles
And I press xpath link "//*[#id='1']"
Then I should see "Please wait for a moment..."
When I wait for 5 seconds
And I press xpath link "//*[#id='2']"
Then I should see "Please wait for a moment..."
When I visit /administrator/user_profiles_updates
Apparently this is the result of a "Won't Fix" bug in the Chrome driver binary.
One solution that worked for me (Our Mileage May Vary) can be found in this Google Group discussion, Comment #3:
https://groups.google.com/forum/?fromgroups=#!topic/selenium-developer-activity/DsZ5wFN52tc
The relevant portion is right here:
I've since worked around the issue by navigating directly to the href of
the parent anchor of the span.
driver.Navigate().GoToUrl(driver.FindElement(By.Id(embeddedSpanIdToClick)).FindElement(By.XPath("..")).GetAttribute("href"));
In my case, I'm using Python, so once I got the desired element, I simply used
driver.get(ViewElm.get_attribute('href'))
I would expect this to only work, however, if the element you are trying to click on is a link...
Re Tony Lâmpada's answer, comment #27 did indeed solve the problem for me, except that it provided Java code and I needed Python. Here's a Python function that scrolls to the element's position and then clicks it.
def scroll_to_and_click(xpath):
element = TestUtil.driver.find_element_by_xpath(xpath)
TestUtil.driver.execute_script('window.scrollTo(0, ' + str(element.location['y']) + ');')
element.click()
This solved the problem for me in Chrome 34.0. It caused no harm in Firefox 28.0 and IE 11; those browsers aren't subject to the problem, but scrolling to the element's position before clicking it still isn't a bad thing.
This might happen if the element changes position while the driver is attempting to click it (I've seen this with IE too). The driver retains the initial position but by the time it actually gets to clicking on it, that position is no longer pointing to that element. The FireFox driver doesn't have this problem BTW, apparently it "clicks" elements programmatically.
Anyway, this can happen when you use animations or simply change the height of elements dynamically (e.g. $("#foo").height(500)). You need to make sure that you only click elements after their height has "settled". I ended up with code that looks like this (C# bindings):
if (!(driver is FirefoxDriver))
{
new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(
d => d.FindElement(By.Id(someDynamicDiv)).Size.Height > initialSize);
}
In case of an animation or any other factor you can't easily query for, you can utilize a "generic" method that waits for the element to be stationary:
var prevLocation = new Point(Int32.MinValue, Int32.MinValue);
int stationaryCount = 0;
int desiredStationarySamples = 6; //3 seconds in total since the default interval is 500ms
return new WebDriverWait(driver, timeout).Until(d =>
{
var e = driver.FindElement(By.Id(someId));
if (e.Location == prevLocation)
{
stationaryCount++;
return stationaryCount == desiredStationarySamples;
}
prevLocation = e.Location;
stationaryCount = 0;
return false;
});
I met this because a loading dialog cover on this element. I simplely solve it by add a waiting before working with the this element.
try {
Thread.sleep((int) (3000));
} catch (InterruptedException e) {
//
e.printStackTrace();
}
Hope this help!
Explanation of error message:
The error message simply says, that the element you want to click on is present, but it is not visible. It could be covered by something or temporary not visible.
There could be many reasons why the element is not visible in the moment of the test. Please re-analyse your page and find proper solution for your case.
Solution for particular case:
In my case, this error occures, when a tooltip of the screen element i just clicked on, was poping over the element I wanted to click next. Defocus was a solution I needed.
Quick solution how to defocus would be to click to some other element in another part of the screen which does "nothing" resp. nothing happens after a click action.
Proper solution would be to call element.blur() on the element poping the tooltip, which would make the tooltip disapear.
The reason for this error is that the element that you are trying to click is not in the viewport (region seen by the user) of the browser. So the way to overcome this is by scrolling to the desired element first and then performing the click.
Javascript:
async scrollTo (webElement) {
await this.driver.executeScript('arguments[0].scrollIntoView(true)', webElement)
await this.driver.executeScript('window.scrollBy(0,-150)')
}
Java:
public void scrollTo (WebElement e) {
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeAsyncScript('arguments[0].scrollIntoView(true)', e)
js.executeAsyncScript('window.scrollBy(0,-150)')
}
I was facing the same problem with clj-webdriver (clojure port of Selenium). I just translated the previous solution to clojure for convenience. You can call this function before doing click or whatever to avoid that problem.
(defn scrollTo
"Scrolls to the position of the given css selector if found"
[q]
(if (exists? q)
(let [ loc (location-once-visible q) jscript (str "window.scrollTo(" (:x loc) "," (:y loc) ")") ]
(execute-script jscript))))
Maybe it's not really clean solution but it works:
try:
el.click()
except WebDriverException as e:
if 'Element is not clickable at point' in e.msg:
self.browser.execute_script(
'$("{sel}").click()'.format(sel=el_selector)
)
else:
raise
I was getting this bug because I tested a hover and then needed to click on the link underneath the tooltip. The solution was to add page.find('.sp-logo').hover before click_link to get the tooltip out of the way.
It's funny, all the time I spent looking at the various responses, no one had tried the obvious, which of course, I hadn't either. If your page has the same id used multiple times, as mine did, ("newButton",) and the one you want is not the first one found, then you will in all likelihood get this error. The easiest thing to do (C#):
var testIt = driver.FindElements(By.Id("newButton"));
Note it's FindElements, not FindElement.
And then test to see how many results came back from the retrieval. If it's the second one, you can then use:
testit[1].Click();
Or get whomever reused ids to fix them.
After testing all mentioned suggestions, nothing worked. I made this code. It works, but is not beautiful
public void click(WebElement element) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
element.click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
public void click(String css) {
//https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
while(true){
try{
driver.findElement(By.cssSelector(css)).click();
break;
}catch (Throwable e){
try {
Thread.sleep(200);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}
I do a kind of brute force of clicks and it works for me.
try:
elem.click()
except:
print "failed to click"
size = elem.size
mid_of_y = int(size["height"])/2
stepts_to_do_to_left = int(size["width"])
while stepts_to_do_to_left > 0:
try:
print stepts_to_do_to_left, mid_of_y
action = webdriver.common.action_chains.ActionChains(driver)
action.move_to_element_with_offset(elem, mid_of_y, stepts_to_do_to_left)
action.click()
action.perform()
print "DONE CLICK"
break
except:
pass
If you have jQuery loaded on the page, you can execute the following javascript command:
"$('#" + element_id + "').click()"
Example using python executor:
driver.execute_script("$('#%s').click()" % element_id)
Try to maximize the browser when you are working with resolutions greater than 1024x768.
driver.manage().window().maximize();

Selenium Java Element not interactable

Im trying to get into java/selenium but i have some problems i cant solve.
I cant interact with the "WEITER" Button from the website Snipes.com (https://www.snipes.com/checkout?stage=payment#payment). It works with every other button but the box of this one looks a little bigger than the button itself. Perhaps this is the problem but i dont know how i can only click the button.
The code im using for this part is following:
TimeUnit.MILLISECONDS.sleep(500); //select Paypal as Payment
selectPayment = driver.findElementByXPath("/html/body/div[3]/div[2]/div/div/div[2]/div[1]/div[3]/div[2]/div/div/form/div/ul/li[1]/div[1]/label");
js.executeScript("arguments[0].scrollIntoView(true);", selectPayment);
js.executeScript("arguments[0].click();", selectPayment);
TimeUnit.MILLISECONDS.sleep(500);
nextButtonCheckout = driver.findElementByXPath("/html/body/div[3]/div[2]/div/div/div[2]/div[1]/div[3]/div[2]/button");
nextButtonCheckout.click(); //click the "WEITER" Button
TimeUnit.MILLISECONDS.sleep(200);
Is there any way to click only the "main" button element instead of the whole thing so i can interact with it?
Error: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div[5]/div/div/div/div/div1/button"}
whole error: https://pastebin.com/jki8T8Y4
I want to click the little "x" on the top right of this pop up and sometimes it works but sometimes it doesnt. How can I test if it found the element and if not try again? I use proxies for this and the speeds are different so i cant just wait 5s and then check if it works. Sometimes the element can be found in 2s sometimes in 15s. I need to retry it a few times and my idea is to check it the variable 'selectRegion' if something is stored in it. I tried it with if(selectRegion =! "the output from the element") but i cant compare a WebElement with a String.
the code i use:
//Snipes Region + accept cookies
driver.get("https://www.snipes.com/login");
TimeUnit.SECONDS.sleep(7);
selectRegion = driver.findElementByXPath("/html/body/div[5]/div/div/div/div/div[1]/button");
selectRegion.click(); //click on the "x"
System.out.println(selectRegion); //get the variable output the use it later for the retries
acceptCookies = driver.findElementByXPath("/html/body/div[2]/div[2]/div/div[2]/div[2]/button");
acceptCookies.click();
This is a common problem but does anyone know how i can use user:passw authenticated proxies with selenium? Everytime i start it there is this authentication pop up but i cant interact with it.

Selenium element can not be found within iframe

I am trying to retrieve a JSON element, the problem is that in the source code it doesn't exist, but I can find it via inspect element.
I have tried with
C.driver.findElement(By.id("ticket-parsed"))
and via XPath
C.driver.findElement(By.xpath("//*[#id=\"ticket_parsed\"]"));
and I can't find it.
Also
C.driver.switchTo().frame("html5-frame");
System.out.println(C.driver.findElement(By.id("ticket_parsed")));
C.driver.switchTo().defaultContent();
i get
[[ChromeDriver: chrome on XP (1f75e50635f9dd5b9535a149a027a447)] -> id: ticket_parsed]
on
driver.switchTo().frame(0) or driver.switchTo().frame(1)
i get that the frame doesn't exists
and at last i tried
WebElement frame = C.driver.findElement(By.id("html5-frame"));
C.driver.switchTo().frame(frame.getAttribute("ticket_parsed"));
an i got a null pointer exception
Here's an image of the source:
what am I doing wrong?
Well!
The element #ticket-parsed is in iFrame. So, you can click it without getting into an iframe.
Here is the code to switch to iFrame,
driver.switchTo().frame("frame_name");
or
driver.switchTo().frame(frame_index);
In your case,
driver.switchTo().frame("html5-frame");
After switching into the iframe, you can click that element using either XPath or CSS.
C.driver.findElement(By.id("ticket-parsed"))
NOTE:
After completing the operation inside the iframe, you have to again return back to the main window using the following command.
driver.switchTo().defaultContent();
I didn't found a solution with my excising setup,but i did found a js command which gets the object correctly
document.getElementById("html5-frame").contentDocument.getElementById("ticket_parsed")
you can integrate js commands like this
JavascriptExecutor js=(JavascriptExecutor)driver;
js.executeScript(*yourCommandHere*);
if you want to get the output of the command just add the word return before your command (in this specific situation it didn't work but in any other situation it did)
*TypeOfData* foo = js.executeScript(return *yourCommandHere*);
at last because of limited time i had to use unorthodox methods like taking screenshots and comparing the images if they are exactly the same
Thanks for the help

code, sometimes works some times doesnt. different error messages

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.

Selenium webdriver 2.47.1 how to wait for a page reload

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.

Categories