I have a text box where I enter the text during tests, for example "cars", but very often not whole text appear in the text box, for example only "car". So my question is how can I wait until whole text will appear and how can I check that?
This
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.textToBePresentInElement(element, "text"));`
Doesn't work for me. It is the same result as without it.
[EDIT]
Thread.sleep(4000);
Doesn't work for me too.
Also
(new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
return d.findElement(...).getAttribute("value").length() != 0;
}
});
Will not work for me, because there is no value, because it is not saved.
You are close, the only thing missing is a loop to catch Selenium TimeOut Exceptions whilst you are polling the element. Also, I would rather go with the isDisplayed() instead of isTextPresent() and focus my Xpath on locating the 'cars' text that you are after.
Here is the method for waiting, it will return true/or false based on if the element was present during the polling time (10sec for example); worth noting that if the element is found as present earlier than the 10sec limit the loop will break and will return true:
public boolean waitForElement(String elementXpath, int timeOut) {
try{
WebDriverWait wait = new WebDriverWait(driver, timeOut);
boolean elementPresent=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(elementXpath)).isDisplayed());
System.out.printf("%nElement is present [T/F]..? ")+elementPresent;
}
catch(TimeoutException e1){e1.printStackTrace();elementPresent=false;}
return elementPresent;
}
Now, it really boils down how you 'grab' the element. You mentioned, you want the full cars text to appear. Hypothetically speaking let's say the element is located by id=brand and you want the text inside an a href link. So you want something like this for your xpath:
//div[#id='brand']//a[text()[contains(., 'cars')]]
Please note that the above is case-sensitive so it will fail if you are looking for Cars.
Best of luck!
Update after OP's comment:
Correcting the way we identify the web-element:
//div[#id='widget_dijit_form_TextBox_0']//div//input
Now all is needed is to use the waitForElement above until the element appears. When it does you can grab the text by using:
String textInsideInputTag = elementPresent.getText();
Now you can compare this to your intended value (i.e. 'cars'):
if(textInsideInputTag.equals("cars")){
System.out.println("Successfully found cars inside <input> tag");
}
else{
System.out.println("Couldn't locate cars in the element!");
}
Related
Dynamically created text-box on add button click with same id and class-name not able to send text second/third text-box.
List<WebElement> clientidtxt = driver.findElements(By.xpath("//label[contains(.,'Client ID')]/following::input[#id='CId']"));
for (WebElement webElement1 : clientidtxt)
{
if(!clientidtxt.isEmpty())
{
clientId.sendKeys(Keys.ENTER);
clientId.sendKeys(uuid);
System.out.println(webElement1.getText());
}
}
I have already send text to first text-box but not able to send to the second or third ....
Your code is kinda confusing.
You are looping through a list of web elements but inside you check to see if the list is empty... it can't be if you are looping through the list so that part can be removed.
You are using a foreach but you aren't actually using webElement1 but instead are referencing clientId which isn't declared in the code you posted.
I've updated the code with a best guess. Try this and see if it's what you are looking for.
List<WebElement> clientidtxt = driver.findElements(By.xpath("//label[contains(.,'Client ID')]/following::input[#id='CId']"));
for (WebElement webElement1 : clientidtxt)
{
webElement1.sendKeys(Keys.ENTER); // What's this for? Can this be removed?
webElement1.sendKeys(uuid);
System.out.println(webElement1.getText()); // if webElement1 is an INPUT, this needs to be webElement1.getAttribute("value") to return what the INPUT contains
}
condition:how To check data is displayed or not
Boolean isPresent3 = driver.findElements(By.cssSelector(".input-horizon.horizon-program-guide.form-control.ng-pristine.ng-untouched.ng-valid.ng-not-empty.ng-valid-min")).size()> 0;
if (isPresent3 == true) {
System.out.println("Aflam data exists");
}
else {
System.out.println("Aflam data does not exists");
}
Boolean isPresent3 = driver.findElements(By.cssSelector("csspath")).size()> 0;
this code some time works sometimes not any good solution that works evrytime
To check whether the element is visible use isDisplayed() method which returns boolean values (ie)
List<WebElement> element=driver.findElements(By.cssSelector(".input-horizon.horizon-program-guide.form-control.ng-pristine.ng-untouched.ng-valid.ng-not-empty.ng-valid-min"));
System.out.Println(element.size());
if(element.isDisplayed()==true){
System.out.Println("element is present");
}
else
{
System.out.Println("element is not present");
}
It checks whether the element is present on the page. To check visibility of the element you should use "isDisplayed()". My suggestion is to use both the conditions.
List<WebElement> elem= driver.findElements(By.cssSelector(".input-horizon.horizon-program-guide.form-control.ng-pristine.ng-untouched.ng-valid.ng-not-empty.ng-valid-min"));
if(elem.size()> 0){
if(elem.get(0).isDisplayed()){
System.out.println("Element is dislayed and present");
}
}
else{
System.out.println("Element is not present");
}
Well, if it works sometime and not all the time then it may be the case where the element takes time to be available in dom and your findElements statement executed before it's available!
Quick and dirty work-around is, add sleep, for example Thread.sleep(3000).
Anther work-around is you can have waitForElementpresent condition in try catch block and in catch block you can set flag false!
If you are using qaf you can use assertion/verification available with driver and element object where you don't need to use any of above work-arounds. For example in your case it may look like:
$("css=csspath").verifyPresent(); // checks only presence in dom.
$("css=csspath").verifyVisible();// ensures present and displayed
I am facing problem while checking the clickable web element.
So i have to check the alphabetic series and some of the alphabet are clickable and some are not clickable.
i used for loop for it starting with xpath of alphabet 'A'
and going in loop till alphabet 'Z'.
but as soon as xpath of alphabet A is click & pass it goes to alphabet 'B'
which is not clickable and due to this whole script is getting fail.
here is the code
for(int j=3; j<=26;j++) {
String T1 =".//*[#id='twctvEl']/div/div/div[1]/ul/li[";
String T2 = "]/a";
String T12 = T1+j+T2;
chrome.findElement(By.xpath(T12)).click();
String alpha =chrome.findElement(By.xpath(T12)).getText();
System.out.println("checking the alphabet"+alpha);
}
Please advice here
NOTE: In the series of alpha bet from A-Z only B,Q,S,X,Y,Z are not clickable rest all are clickable.
You can add waits before element to become clickable:
for(int j=3; j<=26;j++)
{
String T1 =".//*[#id='twctvEl']/div/div/div[1]/ul/li[";
String T2 = "]/a";
String T12 = T1+j+T2;
WebElement el = chrome.findElement(By.xpath(T12));
WebDriverWait wait = new WebDriverWait(driver, timeout);
WebElement el= wait.until(ExpectedConditions.elementToBeClickable(element));
el.click();
String alpha =el.getText();
System.out.println("checking the alphabet"+alpha);
}
You can check if the element is visible and enabled before clicking on it
WebElement letter = chrome.findElement(By.xpath(T12));
if (letter.isDisplayed() && letter.isEnabled()) {
letter.click();
}
Well, it seems that when you click the element "A", it take you to another page or context and for this reason, during next iteration chrome driver is not able to find your Element "B" using xPath.
I'm using Java, Selenium, and Chrome for test automation. Our developers recently upgraded our UI from AngularJS to Angular2 (not sure if that matters). But since then, sendKeys is inputting incomplete characters in to the text field. Here's an example:
public void enterCustomerDetails()
{
txtFirstName.sendKeys("Joh201605130947AM");
txtSurname.sendKeys("Doe201605130947AM");
txtEmail.sendKeys("johndoe#gmail.com");
}
I also tried using executeScript. It didn't work. It can enter complete characters but the form thinks the field is null.
public void forceSendKeys(WebElement element, String text)
{
if (element != null)
((JavascriptExecutor) this.webDriver).executeScript("arguments[0].value=arguments[1]", element, text);
}
public void enterCustomerDetails()
{
forceSendKeys(txtFirstName, "Joh201605130947AM");
forceSendKeys(txtSurname, "Doe201605130947AM");
forceSendKeys(txtEmail, "johndoe#gmail.com");
}
I also tried using .click() before .sendKeys and adding in sleep time. They didn't work too.
I got an idea to enter the characters 1 by 1 from this post: How to enter characters one by one in to a text field in selenium webdriver?
It worked but that means I have to rewrite all my codes from sendKeys to the new function:
public void sendChar(WebElement element, String value)
{
element.clear();
for (int i = 0; i < value.length(); i++){
char c = value.charAt(i);
String s = new StringBuilder().append(c).toString();
element.sendKeys(s);
}
}
public void enterCustomerDetails()
{
sendChar(txtFirstName, "Joh201605130947AM");
sendChar(txtSurname, "Doe201605130947AM");
sendChar(txtEmail, "johndoe#gmail.com");
}
If you guys know a better way, please help! :)
I assume this is caused by this Angular2 issue https://github.com/angular/angular/issues/5808
Angular can't process input events when they arrive too fast.
As a workaround you would need to send single characters with a small delay between each.
I stumbled upon this error when doing integration tests with NightwatchJS (which uses selenium).
So I'm writing this for people coming here in the future.
I wrote this extension command for nightwatch:
exports.command = function (selector, value, using) {
var self = this;
self.elements(using || 'css selector', selector, function (elems) {
elems.value.forEach(function (element) {
for (var c of value.split('')) {
self.elementIdValue(element.ELEMENT, c);
}
});
});
return this;
};
Which can be used in this way:
var username = 'integration#test.com';
browser.setValueSlow('input[ngcontrol=username]', username); //Works with ng2!
This issue was also discussed on NightwatchJS's github here
By using Actions class, this issue solved for me
Tried many ways as mentioned above. Also tried to setvalue by js executescript
Finally, found this code and it worked well for grid component built on angular
actions.sendKeys(webElement,
modifiedValue).perform();
I was getting this error too in Java, Selenium. You might also be getting this error too while writing your codes - "sendKeys (CharSequence) from the type Webelement refers to the missing type charSequence"
I tried varying the wait time and even typing extra characters before the main characters, they did not work.
The simple trick I used was to change the Java Compiler version from JRE 9 to JRE 10.
This is due to a bug in Angular apps. Workaround is to put a sleep function.
public void setText(By element, String text) {
sleep(100); // Angular version < 2 apps require this sleep due to a bug
driver.findElement(element).clear();
driver.findElement(element).sendKeys(text);
}
i had the same problem, if you see it carefully selenium is changing the characters, some numbers perform a backspace or other symbols, i read it happens when using selenium with vncserver, i changed to firefox.... and it worked.
if that's not your problem, maybe sending the data in parts:
input1="Joh201605130947AM"
txtFirstName.sendKeys(input1[0:7])
txtFirstName.sendKeys(input1[8:end])
Using
Chromium 78.0.3904.70,
Vaadin Flow Framework 14.1.3,
Selenium 3.141.59
and OpenJDK 11.0.5
the behavior also occurs and is even worse:
I see that the character is typed in and suddenly after that it disappears.
A workaround is to be persistent and just try it again. And again. Until the character is finally typed in.
// Type in every single character
for (int i = 0; i < textToType.length(); i++) {
boolean typingCharacterWasSuccessful = false;
// If typing was not successful before, just type again
while (!typingCharacterWasSuccessful) {
// Type in the character
char singleCharacterToType = textToType.charAt(i);
htmlTextfeld.sendKeys(Character.toString(singleCharacterToType));
// Wait a little. Maybe alternatively/additionally wait.until(...)
Thread.sleep(200);
// Check typed in string.
String inputValueAfterTyping = htmlTextfeld.getAttribute("value");
if (inputValueAfterTyping.length() > i + 1) {
// Alternatively: delete everything and start all over
throw new Exception("Input value too long. Maybe character typed in twice!?");
}
// Typing was successful if the value in the input field is as expected (up to now)
typingCharacterWasSuccessful
= inputValueAfterTyping.equals(textToType.substring(0, i + 1));
}
}
I had a similar issue for big texts in Java.
I overcome the issue using the copy and paste of the text in the keyboard-related methods, as in the following method:
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
public static void clickAndSetMultilineText(WebElement element, String text) {
/** click on element **/
element.click();
/** clear older content of the text using keyboard functionality **/
element.sendKeys(Keys.CONTROL + "a"); // select all text
element.sendKeys(Keys.DELETE); // delete old text
StringSelection stringSelection= new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, null); // copy text to the keyboard
element.sendKeys(Keys.CONTROL+"v"); // paste text to the field
}
Hope this is helpful.
try this code.. other way to set values using javascript
WebDriver driver = new FirefoxDriver();
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("document.getElementsByName('body')[0].setAttribute('type', 'text');");
driver.findElement(By.xpath("//input[#name='body']")).clear();
driver.findElement(By.xpath("//input[#name='body']")).sendKeys("Ripon: body text");
Hi I would like to count how many times a text Ex: "VIM LIQUID MARATHI" appears on a page using selenium webdriver(java). Please help.
I have used the following to check if a text appears in the page using the following in the main class
assertEquals(true,isTextPresent("VIM LIQUID MARATHI"));
and a function to return a boolean
protected boolean isTextPresent(String text){
try{
boolean b = driver.getPageSource().contains(text);
System.out.println(b);
return b;
}
catch(Exception e){
return false;
}
}
... but do not know how to count the number of occurrences...
The problem with using getPageSource(), is there could be id's, classnames, or other parts of the code which match your String, but those don't actually appear on the page. I suggest just using getText() on the body element, which will only return the page's content, and not HTML. If I'm understanding your question correctly, I think that is more what you are looking for.
// get the text of the body element
WebElement body = driver.findElement(By.tagName("body"));
String bodyText = body.getText();
// count occurrences of the string
int count = 0;
// search for the String within the text
while (bodyText.contains("VIM LIQUID MARATHI")){
// when match is found, increment the count
count++;
// continue searching from where you left off
bodyText = bodyText.substring(bodyText.indexOf("VIM LIQUID MARATHI") + "VIM LIQUID MARATHI".length());
}
System.out.println(count);
The variable count contains the number of occurrences.
There are two different ways to do this:
int size = driver.findElements(By.xpath("//*[text()='text to match']")).size();
This will tell the driver to find all of the elements that have the text, and then output the size.
The second way is to search the HTML, like you said.
int size = driver.getPageSource().split("text to match").length-1;
This will get the page source, the split the string whenever it finds the match, then counts the number of splits it made.
You can try to execute javascript expression using webdriver:
((JavascriptExecutor)driver).executeScript("yourScript();");
If you are using jQuery on your page you can use jQuery's selectors:
((JavascriptExecutor)driver).executeScript("return jQuery([proper selector]).size()");
[proper selector] - this should be selector that will match text you are searching for.
Try
int size = driver.findElements(By.partialLinkText("VIM MARATHI")).size();