Anna
Anna

Reputation: 157

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.

Upvotes: 0

Views: 392

Answers (2)

ᴇʟᴇvᴀтᴇ
ᴇʟᴇvᴀтᴇ

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

Kovacic
Kovacic

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

Related Questions