Java Selenium webdriver filling list webelement manually - java

first of all:
I want to fill a List manually with element.add();
Because the elements of the page I am working with is just showing a specific range of elements, I can't just load all elements in a List<WebElement>.
That's why I want to do functions to check if an element exists in my List, if it doesn't exists there I will add it.
I want to know if there is a way to iterate specific elements like element.next();
Here is the xpath I am getting my elements:
###.findElement(By.xpath(".//a[starts-with(#href, '/p/')]"));

You ca use following snippet to fulfill your requirement
public boolean isDropdownOptionExists(String optionToBeVerified, By optionWhereToBeVerified) {
boolean isOptionFound = false;
Select optionsInDropDown = new Select(driver.findElement(optionWhereToBeVerified));
List<WebElement> availableOptions = optionsInDropDown.getOptions();
for(WebElement option: availableOptions) {
if(option.getText().equals(optionToBeVerified)) {
isOptionFound = true;
break;
}
}
return isOptionFound;
}

Related

Selenium webdriver - Iterate, find webelement and then click on it - how can I do that?

I'd like to find the webelement that has as the visible text "7000118777", however I don't know how to exactly find it in the list and then click on it.
When I iterate it shows that the index is -1 and I get the error of "productList.get(-1);" - this is not the correct one.
public void findProductAndAddToCart(String product) {
List<WebElement> productList = SeleniumDriver.getDriver().findElements(By.className("bcom--txtBold"));
for (WebElement webElement : productList) {
String elements = (webElement.getAttribute("innerHTML"));
int indexOfProduct = elements.indexOf("7000118777");
System.out.println("Indeks produktu "+indexOfProduct);
}
productList.get(-1);
As you have not provided a link to url or screenshot of your html, this is what i understand from your question that you want to click on a element from a list where visible text is "7000118777". I also believe that you located the elements correct i.e., your productList. Please refer the below code (Replace myDriver with your WebDriver) :
List<WebElement> productList = myDriver.findElements(By.className("bcom--txtBold"));
for (int i=0; i< productList.size();i++) {
String element=productList.get(i).getText();
if(element.equals("7000118777"))
{
productList.get(i).click();
}
}

click on button which have values from array or list

I have a list of dropdown predefine values from the web site as below
"KSA", "UAE", "Bahrain", "Oman", "Qatar", "Kuwait","Egypt","Jordan", "Tunisia" , "Morocco", "Palestine","Iraq"
need a helping selenium/ katalon code for click on those values
Put the countries in a list and if the dropdown is a select element, you can use the following code to select, for example "KSA":
def countries = ["KSA", "UAE", "Bahrain", "Oman", "Qatar", "Kuwait","Egypt","Jordan", "Tunisia" , "Morocco", "Palestine","Iraq"]
WebUI.click(findTestObject('dropdown-element'))
WebUI.selectOptionByValue(findTestObject('dropdown-element'), countries[0], false)
if you are using c#, then try this
IWebDriver driver = new ChromeDriver();
IList<IWebElement> dropdownLists = driver.FindElements(By.Id("yourdropdown"));
foreach (IWebElement item in dropdownLists)
{
if (item.Text.Equals("KSA"))
{
item.Click();
}
//if(item.Text.Equals("UAE")) ..... etc
}
you can also use a switch condition to select your place within the foreach statement

Extract text from multiple xpath and assert text - Selenium/Java

I need to find the text in an element and assert whether it matches with my required result.
The thing is, there can be n number of element from 1-100 in the page. So I can't get the xpath of all those elements and then assert the text in it.
The xpath looks like this: (from the first element)
(//DIV[#class='issues-list-item clearfix'])[1]
(//DIV[#class='issues-list-item clearfix'])[2]
(//DIV[#class='issues-list-item clearfix'])[3]
(//DIV[#class='issues-list-item clearfix'])[4]
....
(//DIV[#class='issues-list-item clearfix'])[100]
How do I loop through these xpath and assert for my text?
I tried the below method after referring few articles and it really did not help.
private static WebElement element = null;
private static List<WebElement> elements = null;
public WebElement test() throws Exception {
elements = driver.findElements(By.xpath("(//DIV[#class='issues-list-item clearfix'])[1]"));
for (WebElement element : elements) {
List<WebElement> TE = element.findElements(By.xpath("(//DIV[#class='issues-list-item clearfix'])[1]"));
if (TE.size() > 0) {
String myText = TE.get(0).getText();
if (myText.contains("High")) {
return element;
}
}
}
return null;
You can try this :
public List<WebElement> test() throws Exception {
List<WebElement> TE = new ArrayList<WebElement>();
elements = driver.findElements(By.xpath("(//DIV[#class='issues-list-item clearfix'])"));
for (WebElement element : elements) {
if(element.getText().contains("High")) {
TE.add(element);
}
}
return TE;
}
Note that , it will return a list web element which contains High as text.
The more efficient way to do this is to add your check for "High" to the locator. That way you don't have to loop through all the elements to find only the ones you want. Your locator does all that work for you and more quickly. There's also a lot less code.
public List<WebElement> test() throws Exception {
return driver.findElements(By.xpath("(//DIV[#class='issues-list-item clearfix'][contains(.,'High')])"));
}
There are a number of ways you can verify that the desired element is found. One way would be to use a TestNG Assert like
Assert.assertTrue(test().size() > 0, "Verify an element containing 'High' was found.");
//DIV[#class='issues-list-item clearfix'])[1] your query is wrong. The [1] at the end means that it will select oinly teh first item from all the items matching the query before, aka you will only compare against the first one. The second query you won't need, neitehr the if checking for size (optionally before the for loop)

How to parameterize java method to iterate on elements in a table?

I have a table with products' names which locators differs only by index. I would like to use one method to iterate on all of the elements, because the number of elements can be changed up to 10 and I need to go through them all.
#FindBy(xpath="(//*[#class=\"product-name\"])[2]")
protected WebElement productName1;
#FindBy(xpath="(//*[#class=\"product-name\"])[3]")
protected WebElement productName2;
#FindBy(xpath="(//*[#class=\"product-name\"])[4]")
protected WebElement productName3;
A method that I want to parametrize is:
public String checkProductsInCart() {
wait.until(ExpectedConditions.visibilityOf(productName1));
String productName1String = productName1.getText();
return productName1String; }
How should I do that? I would appreciate your help.
Obtain all of the product name elements in a single list:
#FindBy(xpath="//*[#class=\"product-name\"]")
protected List<WebElement> productNameElements;
Then, in your test method, you can iterate over the elements (you could use for loop with an int index if you prefer):
List<String> productsInCart = new ArrayList<>();
for (WebElement element : productNameElements) {
productsInCart.add(nameOfProductInCart(element));
}
You can alter your check method to take a WebElement as a parameter:
public String nameOfProductInCart(WebElement element) {
wait.until(ExpectedConditions.visibilityOf(element));
return element.getText();
}
Alternatively, if this doesn't work (e.g. because the product list takes time to populate), you could use the WebDriver instance and programmatically perform each check:
List<String> productNames = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
WebElement element = driver.findElement(By.xpath("(//*[#class=\"product-name\"])[" + i + "]"));
wait.until(ExpectedConditions.visibilityOf(element));
productNames.add(element.getText());
}
UPDATE: To answer the question in your comment, if you want the elements, rather than their text, you can store the elements themselves in a list:
List<WebElement> productNameElements = new ArrayList<>();
for (int i = 2; i <= 10; i++) {
WebElement element = driver.findElement(By.xpath("(//*[#class=\"product-name\"])[" + i + "]"));
wait.until(ExpectedConditions.visibilityOf(element));
productNameElements.add(element);
}
Now you can access the elements individually by getting them by index from the productNameElements list:
productNameElements.get(0); // First item
This should be easier to manage than having a separate variable for each item.
Just addendum to #ELEVATE's answer, You can find element via className:
#FindBy(className = "product-name")
private List<WebElement> tableItems;
or
#FindBy(xpath="//*[#class='product-name']")
private List<WebElement> tableItems;
but this depends if this is unique identifier...

selenium filter with Predicate

I am looking to use and learn about the Predicate and Lambda expression. In particular using it with selenium.
Imagine you have a large selection(List) of WebElements and you want to apply a predicate filter to it so that the list is smaller .
Am I on the right track for 1,2,3 below what changes would I meed to make?
List<WebElement> webElements = driver.findElements(By.cssSelector(".someClassName")); // returns large list
// then try and filter down the list
Predicate<WebElement> hasRedClass -> Predicate.getAttribute("class").contains("red-background");
Predicate<WebElement> hasDataToggleAttr -> Predicate.getAttribute("data-toggle").size() > 0;
// without predicate probably looks like this
//driver.findElements(By.cssSelector(".someClassName .red-background"));
// 1. this is what I think it should look like???
List<WebElement> webElementsWithClass = webElements.filter(hasRedClass);
// 2. with hasDataToggleAttr
List<WebElement> webElementsWithDataToggleAttr = webElements.filter(hasDataToggleAttr);
// 3. with both of them together...
List<WebElement> webElementsWithBothPredicates = webElements.filter(hasRedClass, hasDataToggleAttr);
I hope here is what you are looking for:
List<WebElement> webElements = driver.findElements(By.cssSelector(".someClassName")); // returns large list
// then try and filter down the list
Predicate<WebElement> hasRedClass = we -> we.getAttribute("class").contains("red-background");
Predicate<WebElement> hasDataToggleAttr = we -> we.getAttribute("data-toggle").length() > 0;
// without predicate probably looks like this
//driver.findElements(By.cssSelector(".someClassName .red-background"));
// 1. this is what I think it should look like???
List<WebElement> webElementsWithClass = webElements.stream()
.filter(hasRedClass).collect(Collectors.toList());
// 2. with hasDataToggleAttr
List<WebElement> webElementsWithDataToggleAttr = webElements.stream()
.filter(hasDataToggleAttr).collect(Collectors.toList());
// 3. with both of them together...
List<WebElement> webElementsWithBothPredicates = webElements.stream()
.filter(hasDataToggleAttr.and(hasRedClass)).collect(Collectors.toList());

Categories

Resources