Verify Select element - java

Good afternoon in my timezone
I am using Selenium to test my web application.There is a dropdown list on a page that when we choose one value from it, it will fullfill 3 input text fields and select values in three more dropdown lists.
There is a lot of possible combinations to fullfill those fields so i want to use regular expressions to verify the fulfillment.The Dropdown list when selected makes an Ajax call to fullfill all those fields.
So i was thinking to use the following statements to make the "assertions":
wait.until(ExpectedConditions.textToBePresentInElement(By.xpath("//input[#name='name']"), text));
This statement will be used to check the input fields, but i realize that the method "textToBePresentInElement" does not accept regular expression in the place of the text(second argument). Which options do i have ?
Because the fullfillment is made through Ajax , i have to wait , one possible solution is to use Thread.sleep while verifying the text through something like this driver.findElement().getText().matches("REgEx");
There is no better solution ?
To check the other 3 dropdown lists what method should i use ?
The Thread.sleep following this statement :
(new Select(driver.findElement(By.xpath("//select[#name='tipoTransacao']")))).getFirstSelectedOption().getText().matches
Thanks in advance
Best regards

Here is Java solution
public void waitUntilTextIsPresent(WebElement element, String regex, long timeout, long polling) {
final WebElement webElement = element;
final String regex = regex;
new FluentWait<WebDriver>(driver)
.withTimeout(timeout, TimeUnit.SECONDS)
.pollingEvery(polling, TimeUnit.MILLISECONDS)
.until(new Predicate<WebDriver>() {
public boolean apply(WebDriver d) {
return (webElement.getText().matches(regex);
}
});
}

A horrible mismash of Java & C# here, due to copy/pasting your examples and my working solution, but hopefully you can adapt it to just Java...
This should wait until the regex matches, you don't always have to use the ExpectedConditions class
public void WaitForTextPresent(By by, string regex, int maxSecondsToWait = 30)
{
new WebDriverWait(_webDriver, new TimeSpan(0, 0, maxSecondsToWait))
.Until(d => d.FindElement(by).getText().matches(regex));
}

Related

How to click on a button until an element appears on a page in selenium

I have a page with a dynamic table that periodically updates with new data. What I am trying to do is to click on a button and reload the page let's say every 3 seconds until the element from that table appears.
I know the xpath of the element I want to appear, but I just can't make it work using the FluentWait. I tried configuring as seen in the code below, but when I'm calling the method it keeps clicking on the button extremly fast disregarding the pollingEvery configuration and without giving the page enough time to fully reload itself. Code can be checked out below.
What I am not sure about is the return statement. I don't fully grasp what should it be if I only need to click on a button until that element appears.
What am I missing?
public void clickButtonUntilElementIsDisplayed(WebElement elementToBeClicked, String xPathOfElementToBeDisplayed){
FluentWait<WebDriver> wait = new FluentWait<>(getDriver());
wait.pollingEvery(Duration.ofSeconds(5));
wait.withTimeout(Duration.ofSeconds(200));
wait.ignoring(NoSuchElementException.class);
Function<WebDriver,WebElement> clickUntilAppearance = webDriver -> {
while(webDriver.findElements(By.xpath(xPathOfElementToBeDisplayed)).isEmpty())
click(elementToBeClicked);
return webDriver.findElement(By.xpath(xPathOfElementToBeDisplayed));
};
wait.until(clickUntilAppearance);
}
The class in which this method can be found extends Page
The return type of the Functional Interface need to be changed. There are 2 cases in which the functional interface will keep looping.
Value returned is null.
It threw an Exception mentioned as part of ignoring
Don't use while. Use if condition. For every pollingEvery this Functional Interface would get executed.
Function<WebDriver,WebElement> clickUntilAppearance = webDriver -> {
List<WebElement> tableElements = webDriver.findElements(By.xpath(xPathOfElementToBeDisplayed));
if(tableElements.isEmpty()) {
click(elementToBeClicked);
return null;
} else {
return tableElements.get(0);
}
};
WebDriverWait w = new WebDriverWait(driver, 5);// 5seconds
w.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("element_location")));

How do I make an xpath with a variable for a selenide test

I want to write a testmethod which I can give a parameter which will define which element to test.
Something like;
public void addImage(String imageNr){
$(By.xpath("(//input[#name='image'])['" + imageNr + "']"));
}
To get i.e. (//input[#name='image'])[2] or (//input[#name='image'])[3]
How would I go about that?
within Selenide you have something called the ElementsCollection. More information can be found on this page: https://selenide.gitbooks.io/user-guide/content/en/selenide-api/elements-collection.html
What you can do is transform the SelenideElement to an ElementsCollection by using double dollar signs:
For example:
This .get requires an Integer type. It will give you first all elements and you can take the second element from the returned list.
$$(By.xpath("(//input[#name='image'])).get(pageNr)
You will still need to do an action after getting this. for Example .click();
Good luck with it.
You can format the XPath String expression with the use of String.format, as following:
public void addImage(String imageNr){
String xpath = "(//input[#name='image'])[{0}]";
xpath = String.format(xpath,imageNr);
$(By.xpath(xpath));
}

How to extract the display attribute of an element using Selenium Webdriver and Java

unable to locate the hidden element in div
<div id="divDuplicateBarcodeCheck" class="spreadsheetEditGui" style="z-
index: 1200; width: 640px; height: 420px; top: 496.5px; left: 640px;
display:block"> ==$0
I want to locate the display element, but the element is hidden, i have written the code for it too.
String abc=d.findElement(By.xpath("//div[#id='divDuplicateBarcodeCheck']/"))
.getAttribute("display");
System.out.println(abc);
Thread.sleep(3000);
if(abc.equalsIgnoreCase("block"))
{
d.findElement(By.id("duplicateBarcodeCheck")).click();
System.out.println("duplicate barcode Close");
}
else
{ System.out.println("Barcode selected");}
There is no such attribute as display. It's part of style attribute.
You can either find the element and get its attribute style:
String style = d.findElement(By.xpath("//div[#id='divDuplicateBarcodeCheck']")).getAttribute("style");
if(style.contains("block")) {
d.findElement(By.id("duplicateBarcodeCheck")).click();
System.out.println("duplicate barcode Close");
} else {
System.out.println("Barcode selected");}
}
OR you can find this element directly with cssSelector (it's also possible with xpath):
WebElement abc = d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"))
Note, that above will throw NoSuchElementException if the element was not found. You can use try-catch block to perform similar operations just like you did in if-else statement like this:
try {
d.findElement(By.cssSelector("div[id='divDuplicateBarcodeCheck'][style*='display: block']"));
d.findElement(By.id("duplicateBarcodeCheck")).click();
System.out.println("duplicate barcode Close");
} catch (NoSuchElementException e) {
System.out.println("Barcode selected");
}
If I'm getting you correct you are trying to archive checking if an element is displayed or not. You could do something like this using plain selenium and java:
// the #FindBy annotation provides a lazy implementation of `findElement()`
#FindBy(css = "#divDuplicateBarcodeCheck")
private WebElement barcode;
#Test
public void example() {
driver.get("http://some.url");
waitForElement(barcode);
// isDisplay() is natively provided by type WebElement
if (barcode.isDisplayed()) {
// do something
} else {
// do something else
}
}
private void waitForElement(final WebElement element) {
final WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOf(element));
}
Your Test (an end-to-end UI test!) should not stick to an implementation detail like display:none or display:block. Imagine the implementation will be changed to remove the element via javascript or something. A good selenium test should always try represent a real users perspective as good as possible. Means if the UI will still behave the same your test should still be successful. Therefore you should do a more general check - is an element displayed or not.
This is one of the basic functionalities of Seleniums WebElement interface, or to be even more precise its isDisplayed() method.
Quote from the Selenium Java Docs:
boolean isDisplayed()
Is this element displayed or not?
This method avoids the problem of having to
parse an element's "style" attribute.
Returns:
Whether or not the element is displayed
Furthermore I would recommend to write some small helper methods for things like that, in my experience it's a common use case you'll face more often.
helper method could for instance look something like this:
boolean isElementVisible(final By by) {
return driver.findElement(by).isDisplayed();
}
boolean isElementVisible(final WebElement element) {
return element.isDisplayed();
}
If you are using some Selenium abstractions like FluentLenium or Selenide things will become even more convenient because they provide things like assertion extensions and custom matchers for well known assertion libraries like assertJ, hamcrest, junit.
For instance with FluentLenium and AssertJ (a stack that i can personally recommend) the answer for your problem is looking as easy as this:
// check if element is displayed
assertThat(el("#divDuplicateBarcodeCheck")).isDisplayed();
// check if element is not displayed
assertThat(el("#divDuplicateBarcodeCheck")).isNotDisplayed();
Some more thoughts:
You should also use CSS selectors if possible instead of xPath selectors. CSS selectors are less fragile, it will speed up your tests and are better readable.
You should have a look at implicit waits instead of using Thread sleeps (bad practice). you can again implement helper methods like this by yourself, e.g:
void waitForElement(final WebElement element) {
final WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOf(element));
}
void waitForElement(final By by) {
final WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfElementLocated(by));
}
void waitForElementIsInvisible(final By by) {
final WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.invisibilityOfElementLocated(by));
}
or (what i would recommend) use a library for that, for instance Awaitility
If your are looking for a more extended example you can have a look here:
java example with plain selenium
example using fluentlenium and a lot of other helpful stuff
Seems there is an extra / at the end of the xpath which you need to remove. Additionally, you need to induce WebDriverWait for visibilityOfElementLocated(). So effectively your line of code will be:
String abc = new WebDriverWait(d, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[contains(.,'Leave Balance')]//following::div[#id='applyleave_leaveBalance']"))).getAttribute("style");
System.out.println(abc);
if(abc.contains("block"))
{
d.findElement(By.id("duplicateBarcodeCheck")).click();
System.out.println("duplicate barcode Close");
}
else
{
System.out.println("Barcode selected");
}
Virtually, if() block is still an overhead and you can achieve the same with:
try {
new WebDriverWait(d, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//label[contains(.,'Leave Balance')]//following::div[#id='applyleave_leaveBalance']"))).click();
System.out.println("duplicate barcode Close");
} catch (NoSuchElementException e) {
System.out.println("Barcode selected");
}
Q1. I want to locate the display element, but the element is hidden, i have written the code for it too.
A1. As per your below code:
<div id="divDuplicateBarcodeCheck" class="spreadsheetEditGui" style="z-
index: 1200; width: 640px; height: 420px; top: 496.5px; left: 640px;
display:block"> ==$0
It doesn't look hidden, the problem is that your using incorrect xpath and element getter.
Use:
String abc = d.findElement(By.xpath("//div[#id='divDuplicateBarcodeCheck']"))
.getCssValue("display");
Instead of:
=> .getAttribute("display");
Alternative method using JavascriptExecutor:
JavascriptExecutor jse = (JavascriptExecutor) d;
String displayProperty = (String) jse.executeScript("return
document.getElementById('divDuplicateBarcodeCheck').style.display");
System.out.println("Display property is: "+displayProperty);

make wait function do something on and on if it fails

I am very beginner with Selenium and Java to write tests.
I know that I can use the code below to try to click on a web element twice (or as many time as I want):
for(int i=0;i<2;i++){
try{
wait.until(wait.until(ExpectedConditions.visibilityOfElementLocated
(By.xpath("//button[text()='bla bla ..']"))).click();
break;
}catch(Exception e){ }
}
but i was wondering if there is anything like passing a veriable to the wait function to make it do it ith times itself, something like:
wait.until(wait.until(ExpectedConditions.visibilityOfElementLocated
(By.xpath("//button[text()='bla bla ..']"),2)).click();
For example in here 2 may mean that try to do it two times if it fails, do we have such a thing?
Take a look at FluentWait, I think this will cover your use case specifying appropriate timeout and polling interval.
https://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/support/ui/FluentWait.html
If you can't find something in the set of ExpectedConditions that does what you are wanting you can always write your own.
The WebDriverWait.until method can be passed either a com.google.common.base.Function or com.google.common.base.Predicate. If you create your own Function implementation then it's good to note that any non-null value will end the wait condition. For Predicate the apply method simply needs to return true.
Armed with that I do believe there's very little you can't do with this API. The feature you're asking about probably does not exist out of the box, but you have full capability to create it.
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Function.html
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Predicate.html
Best of Luck.
Untested Snippet
final By locator = By.xpath("");
Predicate<WebDriver> loopTest = new Predicate<WebDriver>(){
#Override
public boolean apply(WebDriver t) {
int tryCount = 0;
WebElement element = null;
while (tryCount < 2) {
tryCount++;
try {
element = ExpectedConditions.visibilityOfElementLocated(locator).apply(t);
//If we get this far then the element resolved. Break loop.
break;
} catch (org.openqa.selenium.TimeoutException timeout) {
//FIXME LOG IT
}
}
return element != null;
}
};
WebDriverWait wait;
wait.until(loopTest);

Finding and Clicking element in list - Selenium

I have been messing around with automating this options page, and since it provides a variety of options each with its own sub-options, I do not want to take the time to identify and declare all of the elements by their xpath(or CSS.. either or). So I have this reliable code that does a good job at finding the text identifier in the HTML tags.
public void selectAnOption(String option) {
List<WebElement> choice = driver.findElements(By.xpath("//div[#class='atcui-scrollPanel-wrapper']/ul/li"));
for(WebElement e : choice){
System.out.println(e.getText());
if(e.getText().equals(option)){
e.click();
break;
}
}
}
By running this I get a printout like
Mileage
Transmission
Gas Type
And so on.So boom! I know that they are identified, but my e.click() is not actually clicking. I get no errors when I start the test it just says it passed but the button was never actually clicked. Below is the HTML segment I am working with and you can see how nested it is.
For Java 8 and above you can use:
public void selectAnOption(String option) {
List<WebElement> choice = driver.findElements(By.xpath("your_xpath"));
choice
.stream()
.filter(e->e.getText().equals(option))
.findFirst().get().click();
}
Fixed it.. for anyone with a similar issue, I believe it lies in the fact that when this html code was developed, there were excess spaces (used for design purposes or fitting elements during development..maybe?) so I used .contains instead of .equals. duh!!
public void selectAnOption(String option) {
List<WebElement> choice = driver.findElements(By.xpath("//div[#class='atcui-scrollPanel-wrapper']/ul/li"));
for(WebElement e : choice){
System.out.println(e.getText());
if(e.getText().contains(option)){
e.click();
break;
}
}
}

Categories