0

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%
imbasheep
  • 92
  • 3
  • 9

5 Answers5

1

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;
  }
}
Murthi
  • 5,299
  • 1
  • 10
  • 15
  • I like your css selector option: "td:last-child" It is working but there if else conditions are really low level solutions. I managed to get what I wanted. Your answer is same as @Pankaj Sharma wrote but your clean code style is low. if else statement count be changed for Assert and that's it. But I am really thankful for your css solutions. From now on I will try to use yours. – imbasheep Sep 12 '17 at 06:39
  • Is there any way to check with css selector if the tr element contains Mask and get it child which is 8% in one row? – imbasheep Sep 12 '17 at 07:44
1

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

  • I think this one wont help due to your assert takes the second element which will be "5%" in this case if I am not mistaken. In my case all elements are randomised every single time so your for loop does find the right but then I need to remember that and use it to find with another for loop which will search now in found – imbasheep Sep 07 '17 at 07:36
  • Paste this piece of code inside a function, pass first argument as 'Text inside the first column' and second as 'text to verify'. In the for loop, It will traverse the elements, If the specific element contains the text (e.g. Mask) then will continue to have that specific row and will get the third column (e.g. '8%'). P.S. I have updated the code – Pankaj Sharma Sep 07 '17 at 08:11
  • Your one is working actually fine, Thank you. It is similar to @Murthi answer but yours is more cleaner and understandable. Only thing is you can use foreach. – imbasheep Sep 12 '17 at 06:43
1

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%
Guy
  • 46,488
  • 10
  • 44
  • 88
  • xpath solutions is great, clean and simple but I really want to use css for my code. If there is something similar in css view, share it please – imbasheep Sep 12 '17 at 06:48
  • @iljuwka you can find text using `cssSelctor`, something like `"td:contains(Mask)"` if memory serves. However Selenium doesn't support using this, you will get `InvalidSelectorException`, and `cssSelector` doesn't have the equivalent of `following-sibling` anyways. – Guy Sep 12 '17 at 07:19
  • yes, I was getting every time "InvalidSelectorException" error. This is why I asked if someone will get any way to solve it. I think //xpath is best I can use – imbasheep Sep 12 '17 at 08:24
0

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);
    }
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
0

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");
}
Abhisek Mishra
  • 269
  • 3
  • 15