First character is missing inconstantly while sending string to the ExtJS input via sendKeys() - selenium

I randomly face the issue of missing first character in the ExtJS5 input field, while sending string via sendKeys method.
System info:
Ubuntu 14.04 -> docker containers with selenium grid (2.48.2)
Browser Firefox
Code is simple. I just get input web element, wait if it's clickable (i.e. isEnabled and isDisplayed), clear and send string:
wait.until(ExpectedConditions.elementToBeClickable(input)).clear();
input.sendKeys(value);
input element is simple too:
<input id="textfield-1455-inputEl" data-ref="inputEl" type="text" role="textbox" size="1" name="name" class="x-form-field x-form-required-field x-form-text x-form-text-default x-form-focus x-field-form-focus x-field-default-form-focus" autocomplete="off" componentid="textfield-1455"/>
I've noticed that issue occurs only for the first sendKeys() executing on the page:
Enter the page, wait for page load, work with first input
Enter the page, wait for page load, choose Enable into corresponding select box in order to enable input field, work with input field (image with this example is attached)
Enter the page, wait for page load, click button add in order to add the needed input field, work with input field
Other occurrences of the sendKeys on the page are stable.
I've looked for similar questions. It does not seem the issue with special characters (Missing characters example: 46-> 6; coverTest -> overTest; 1 -> nothing);
Also, I don't think it's an issue with missing characters due to remote webdriver infrastructure. The tests fail randomly but in exact places.
I know that I can use sendKeys(), then check the value of the input and repeat the sending action. However, it's the last option.
Is there any additional check needed for ExtJS input (any attribute in DOM) in order to be sure that input field is ready?
Appreciate your help.

Some times it happens with me. Try clicking on to the field first, but it's a wild guess assuming there can be some focus related issues.
Your sequence could be somewhat like this:
wait.until(ExpectedConditions.elementToBeClickable(input)).click();
input.clear();
input.sendKeys(value);
Weird thing is that I actually faced a situation, where I clicked it twice before sending values and it worked somehow :P
Another thing to try could be using a non-native javascript executor.
JavascriptExecutor myExecutor = ((JavascriptExecutor) driver);
myExecutor.executeScript("arguments[0].value='6';", input);
Sorry man, if the system would have been in front of me I'd have tried much more things.

I was struggling with sendKeys failing my self, but the following works pretty consistently. The method findVisibleElement is a custom wrapper for driver.until....
protected static boolean sendKeysByChar(By by, String input)
{
WebElement field = driver.findVisibleElement(by).base();
field.click();
field.clear();
for (int i = 0; i < input.length(); i++) {
String current = driver.findElement(by).getAttribute("value");
String nextChar = String.valueOf(input.charAt(i));
while (current.length() <= i || !current.endsWith(nextChar)) {
field.sendKeys(nextChar);
current = driver.findElement(by).getAttribute("value");
}
}
field = driver.findElement(by); // Refresh element
if (field.getAttribute("value").equals(input)) { return true; }
log.warn("Send keys by char failed.");
return false;
}

Related

Not able to Enter Text in a TextBox using Selenium Webdriver

I have a TextBox that appears on Radio Button Selection and I have to enter values in a particular format(XYZ989898-99). However I am unable to do so by using the commonly used methods of entering text in selenium.
Background info related to Textbox :
TextBox appears when user clicks on Yes radio button.
TextBox has default value as XYZ already entered.
SendKeys do not concatenate the text given without XYZ as well.
TextBox is inside an Iframe to which focus is shifted correctly.
The code does not fail, it just remained clicked on textbox without entering anything.
Approach 1 :
driver.findElement(locator).SendKeys("989898-99");
Approach 2 :
driver.findElement(locator).clear();
driver.findElement(locator).SendKeys("XYZ989898-99");
Approach 3 :
WebElement element = driver.findElement(locator);
Actions action1 = new Actions(driver);
action1.movetoElement(element).click().perform();
action1.sendKeys("XYZ989898-99");
HTML Sample :
<div class="value" ng-show="selectedValue" style="">
<label class="labelAboveTextBox">XYZ Number*</label>
<input type="text" class="Value" ng-model="XYZNumber" ng-
req="XYZNumber" xyz-input="" maxlength="12" style="value"
id="value" value="XYZ" required="required">
<!-- ngIf: invalidtspmessage -->
<span style="font-family: 'NeueHaasGroteskText';font-size:
0.7rem;color: black;">
Note: Enter XYZ is this format: XXXXXXXXX-XX
</span>
</div>
I would like to know If there is any other approach that can be used to get this problem resolved and also why does the above approaches failed to work.
You have used the wrong methods for sending the keys. (in approach 1 and 2)
Instead of .SendKeys(), you have to use .sendKeys() method for writing anything on UI side
Into the third approach, you have used the wrong method .movetoElement(). The method name is .moveToElement().
For sendKeys() don't need to use Actions class. basically, it is for Keyboard events and for mouse events.
(WebElement).sendKeys("989898-99"); // first approach you can use
(WebElement).clear(); // second approach you can use
(WebElement).sendKeys("XYZ989898-99");
Hope this will help you to solve your errors.
Other way you can use is to set the text is by using the JavaScriptExecutor. Give some delay before performing the action.
Try the below sample code :
Thread.sleep(3000);
((JavascriptExecutor) driver).executeScript("document.getElementById('value').value='XYZ989898-99';");
As the id is unique, you can use the JavaScript's getElementById() function to set the value.
If you want to set the text through the sendKeys() method and before that if you want to clear the text then simple clear() may not work instead you can try to delete the XYZ values first and try to send the values like below again :
// Wait for some time
Thread.sleep(3000);
// Locate the element first and store it in some variable
WebElement element = driver.findElement(By.id("value"));
// Fetch the existing text from the field first
String existingValue = element.getAttribute("value");
// Wait for some time
Thread.sleep(3000);
// Click on that element first so the focus will shift to there
element.click();
// Wait for some time
Thread.sleep(2000);
// Loop until the existing value length
for(int i=0;i<existingValue.length();i++) {
// Remove the existing character text one by one
element.sendKeys(Keys.BACK_SPACE);
}
// Try to send the text at the end, make sure that you should append XYZ as a prefix
element.sendKeys("XYZ989898-99");
I hope it helps...

Cant insert text - a msg that the element is not visible is displayed

I run automation on a site that after I click on a button and a screen of PayPal is opened for inserting details. The PayPal is opened in another tab. I added a syntax that move the testing to the relevant tab and then I insert a syntax that checks that the "email input" field exists (to check that it is really goes to the correct tab) - and the result of this test :- field exists.
Then - I add a syntax for the same field to insert the email and the test is failed - the text is not inserted and there is a msg that the field is not visible.
No need to do scroll because the filed is in the top of the screen.
What can I do in this case?
This is the relevant code:
String oldTab = driver.getWindowHandle();
comOps.clickOrChose(PLS.buyButton);
Thread.sleep(4000);
ArrayList<String> newTab = new ArrayList<String> (driver.getWindowHandles());
newTab.remove(oldTab);
driver.switchTo().window(newTab.get(0));
comOps.verifyElementExist(PLP.payPalEmail);
comOps.insertText(PLP.payPalEmail, "paypal-buyer#makeitleo.com");
The reason you get this error message is that the element apparently exists but is not visible when you try to enter text to it. There are a lot of possible reasons why the element is not visible.
Given that a new tab is opended a probable reason is that the page (and its elements) is still loading. If this is the case, you need to wait for the visiblity of the element, e.g. using this piece of code (before inserting text):
WebDriverWait wait = new WebDriverWait(driver, 300); //waiting up to 5 minutes
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(PLP.payPalEmail);
wait.until(condition);
Note: that this solution assumes that PLP.payPalEmail is of type org.openqa.selenium.WebElement. If it is of type org.openqa.selenium.By use visibilityOfElementLocated(By locator).
Telling from your code snippet, I assume that comOps is an object of a class wrapping all Selenium actions. So, it is a good idea to place the above code in some method inside that class which could look like this:
public void verifyElementVisible(WebElement element) {
WebDriverWait wait = new WebDriverWait(driver, 300); //ToDo: use configurable timeout
ExpectedCondition<WebElement> condition =
ExpectedConditions.visibilityOf(element);
wait.until(condition);
}
and call it like this
comOps.verifyElementVisible(PLP.payPalEmail);

WebDriver SendKeys Doesn't Send Value

I am trying to run selenium webdriver, imitating typing something to textbox and submit it.
I have this following code:
WebElement element = null;
element = waitForElementPresent(tFByCssSelector,timeoutValue);
element.clear();
element.click();
element.sendKeys("Input String");
The code successfully type "Input String" to the textField, but when I submit the form, it says the form is empty (The form had been set to catch empty input exception).
I wonder why sendKeys does not set the value of the text field even though it has typed the wanted value into the text field.
Try to tab out of the field:
element.sendKeys("Input String");
element.sendKeys(Keys.TAB);
It may be that the field value only gets set on blur.
As I see, all looks okay in your selenium code. I believe there is some problem with your HTML form.
The form should have proper action for receiving the values. A sample form is provided below.
<form action="http://foo.com" method="post">
<input name="say" value="Hi">
<input name="to" value="Mom">
<button>Send my greetings</button>
</form>
Based on what you use in method parameter, you will get the form data in POST or GET variables.
Also you don't need to click on the element before sending keys in Selenium.

Selenium Xpath Not Matching Items

I am trying to use Selenium's Xpath ability to be able to find an set of elements. I have used FirePath on FireFox to create and test the Xpath that I have come up with and that is working just fine but when I use the Xpath in my c# test with Selenium nothing is returned.
var MiElements = this._driver.FindElements(By.XPath("//div[#class='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
and the Html looks like this:-
Can Anyone please point me right as everything that I have read the web says to me that this Xpath is correct.
Thanking you all in-advance.
Please post the actual HTML, so we can simply "drop it in" into a HTML file and try it ourselves but I noticed that there is a trailing space at the end of the class name:
<div title="Actions Selected Jobs." class="context-menu-item " .....
So force XPath to strip the trailing spaces first:
var MiElements = this._driver.FindElements(By.XPath("//div[normalize-space(#class)='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
Perhaps you don't take into consideration the time that the elements need to load and you look for them when they aren't yet "searchable". UPDATE I skipped examples regarding this issue. See Slanec's comment.
Anyway, Selenium recommends to avoid searching by xpath whenever it is possible, because of being slower and more "fragile".
You could find your element like this:
//see the method code below
WebElement div = findDivByTitle("Action Selected Jobs");
//example of searching for one (first found) element
if (div != null) {
WebElement myElement = div.findElement(By.className("context-menu-item"));
}
......
//example of searching for all the elements
if (div != null) {
WebElement myElement = div.findElements(By.className("context-menu-item-inner"));
}
//try to wrap the code above in convenient method/s with expressive names
//and separate it from test code
......
WebElement findDivByTitle(final String divTitle) {
List<WebElement> foundDivs = this._driver.findElements(By.tagName("div"));
for (WebElement div : foundDivs) {
if (element.getAttribute("title").equals(divTitle)) {
return element;
}
}
return null;
}
This is approximate code (based on your explanation), you should adapt it better to your purposes. Again, remember to take the load time into account and to separate your utility code from the test code.
Hope it helps.

WebDriver does not use latest page source

I'm running into problems when executing Selenium 2.18 WebDriver tests against an Oracle SSXA-based site, which translates to tons of popups, Ajax-loaded content and iframes. For a given page, based on manual observation, the page is initially loaded with an empty sslw_doc_content_id span (no text). About a second later, the span still exists and contains text.
To check that this page has loaded, I'm using a WebDriverWait with a Predicate that checks that the sslw_doc_content_id span has non-empty text:
new Predicate<WebDriver>() {
#Override
public boolean apply(final WebDriver input) {
return StringUtils.isNotEmpty(input.findElement(By.id("sslw_doc_content_id")).getText());
}
}
Somehow, WebDriver always finds the WebElement but always returns an empty string when calling WebElement.getText(). And so this predicate always evaluates to false.
Inspecting the page with Chrome or Firefox shows that the element exists and does have text. When debugging the predicate, I've observed that input.getPageSource() contains the span with no text on its first invocation, but that input.getPageSource() contains the span with some text on its second invocation (after the page has been ajax-refreshed).
Why doesn't WebDriver consider the refreshed page source on the second invocation?
Thanks!
You can try loop:
int seconds = 0;
for (int seconds =0; seconds<30; seconds++) {
if (apply(driver)){
break;
}
Thread.sleep(1000);
}
The above loop will check every second if text is there and do it for 30 seconds. If it finds it, it will escape the loop. You can still add one more check after:
if (!apply(driver)){
throw new RuntimeException("Expected text still not there");
}
Or another approach, which I am using: Whenewer I have page to load for long time, I select element which is loaded among the last on the page and check its presence the same way:
for (int seconds =0; seconds<30; seconds++){
try{
driver.findElement(By.id("lastelementonpage"));
}catch (Exception e){
Thread.sleep(1000);
}
}
It turns out that WebDriver does not allow access to hidden elements, and this span was hidden.
http://code.google.com/p/selenium/wiki/FrequentlyAskedQuestions#Q:_Why_is_it_not_possible_to_interact_with_hidden_elements?
I've resorted to using the JavaScript-based solution described in the above link.