I'm facing a strange issue with the sendKeys method on my Selenium test.
In my webapp I have a lot of inputs with default values, I get those inputs with a findElements() and then I try to fill them, very simple.
To simplify, I have something like that:
List<WebElement> allInputs = driver().findElements(By.className("pouet"));
for (WebElement e : allInputs) {
e.clear();
e.sendKeys("pouet");
}
And it can fail because sometimes the sendKeys() fills the wrong input whereas the clear() has been correctly executed on the right input.
Does anyone has already faced this kind of issue?
Thanks a lot :)
It is strange but it happened in my case, sometimes my firefoxdriver wrote in wrong field even if all fields were unique and successfully found. Small time span between two sendKeys() calls solved the issue. I wasn't using sleeps (you could try with Thread.sleep(5000) just for test to ensure this is it), simple verification if correct text was written in the field between these 2 calls was enough time so that next sendKeys() writes in correct field.
Encountered this, for my case sometimes my clear seemed to be failed and my sendKeys append the previous value. So I need to put Thread.sleep(1000) between e.clear() and e.sendKeys().
However based on your description it seems your issue is more to not able to point to the correct textfield. You should try to put the sleep after the sendKeys() like #acikojevic said.
Try clicking the input field first before clearing it. Without a click sometimes the field is not ready for clearing/input. So:
e.click();
e.clear();
e.sendKeys("pouet");
I had a case where this exact thing happened. And adding the element.click() call didn't help!
It turned out the culprit is not selenium. There was a script on the page that ised HTMLElement.focus() to focus a particular element in the form depending on a condition.
So Selenium was actually racing with the JavaScript on the page for focus, and that caused this issue.
Related
I'm studying the Selenium WebDriver for a school project.
I am currently creating a Maven Web Application (with jsp / servlets) that web scrapes tripadvisor data, puts it into a database and then sorts the data based on user past behavior.
My problem starts when I have to submit my keys to tripadvisor search bar. There is no submit button so I have to use org.openqa.selenium.Keys import. Here is the code I tried:
driver.findElement(By.xpath("//span[contains(#class, 'brand-trip-search-geopill-TripSearchGeoPill__icon--jEoJX')]")).click();
String keyword = request.getParameter("<parameter-inserted-by-user>");
//insert text inside search form
WebElement insert_element = driver.findElement(By.xpath("//input[#class='input-text-input-ManagedTextInput__managedInput--106PS']"));
insert_element.sendKeys(keyword+Keys.ENTER);
The problem that arises is that when I run the test, the text is inserted in the search form, but when Keys.ENTER happens the search is not committed, and it registers as if I actually wrote:
insert_element.sendKeys(Keys.ENTER);
I have been lurking around stackoverflow looking for a solution, and I tried the following alternative:
insert_element.sendKeys(keyword + "\n");
to no avail. It only registers the "Enter" command and thus offers me a search of my "Nearby" location.
I also saw I could use javascript but it looks burdensome for such a simple task as submitting a search request.
Currently I'm using Chromedriver v.2.44 and Selenium v.3.141.59
Can someone help me? Thank you in advance for your time.
You're hitting a timing problem. Selenium is typing really fast then pressing the enter key. Do the actions manually and you will see a slight delay between typing an getting results based on what you typed.
I have sample code that proves the above, but am leaving this for you to figure out. The above comment and your code should be enough.
---Edit--- adding sample code now that the OP figured it out
driver.findElement(By.xpath("//span[contains(#class, 'brand-trip-search-geopill-TripSearchGeoPill__icon--jEoJX')]")).click();
String keyword = request.getParameter("<parameter-inserted-by-user>");
//insert text inside search form
WebElement insert_element = driver.findElement(By.xpath("//input[#class='input-text-input-ManagedTextInput__managedInput--106PS']"));
insert_element.sendKeys(keyword);
Thread.sleep(1000); // <-- Not ideal but for a permanent solution, but illustrates this is timing related.
insert_element.sendKeys(Keys.ENTER);
What I'm doing
I've been making a utility method to help me find and properly wait for Webelements in Selenium. so far its going well and I have a way to try all kinds of different locators, wait till a webelement is found and then wait untill the webelement is displayed/enabled all with timeouts and nice things like that.
Whats the problem then?
The problem is that I sometimes need to find Webelements after pages reload. I've read up on available solutions to the 'staleness' problem and I know how to solve it (using the old webelement I just found and clicked on I'll wait till it's stale before I search again) BUT I don't want to manually have to check wether a given webelement causes a page to reload. I've tried looking in the Webelement and Expected conditions class to see if there is any method that returns true if a given webelement causes a page reload. I've tried searching about it here and on google and gotten nothing useful. I wanted to know if its possible to have something like this:
Boolean causesPageReload = webElement.causesPageReload;
With some imaginary method named causesPageReload that determines wether a webelement causes a page reload when it is clicked on, submitted to, ect. I know that some webelements just cause javascript to run on the page and others reload the page but If i could programatically determine if it reloads the page I could just say:
if (causesPageReload){
wait.until(ExpectedConditions.stalenessOf("insert old webelement here"));
}
And solve the problem. Is there anything in the underlying HTML, javascript or maybe something already built in that could provide this information? Sure I can manually go through the steps myself and see which webelements under test actually cause a page refresh, but that is subject to change, prone to human error and also time consuming.
Possible alternatives?
Alternatively I could just do my staleness check with a timeout of ten seconds and then if it reloads the page thats fine but if it doesn't it allows 10 seconds for the javascript or whatever to finish what it's doing. (I was also kinda wondering If I needed to wait for non page reloading webelement clicks as well but that seems harder due to javascript and entails a different question) I don't know if I would need to wait if the page isn't going to reload. even if I knew that I did need to wait in the non reload case, I wouldn't know how to. My current waits just wait for the webelement to be found, displayed and enabled so if clicking on it causes something important (that I need to wait for) but doesn't change those things, I'd need something else but that requires another question to be more in depth.
Tl:Dr
I just need to know if I can find out which webelements cause pages to reload programatically and if I can't then is there any need to wait for the non reloading ones (no need to go all in depth about the second case just tell me how to ask that as a second question later)?
Update
I've tried multithreading this and so far I've gotten something that can (in a timely manner) decide wether a given element when clicked changes in the DOM or doesn't. This covers most page reloading cases but might lead to a false positive since I'm pretty sure there are other instances where Element references go stale that don't involve the page reloading. I think the root cause of the problem is there is no data/flag/hook to grab onto to really tell. I suppose a better hook would lead to a better solution but I have no idea what that hook would be. On the bright side I did learn/become familiar with alot of multithreading which is good because its an area I've been weak in. I'm going to try to research the javascript thats been mentioned in answers and see If i can't combine that with my multithread approach. Once I have a good hook all I'd need to change is an ExpectedConditions call on a WebDriverwait waiting object.
Update 2
I found this website:
https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Which details "load" and "DOMcontentloaded" events. Two things in javascript that fire when pages are loaded/reloaded. I have already created a thread application with ExpectedConditions like so:
WebDriverWait wait = new WebDriverWait(driver,timeoutSeconds);
try{
wait.until(ExpectedConditions.stalenessOf(webElement));
}
catch (TimeoutException e){
}
Thus I'm pretty sure I can modify the wait.until line to check for a javascript event firing with a timeout using a Java to Javascript interface. To use the two langauges together I was led to this question:
How can I use JavaScript in Java?
In order to obatin knowledge on how that basically works. I'm going to try to implement this using Nashorn or maybe some other interface depending on whats the best.
What this potentially means
While this doesn't determine for us wether a given webelement causes page reloading BEFORE actually "trying" it, it does determine it just by "trying" the webelement. And, because I used a thread off of main, my check for "no it didn't reload the page" is effectively just the timeout condition which can be configured as needed. I don't think its possible to determine if a Webelement causes a page reload without actually trying it, but at least we can try it, determine if it reloads within a timeout period and then we will know we will have waited sufficiently long enough to not get any stale reference exceptions when searching for the same or a next element if we at least know that the next element we're looking for exists on the new page (assuming that once we execute the method to try to locate it, it waits for said element to be displayed and selectable but I've already done that). This also allows us to determine if a given webelement was deleted from the page by "trying it" because if we combine the javascript pageload call with the stalereference check I already have, then we can use the condition of "the JS load event didn't fire (page static) BUT stalereference excpetion was thrown (DOM element changed)" as the check for "this element was deleted/changed signifigantly but page wasn't reloaded", Which is quite useful information. Additioanlly since these elements can now be grouped into three categories:
Doesn't get deleted, can reference again
Deleted but page static
Deleted but page changes
We can store the results beforehand and (as long as the locators remain intact) we can more easily know wether we must wait or not after clicking the webelement. We could even go further and if we know we have the 2nd case, we could retry locating the element and see if it's locators change or not when we click it since I think stalereference exceptions can be thrown without requiring all the locators to change. How useful this is? I'm not sure but I think its pretty useful stuff but somehow I don't think I'm the first one to try/find a solution for this. I will post an answer when I successfully implement and test this but it will be awhile because I need to learn some basic Javascript and then how to integrate that with my java.
There isn't any way to programatically find out if the click will cause a reload.
You need each case separately, for this you can create main click() method with overload (or not) and call the appropriate one in each case
public void clickOnElement(WebElement element, boolean waitForStaleness) {
element.click();
if (waitForStaleness) {
wait.until(ExpectedConditions.stalenessOf(element));
}
}
public void clickOnElement(WebElement element) {
clickOnElement(element, false);
}
You can use
WaitElement(pBy, pWait);
end if you need if element is visible for continue you can add is_displayed()
finaly is not working you use a java wait :
Thread.sleep(second)
or
TimeUnit.SECONDS.sleep(second);
I have an issue with selenium webdriver and i would be very grateful if anyone can help me
Environment:
selenium-server-standalone-2.31.0.jar / selenium-server-standalone-2.35.0.jar
IEDriverServer.exe (tried version 2.28 - 2.35)
Sample code:
WebElement href = this.findElement(By.xpath("//A"));
href.sendKeys(Keys.ENTER);
href.click();
Problem: A fix to any of this would help me
href.sendKeys() successfully simulates user click, but does not wait for page to load
href.click() fails to simulate user click, but successfully wait for page to load
I have search for the source code of .click() method to try to manually create a waitForPageToLoad function, but i haven't been able to find it.
I know i am not giving to much information because the application I am running the test against is internal, so I cant share a link for debugging. But any idea or previous experience with similar problems that could help me figure out what is going on would be appreciate it.
Right now, I have to do both sendKeys and click to achieve the expected results.
Whenever you do .click() on a button or link an internal method something like "waitTillPageLoads()" is called and hence webdriver waits until the next page is loaded completely.
I have experienced a scenario where it waited for almost 10-15 minutes for the page to load because web app was too slow. Wierd it sounds i know.
however sendKeys() doesn't wait. Because sendkeys is not used for clicking purpose rather it used for entering keys.
I guess there must be some strong reason for you to do
href.sendKeys(Keys.ENTER);
And if you still want to go with this approach you can implicitly you can wait for element of next page using implicit wait
WebDriverWait wait = new WebDriverWait(webDriver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("xpath")));
Please note :
You quotation
href.click() fails to simulate user click, but successfully wait for page to load
Can be because you have not set your browser level to 100%.
Please Check my answer at Unable to run Selenium script on IE
What you can do here is after sendKeys operation, put several waits for elements which are on the resulting page using WebDriverWait. This will serve your purpose.
The following instruction
Selenium.typeKeys("location", "gmail.com");
types the string gmailcom instead of gmail.com.
What's happening there?
From the comments:
I am trying to simulate autofill and the only way to do it currently on selenium is to combine type and typeKeys. eg:
selenium.type("assigned_to", split[0]+"#");
selenium.typeKeys("assigned_to", "gmail.com");
Now my question is why typeKeys doesn't type the 'dot' in between gmail.com?
Have you tried using the Native key functions and javascript char codes?
I couldn't get a 'period' character to work using them (char 190), but I got the decimal (char 110) to work just fine, and the text box shouldn't have a problem with either.
selenium.Focus("assigned_to");
selenium.Type("assigned_to", split[0]+"#");
selenium.TypeKeys("assigned_to", "gmail");
selenium.KeyPressNative("110");
selenium.TypeKeys("assigned_to", "com");
Use the type method.
From the javadoc for typekeys:
this command may or may not have any
visible effect, even in cases where
typing keys would normally have a
visible effect
...
In some cases, you may
need to use the simple "type" command
to set the value of the field and then
the "typeKeys" command to send the
keystroke events corresponding to what
you just typed.
We had similar problems using typekeys in selenium python.
One workaround we figured to resolve this issue is to use the combination of 'type' and 'type_keys'. As you might be aware, type does not have such issues.
We did this in our selenium python script and it works just fine.
For example:
If there's an email address to be entered in a text box: test.me#test.me.uk
Then do
type(locator,’test.me#test.me.’)
type_keys(locator,’uk’)
Maybe a very crude way to do, but it did the job.
Hope this helps someone else with a similar problem.
Also try to set focus on element before write on it.
selenium.focus(locator);
selenium.typeKeys(locator, value);
it did function in my case, handling a input type=password.
Suppose the string to be typed using typeKeys is "abc.xyz.efg". Then, we can use type and typeKeys commands to write the given string.
type(locator,"abc.xyz.")
typeKeys(locator,"efg")
The above two steps are useful whenever you want to select an element in drop down box, and the drop down pops down only if we use typeKeys command.
I'm also seeing this behaviour when using Selenium RC (C#), and with different characters ('y' for example which also seems to remove the character follow it from the typing action..)
For some situations it is entirely possible to get around the issue by typing out the keys with the TypeKeys or KeyPress functions, but I haven't managed to find a solution that works when you want to type text in a field, enter control characters ([Enter] or a newline for example), and then type more text.. (using the 'Type' function in this case simply overwrites the field contents...).
If anyone manages to find a reasonable solution to this issue, please add it to this question as it's starting to come up in google now and would probably help alot of people out.. (I'd start a bounty if I could..)
This is an open bug in Selenium (bug SEL-519).
After some fiddling around with it, I finally managed to enter '.' into a textarea by using JavaScript. Execute something like window.document.getElementById('assigned_to').value += '.' via storeEval or the like.
I got the same behaviour but fixed it by passing a variable to the Type command instead of a string.
string email = #"name#gmail.com";
selenium.Type(inputfield, email);
It works like a charm!
Here's what I do:
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
// do something, then navigate to a different page
// (window focus is never changed in-between)
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
The link "mylink" does exist, the first invocation of click() always works. But the second click() sometimes seems to work, sometimes not.
It looks like the click() event is not triggered at all, because the page doesn't even start to load. Unfortunately this behaviour is underterministic.
Here's what I already tried:
Set longer time timeout
=> did not help
Wait for an element present after loading one page
=> doesn't work either since the page does not even start to load
For now I ended up invoking click() twice, so:
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
// do something, then navigate to a different page
// (window focus is never changed in-between)
selenium.click("link=mylink");
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
That will work, but it's not a really nice solution. I've also seen in another forum where someone suggested to write something like a 'clickAndWaitWithRetry':
try {
super.click("link=mylink");
super.waitForPageToLoad(60000);
}
catch (SeleniumException e) {
super.click("link=mylink");
super.waitForPageToLoad(60000);
}
But I think that is also not a proper solution....
Any ideas/explanations why the click() event is sometimes not triggered?
Sometimes, seemingly randomly, Selenium just doesn't like to click certain anchor tags. I am not sure what causes it, but it happens. I find in those cases w/ a troublesome link instead of doing
selenium.click(...)
do
selenium.fireEvent( locator, 'click' );
As others have stated above me, I have specifically had issues with anchor tags that appear as follows:
<a href="javascript:...." >
I've done selenium for awhile, and I really have developed a dislike for waitForPageToLoad(). You might consider always just waiting for the element in question to exist.
I find that this method seems to resolve most weird issues I run into like this. The other possibility is that you may have some javascript preventing the link from doing anything when clicked the first time. It seems unlikely but worth a double-check.
I just tried WebDriver (Selenium 2.0) and found that WebElement#sendKeys(Keys.ENTER) works.
Selenium click() event seems not to be always triggered => results in timeout?
Try selenium.pause before Selenium.click command. I have tried all above but none of them seems to resolve our problem. So finally we got a Magic selenium.pause which solved problem for me..
Hope this will solve your problem as well
I am running into this issue now also. From my usages of this, it seems like the following is the most consistent:
#browser.click(selector, {:wait_for => :page})
Not exactly sure why that would be. But it seems that if you do:
#browser.click(selector)
[maybe some stuff here too]
#browser.wait_for(:wait_for => :page)
Then you could end up waiting for a page that has already been loaded (i.e. you end up waiting forever).
I dug into the Selenium source code and found this nugget:
def click(locator, options={})
remote_control_command "click", [locator,]
wait_for options
end
...
# Waits for a new page to load.
#
# Selenium constantly keeps track of new pages loading, and sets a
# "newPageLoaded" flag when it first notices a page load. Running
# any other Selenium command after turns the flag to false. Hence,
# if you want to wait for a page to load, you must wait immediately
# after a Selenium command that caused a page-load.
#
# * 'timeout_in_seconds' is a timeout in seconds, after which this
# command will return with an error
def wait_for_page(timeout_in_seconds=nil)
remote_control_command "waitForPageToLoad",
[actual_timeout_in_milliseconds(timeout_in_seconds),]
end
alias_method :wait_for_page_to_load, :wait_for_page
Basically, this is doing the following:
#browser.click(selector)
#browser.wait_for(:wait_for => :page)
However, as the comment states, the first thing necessary is to use the :wait_for command immediately after.
And of course... switching the order puts you into the same wait forever state.
#browser.wait_for(:wait_for => :page)
#browser.click(selector)
Without knowing all the details of Selenium, it seems as though Selenium needs to register the :wait_for trigger when it is passed as an option with click. Otherwise, you could end up waiting forever if you somehow tell Selenium to wait the very instant before :wait_for is called.
Here this one will work:
selenium.waitForPageToLoad("60000");
selenium.click("link= my link");
I had the same problem - with Selenium 1.0.12 and Firefox 5.0 ; I managed to make the automated tests work this way:
I removed all "AndWait" commands (sometime they hang the test/browser)
I added a pause before the click
I added a waitForVisible after the click (usually I wait for the next html control I want to interact with on next page).
It goes like this:
waitForVisible OK
pause 1000
click OK
waitForVisible link=Go
pause 1000
click Go
etc...
It seems that the "waitForVisible" is triggered too soon, i.e. before the event handler are plugged into the control (thus clicking on the control has no effect). If you wait for 1 second, it's enought to plug/activate the click handlers...
The page has not loaded properly when you are clicking on it. Check for different elements on the page to be sure that the page has loaded.
Also, wait for the link to appear and be visible before you click on it.
Make sure you are increasing the timeout in the correct place. The lines you posted are:
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
This wait is for the page to load that comes back After the click. But the problem you describe is that it is failing when trying to do the click. So, make sure to increase the wait Before this one.
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
// do something, then navigate to a different page
// (window focus is never changed in-between)
// after the last click in these steps:
selenium.waitForPageToLoad(60000);
// anything else that happened after that
selenium.click("link=mylink");
selenium.waitForPageToLoad(60000);
If you're using FireFox, make sure you're using 3.6 or later.
WaitForPageToLoad uses the javascript variable 'readyState', but Firefox only supported this in 3.6. Earlier versions just don't wait
(see org.openqa.selenium.internal.seleniumemulation.WaitForPageToLoad)
I am having the same issue :( with selenium IDE 1.0.10 , phpunit 3.5 , selenium RC server 1.0.3
EDITED:
The culprit seems to be browser FF 3.6.13 , after upgrade to FF 3.6.14
all my errors are gone . My tests are working like charm :).
Selenium IDE 1.0.10
PHPUnit: 3.5.6
Selenium Server:selenium-2.0b1 (selenium-2.0b2 is buggy)
selenium.click("link=Continue to this website (not recommended).");
Thread.sleep(5000);
I've been having the same issue and found that I have to get the text of the link first. I know it's not the ideal way to do it, but I'm fortunate my links are uniquely named.
C# code:
var text = Selenium.GetText(myLocator);
Selenium.Click("link=" + text);
Try this:
selenium.fireEvent(ID, "keypress");