Reputation: 157
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.
Upvotes: 0
Views: 392
Reputation: 12781
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.
Upvotes: 2
Reputation: 1481
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...
Upvotes: 0