Taking element with css selector with multiple elements in a table

5.3k views Asked by At

I am using Selenide/Selenium to write my java automation scripts and recently I faced a problem. I want to take an element from the same row I compare my second element. Html example code:

<tr ng-repeat="testing" class="ng-scope" style="">
    <td class="ng-binding">Style</td>
    <td ng-if="testing2" class="ng-binding ng-scope">1</td>
    <td class="ng-binding">5%</td>
</tr>
<tr ng-repeat="testing" class="ng-scope" style="">
    <td class="ng-binding">Mask</td>
    <td ng-if="testing2" class="ng-binding ng-scope">2</td>
    <td class="ng-binding">8%</td>
</tr>
...

Let's imagine there will be much more of those. And the most important one is that these can be randomised. every single time. They depend on last page what I select and how.

So basically I want to search for testing and that it has 8%.

What I tried but I don't know what to do with it. It stores all elements in list. Bu I get css selector with Chrome driver info before it. I can take it off but I think there is much better solutions:

List<WebElement> list = getWebDriver().findElements(By.cssSelector("[ng-
repeat='hyvitisLiik in vm.taotluseHyvitised'] > [class='ng-binding']"));
for(int i = 0; i < list.size(); i++){
  logger.info(list.get(1));
}

I also tried to get an element with this code:

int counter = $$(By.cssSelector("tr > [class='ng-binding']")).size();
for (int i = 0; i < counter; i++) {
SelenideElement word= $$(By.cssSelector(lokaator)).get(counter);
word.getText();
}

This code takes the "Mask" and a "8%" elements. But what I really want is test if the getText given value is "Mask", take the percent value and compare it. For example: search in web for the word "Mask", take the percent value (in that case it is 8%) and validate with assert that it is exactly 8%.

Is there any way to set CSS selector with index, like

tr[1] > [class='ng-binding']

which will select for the second tr class? any other advice to find I want?

EDIT: Is it possible to get the element with css selector using only one row as showed with xpath option in answer what wrote @Guy:

WebElementelement=getWebDriver().findElement(By.xpath("//td[text()='Mask']/followingsibling::td[2]"));
element.getText(); // 8%
5

There are 5 answers

3
Guy On BEST ANSWER

You can use xpath to locate the element using the Mask text

WebElement element = getWebDriver().findElement(By.xpath("//td[text()='Mask']/following-sibling::td[2]"));
element.getText(); // 8%
1
undetected Selenium On

As you want to search in web for the word "Mask", take the percent value (in that case it is 8%) and validate with assert that it is exactly 8%, you can create a function which will take 2 string type of arguments i.e. the text Mask and the text 8%. From the main() or test() class call the function providing the parameters. In the called function, we can retrieve the text and Assert the percentage easily. Your code will be looking like:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;

public class Q46088968_validate_score 
{
    static WebDriver driver;
    public static void main(String[] args) 
    {
        System.setProperty("webdriver.chrome.driver", "C:\\Utility\\BrowserDrivers\\chromedriver.exe");
        driver = new ChromeDriver();
        driver.get("https://www.gmail.com");
        //other actions
        validate_score("Mask", "8%");
        driver.quit();
    }

    public static void validate_score(String my_text, String expected_percentage)
    {
        String actual_percentage = driver.findElement(By.xpath("//td[.='" + my_text + "']//following::td[2]")).getText();
        Assert.assertEquals(actual_percentage, expected_percentage);
    }
}
1
Abhisek Mishra On

Try this

List<WebElement> elements = getWebDriver().findElements(By.xpath("//td[text()='Mask']/../td[3]"));

    int pass = 0;
    for(WebElement e | elements) {
       if(!(e.getText().equals("8%"))) {
          pass = 1
       }
    }

    if(pass == 0) {
System.out.println("Pass");
} 
else {
System.out.println("Fail");
}
2
Murthi On

You can try with following css selector, it may helps you.

table>tr:nth-child(2)>td ---- To get the first td element of second row

table>tr:nth-child(2)>td:nth-child(3) --- To get last td element of second row

In Java,

List<WebElemet> lstRows=getWebDriver().findElements(By.cssSelector("table>tr[ng-repeat='testing']");

for(WebElement row:lstRows){
   if(row.findElement(By.cssSelector("td")).getText().equals("Mask")){
  {
  String percentage= row.findElement(By.cssSelector("td:last-child")).getText();
   if(percentage.equals("8%")
     System.out.println("pass");
   else
     System.out.println("fail");
  break;
  }
}
3
Pankaj Sharma On

Using CSS and Java, we can perform it as:

List<WebElement> elements = getWebDriver().findElements(By.cssSelector("tr[ng-repeat='testing']"));
    for(int i = 0; i < elements.size(); i++) {
        if(elements.get(i).findElement(By.cssSelector("td")).getText().contains("Mask")) {
            //assert elements.get(i).findElements(By.cssSelector("td")).get(2).getText() equals 8%
    }
}

Alternatively, If you use xpath, you can achieve it by comparing the text of '//tr[@ng-repeat='testing']/td[contains(text(),'Mask')]/../td[3]' locator