Selenium sends incomplete text - java

I'm having a problem with Selenium when it comes to use .sendKeys(text). During the automation process, sometimes selenium is sending incomplete strings to the browser, which causes to create incorrect searchs.
i.e. I want to type "MY DROP", and it will type "Y DROP", or "ROP".
It does not always type the same way, so sometimes 2 letters might be missing, and sometimes the whole word is missing.
This only happens to dropdowns, where I have a specific method that handles the dropdown selection, as we are using angular I can't use the selenium select dropdown method.
I already tried to set Thread.Sleeps and waits on the dropdown selection but nothing seems to work, currently this is what I use to select a value:
public void select(String item) {
waitTillClicable();
WebElement element = getElement();
openDropDown(element);
element.sendKeys(item);
waitResultLoad();
selectResult(element);
}
This code was working perfectly until the last week. I'm thinking it has something to deal with the new Chrome version 45, as before it was not happening. I also tried to use different chromedriver versions, and running on a Linux machine, but nothing seems to have an effect.
Right now I created a workaround where I keep verifying if the string was typed correctly, and re-typing it until it is correct, but this makes the execution time increased, which I wanted to avoid.

Why are you using .sendKeys() to select a value in a SELECT? Use the provided methods for a Select: .selectByIndex(int), .selectByValue(String), or .selectByVisibleText(String). Some examples...
Select test = new Select(driver.findElement(By.id("dropdown")));
test.selectByIndex(1);
test.selectByValue("myValue");
test.selectByVisibleText("VisibleText");

See if the happens on Firefox driver or IE driver
The other thing is the method signature is
public void sendKeys(CharSequence... value)
can you try to send it like this sendKeys( "MY","DROP"); instad and see the result
Hope this may help.
Alan Mehio
London, UK

Related

element.sendKeys(password) method in Selenium sending too many keys

I'm writing Selenium tests for an application my company's working on. It's Selenium 3, and I'm using the 32-bit Internet Explorer Driver(IEDriverServer.exe) because I was using the 64-bit version but it was very slow to do anything.
I'm trying to populate a password field (with id="password"), and I'm using the following line of code:
driver.findElement(By.id("password")).sendKeys("welcome123");
where driver is an InternetExplorerDriver. What's happening instead of inputting the 10 characters "welcome123", is this:
The image of the populated password field
Please let me know what I can do to stop this from happening. I don't know what keys are being sent, but I am sure that in my code it says just "welcome123" and not something obvious like "welcome123_________".
Thanks!
Using the lines
driver.findElement(By.id("password")).click(); and
driver.findElement(By.id("password")).clear(); and then following it up with the
sendKeys("welcome123");
method call, the field is populated correctly. The problem was because IE was auto populating the password field based on password saving settings, and it was just tacking "welcome123" on the to the end.

Appium sendKeys really slow on android

I'm currently testing an application using Appium on an android device (appium version: 1.2.4.1, java-client: 2.1.0). I'm using the following code to send some text in a textField:
driver.findElement(By.name("Name")).sendKeys("My Name");
and it works fine just it takes it too long to actually send the text on the textbox (usually 7 seconds). I was wondering does anybody know another way to send text on a textField that takes less?
Thanks!
I solved this issue by using adb to send text instead of appium!It is really fast!
try {
textElement.click();
new ProcessBuilder(new String[]{"adb", "-s", "YOURDEVICEUUID", "shell", "input", "text", "YOURTEXTASINPUT"})
.redirectErrorStream(true)
.start();
} catch (IOException e) {
e.printStackTrace();
}
Same way you may use this for Click,clear,install,uninstall etc.. there may be some need to sleep thread for sync issues but it is only 50ms which is too less than 5 seconds which appium takes!
You may use DDMLIB to make this adb call instead of ProcessBuilder!
Try :
driver.findElement(By.name("Name")).Click();
driver.Keyboard.SendKeys("My Name");
This should run faster then your method.
This capabilities helped me to reduce the time of inputs on Android
desiredCapabilities.setCapability("ignoreUnimportantViews", true);
desiredCapabilities.setCapability("disableAndroidWatchers", true);
You can find more here https://appium.io/docs/en/writing-running-appium/caps/#android-only
Experiencing slow automation on Appium is common because Appium is based on a client/server architecture. Network issues can influence the performance of a test (unless you are running your test in the same machine where Appium is installed).
I can tell you that I have also experienced problems with slow tests on Appium. It usually happens on simulators/emulators by the way.
Send keys as part of a UX scenario
If your test needs to send keys as part of a User Experience scenario, then SendKeys is your only option. This method does not simply set a value in a textbox, it actually behaves like a user pressing keys and sending keys to a textbox.
If this is what you need, then you need to understand what is happening a network level because this is what your problem is about. Also consider that this method can be slow on its own sometimes (this is my experience).
Setting a text is not important for the UX scenario being tested
In case the step of setting a textbox's value is not a core part of your automation for the specific test being considered, you an always do achieve this by means of ExecuteScript which lets you execute a Javascript code in your app. I am assuming you are automating the WebView context.
int result = driver.executeScript("
try {
var el = document.getElementById('<your-txtbox-id-here>');
el.value = '<your-text-here>';
return 0;
} catch {
return 1;
}
");
Java does not support multiline strings so the previous is a prettyprint of the following:
int result = driver.executeScript("try{var el = document.getElementById('<your-txtbox-id-here>');el.value = '<your-text-here>';return 0;}catch{return 1;}");
This method will return 0 in case the string was successfully set, otherwise 1. It should be faster because the driver will not send each key separately but execute the script in an anonymous function and get back its return value.
Try to add the following capabilities inorder to have appium keyboard(and not the physical keyboard)
capabilities.setCapability("resetKeyboard", true);
capabilities.setCapability("unicodeKeyboard", true);
Replace sendKeys with the setValue method available in later versions of appium:
driver.findElement(By.name("Name")).setValue("My Name");
It is much faster in my experience.
For new commer, in the Appium version 1.9~, both method executeJavaScript() & setValue() works so good, and you can consider to use it.
// use js
executeJavaScript("$('#" + fieldId + "').val(testData);
// use setValue
$(By.id(fieldId)).setValue(testData);
I improved the speed of my test (written in Python) using:
driver.set_value(myElement, "My Name")
instead of:
webElement.send_keys("My Name")
If you are using Java, it will be something similar to:
driver.setValue(driver.findElement(By.name("Name")), "My Name")
Another approach could be with adb... (This is the fastest one but you have to use another thing besides appium)
//1st - Click at your WebElement
driver.click(driver.findElement(By.name("Name")))
//2nd - Using adb send your text
//adb shell input text "My Name"
adb shell input keyboard text "My Name"

Numeric value which is entered in a text filed with WebDriver using Java is deleted automatically

I am using Webdriver with java. I want to input some numeric value in a text field by using Java. I am using the following code:
driver.findElement(By.id("igtxtctl00_MasterPlaceHolder_WTxtZip")).sendKeys("25025");
But after entering the value completely, the entered value is erased automatically.
After the value is stored, I have to click on tab (using script), so that the City field is populated automatically after running the back end process.
I have achieved the same thing using Selenium RC by using below code:
selenium.typeKeys("igtxtctl00_MasterPlaceHolder_WTxtZip", "25025");
Thread.sleep(x);
selenium.keyPress("igtxtctl00_MasterPlaceHolder_WTxtZip", "9");
try some thing like this
driver.findElement(By.id("igtxtctl00_MasterPlaceHolder_WTxtZip")).sendKeys("25025");
after typing zip code just try to click some where else in the page
driver.findElement(By.id("igtxtctl00_MasterPlaceHolder_WTxtZip")).sendKeys(Keys.TAB);
OR
Try with Actions class.
new Actions(driver).sendKeys(driver.findElement(By.id("igtxtctl00_MasterPlaceHolder_WTxtZip")), "").perform();
From inspecting your code, I see that there is client-side logic based on that zip element. There is a post-back to the server to determine the city. The trigger to the post-back is the tab key.
This means that if you want to effectively test your page, you must send the tab key.

:first / :first-child doesn't seem to work with Selenium 2

While migrating from Selenium 1 to Selenium 2 I am running into a problem.
I have the structural equivalent of the following:
<ul id="documentType">
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
Previously I would in Selenium 1 use the following css selector to find the first anchor link:
#documentType li:first-child a
This would work great, however, when I switch to selenium 2 and try and use the equivalent I get element not found. The following does work but is less precise then I would like.
#documentType li a
I have tried but could not get to work the following:
#documentType li:first a
For greater detail I'm using HtmlUnitDriver with the following code:
driver.findElementByCssSelector("#documentType li a");
Any help on getting the equivalent of the original selector working I would greatly appreciate it!
I be confused :)
EDIT: Phill Sacre brought up a good point on the fact I'm directly using HtmlUnitDriver which could be the source of the problem since it's a pure java implementation. I do this specifically for the ability to deal with a nasty Ajax problem of how to know when Ajax is done running. You can do this with the following code:
protected void waitForAjaxToComplete() {
long result = jQueryActive();
while (result != 0) {
result = (Long) driver.executeScript("return jQuery.active;");
}
}
This is obviously advantageous over using the technique of waiting for an element to appear which can be very inaccurate. I wish WebDriver would expose the executeScript method which would resolve this problem.
Further I noted that by default HtmlUnitDriver does use a java based implementation to parse the css selector supplied and I'm guessing this is the source of the problem. The parser is com.steadystate.css.parser.SACParserCSS21.SACParserCSS21 which may not properly take into account the :first and :first-child qualifiers.
What seems to make this ok is that the behavior of HtmlUnitDriver seems to return the first element by default. It's sister method findElementsByCssSelector seems to return an ordered list.
As a result while this appears to be a bug I may have answered my own question by learning how HtmlUnitDriver operates.
Which browser were you doing your Selenium 1 testing on? Looking in the Selenium documentation, the HtmlUnit driver is a pure-Java solution (i.e. it doesn't run in a browser, obviously).
Now I think there are some differences in selectors between browsers, so if you were using the Firefox browser before it may be worth using the FirefoxDriver to run your Selenium 2 tests?
Similar to Phill's answer- HtmlUnit parser the page differently than FF. I would start the debugging process by running the same test using the FF driver and see if it passes there. If it does pass, then the next step I would do is get the HTML from the HtmlUnit driver (I guess the command would be driver.getPageHtml() or something similar). I would compare that html with the html you get when you look at the html through a real browser (FF, chrome,..). Sometimes you see that tags have been put in by the real browser (i.e., by its parser) or by the HtmlUnit browser. You can either correct your selector or use a different driver (or go tell the developers to fix their html because that what usually causes these problems :-)
I had the same problem with this selector (using Spock/Geb). This has been resolved in the new version of Geb which is 0.9.2 (which has the changes to the HTML unit driver too). Now $('tr:first-child a') works fine with HTMLUnitDriver
I can provide the following CSS Selectors
1. css=#documentType > li > a -- First Link
2. css=#documentType > li+li > a -- Second Link
3. css=#documentType > li+li+li > a -- Third Link
else, you can try
1.css=#documentType > li:nth-child(2) > a -- Second Link
2.css=#documentType > li:nth-child(3) > a -- Third Link

How to test AjaxFormChoiceComponentUpdatingBehavior in WicketTester

In my Wicket application I used one radio button with "yes" and "no" options. If I select "No", I should display one dropdown choice. I wrote code using AjaxFormChoiceComponentUpdatingBehavior. How do I unittest this using WicketTester?
Solution for Wicket 1.5.x:
AbstractAjaxBehavior behavior = (AbstractAjaxBehavior)WicketTesterHelper.
findBehavior(getTester().getComponentFromLastRenderedPage("path:to:component"),
AjaxFormChoiceComponentUpdatingBehavior.class);
getTester().executeBehavior(behavior);
First select the radio button that you want.
form.select("path to radio button", 0/1)
Then execute ajax behaviour:
tester.executeBehavior((AbstractAjaxBehavior)tester.getComponentFromLastRenderedPage("path to radio buttons").getBehaviors().get(0));
Here is my piece of code which works perfectly for me with select box but should fiat as well for radio button if you change Behaviour class. Needed steps are:
Insert new value into form (use FormTester)
Find behaviour
Execute behaviour on change
Here is an example of code:
//simulate insert new value
FormTester formTester = tester.newFormTester(PANEL_ID + FORM);
formTester.setValue("selectBox", "newValue");
//Find onchange behaviour
AjaxFormComponentUpdatingBehavior behavior =
(AjaxFormComponentUpdatingBehavior) WicketTesterHelper.findBehavior(
tester.getComponentFromLastRenderedPage(PANEL_ID + FORM + ":" + "selectBox"),
ajaxFormComponentUpdatingBehavior.class);
//execute onchange
tester.executeBehavior(behavior);
I missed the par how to update form value in previous answers.
If the radio button is on a form I think you should use the FormTester class:
http://wicket.apache.org/apidocs/1.4/org/apache/wicket/util/tester/FormTester.html
For an example of an Ajax form submit test you can take a look at:
http://www.java2s.com/Open-Source/Java-Document/J2EE/wicket-1.4/org/apache/wicket/ajax/form/AjaxFormSubmitTest.java.htm
Try something like this:
tester.executeAjaxEvent("form:myRadioButtonId", "onchange");
This turns out to be somewhat painful, at least in Wicket 1.4 (I haven't tried with 1.5).
Via a web search, I found hints in Mischa Dasberg's blog. Basically, you can't use the BaseWicketTester.executeAjaxEvent((String componentPath, String event) method because the behavior you're using isn't an AjaxEventBehavior and you can't use the BaseWicketTester.executeBehavior(final AbstractAjaxBehavior behavior) because it wipes out the request parameters.
Mischa's solution was to implement his own executeBehavior method in a parent test case, which worked for his situation, but not for my need, as it assumed the request parameter id was the same as the full component path.
I've done something similar by implementing my own executeAjaxBehavior in an extension of WicketTester, but assuming (as is true in my case) that the request parameter is the last ":" separated section of the component path:
public void executeAjaxBehavior(String path, String value) {
AbstractAjaxBehavior behavior = (AbstractAjaxBehavior) getComponentFromLastRenderedPage(path).getBehaviors().get(0);
CharSequence url = behavior.getCallbackUrl(false);
WebRequestCycle cycle = setupRequestAndResponse(true);
getServletRequest().setRequestToRedirectString(url.toString());
String[] ids = path.split(":");
String id = ids[ids.length-1];
getServletRequest().setParameter(id, value);
processRequestCycle(cycle);
}
Both his solution and mine (based on his) also assume that the behavior is the first (or only) one on the component.
This is a bit clunky, but something like this may work for you.
It might be better if the ids and behavior were gotten separately and passed as parameters, and of course you might do well to find the first behavior that actually was an AjaxFormChoiceComponentUpdatingBehavior instead of blithely assuming it was the first behavior, but this is a start.
This is also similar code to what's inside the BaseWicketTester class for the other behavior testing methods, which might be worth looking through.

Categories

Resources