Trying to find object by Xpath "How to handle Web Tables"

Hi guys, I´m writting looking for help 'cause I can´t make it work a test case in where I have to click a button inside a table based on unique text, but this text is not always the same.

I had looked several videos and articles on katalon Docs and others web sites. However my problems is to find the table to work with. The developer team are using a tool (GENEXUS) that creates too much codes when compiling the app make it hard to katalon to find the right table.

This is the table:

And this is the code with several “Table/tbody”:

'Valor esperado en la tabla'
String ExpectedValue = '06022019 09:42'

WebDriver driver = DriverFactory.getWebDriver()

'Se ubica la tabla'
WebElement Table = driver.findElement(By.id('Grid1ContainerTbl'))


/*//*table[@id="MASTERDATATABLE_MPAGE"]/tbody/tr[1]/td/table/tbody/tr[5]/td/div/table/tbody/tr/td/div/div/div/table[@id="Grid1ContainerTbl"]/tbody*/

'Para ubicar filas en la tabla se captura todas las filas disponibles en un arreglo'
List<WebElement> Rows = Table.findElements(By.tagName('tr'))

println('No. de filas: ' + Rows.size())

'Se procede a buscar la coincidencia de texto para realizar una acción'

'Loop permite hacer la busqueda en todas las filas de la tabla'
table: for (int i = 0; i < Rows.size(); i++) {
'Se ubican las columnas de una fila especifica (se ubica la celda)'
List<WebElement> Cols = Rows.get(i).findElements(By.tagName('td'))
	println (Rows.get(i))

println('No. de columnas: ' + Cols.size())

println('I get here')

for (int j = 0; j < Cols.size(); j++) {
		println('I get here now')
    'Se verifica el texto esperado celda por celda'
    if (Cols.get(j).getText().equalsIgnoreCase(ExpectedValue)) {
        println('I get also here')

        'Para ubicar el ancla en la fila coincidente del valor esperado para realizar la acción'
        Cols.get(3).findElement(By.tagName('a')).click()

        break
        
        println('acción realizada')
    }
}
}

I need help to figure out how to find the table to work with.
Anyone?

That’s the table you placed a green checkmark against. You should build your xpath from there.

Your problem may also be that your table exists within an iframe:

Try switching to the frame, then locating the element(s) that you want:

WebDriver driver = DriverFactory.getWebDriver();
driver.switchTo().frame("EMBPAGE1");
WebElement table = driver.findElement(By.xpath("//table[@id='Grid1ContainerTbl']"));
2 Likes

Hi @Russ_Thomas, thank you for the answer. I tried to do what you say using:

//table[@id="Grid1ContainerTbl"]/tbody

But doesn´t work either because Katalon can´t find the table, only works (but not fine) when I use:

//table/tbody

But that’s too generic to find the right one. I also try with the whole xpath to the table:

/*//*table[@id="MASTERDATATABLE_MPAGE"]/tbody/tr[1]/td/table/tbody/tr[5]/td/div/table/tbody/tr/td/div/div/div/table[@id="Grid1ContainerTbl"]/tbody*/

without success I have to say =/

I’m a CSS guy, not an xpath guru. Shout out to @Brandon_Hein – he’ll get you up and running.

2 Likes

Thank you @Russ_Thomas!

1 Like

Did Brandon’s advice help?

Hey @Brandon_Hein that worked great!
Now Katalon can identify the table. However now the problem is work with the inside table (tr) because Katalon don´t fill the list:

List<WebElement> Rows = Table.findElements(By.tagName('tr'))

I´m working based on this example:

Handle web tables with Katalon Studio

Good to hear.

So based on your screenshot, it looks like just a syntax error. If you used, word-for-word, the example that I gave, then instead of:

List<WebElement> Rows = Table.findElements(By.tagName('tr'))

you should use:

List<WebElement> rows = table.findElements(By.tagName('tr'))

Notice that the ‘t’ in ‘table’ is lower-case. Your error is saying that it can’t find a variable named Table, because in the example I gave, the variable name is table. Generally speaking, it’s Java/Groovy convention to use camel case when declaring a variable, so try and stick to that.

Edit: I see that the example that you are using doesn’t use camel case, so that’s not your fault :unamused: Either way, don’t get into the bad habit of naming your variables with a starting upper-case character… It will cause you a lot of headaches…

1 Like

Hi @Brandon_Hein thak you for all the support. I made it work with some changes because when the for cicle found a coincidence to click, the first FOR cicle was unable to know that it have to stop, so I force it to stop into the IF sentence with this code:

i = rows.size() - 1

The final code is this one:

    'Valor esperado en la tabla'
    String ExpectedValue = '05022019 12:18'

    WebDriver driver = DriverFactory.getWebDriver()
    'Se ubica la tabla'
    driver.switchTo().frame('EMBPAGE1')

    WebElement table = driver.findElement(By.xpath('//table[@id=\'Grid1ContainerTbl\']/tbody'))

    'Para ubicar filas en la tabla se captura todas las filas disponibles en un arreglo'
    List<WebElement> rows = table.findElements(By.tagName('tr'))

    println('No. de filas: ' + rows.size())

    'Se procede a buscar la coincidencia de texto para realizar una acción'

    'Loop permite hacer la busqueda en todas las filas de la tabla'
    table: for (int i = 0; i < rows.size(); i++) {
        'Se ubican las columnas de una fila especifica (se ubica la celda)'
        List<WebElement> cols = rows.get(i).findElements(By.tagName('td'))
    	println('Conté las columnas de la fila '+i+' hay '+ cols.size()+' columnas')

    	    for (int j = 0; j < cols.size(); j++) {
    	        println('Reviso la fila '+i+' '+'Columna '+j)
    	
    	        'Se verifica el texto esperado celda por celda'
    	        if (cols.get(j).getText().equalsIgnoreCase(ExpectedValue)) {
    	            println('Lo conseguí')
    				String text = cols.get(j).getText()
    				println (j +' ' + text)
    	            'Para ubicar el ancla en la fila coincidente del valor esperado para realizar la acción'
    	            cols.get(5).findElement(By.tagName('input')).click()
    				println('acción realizada')

                    i = rows.size() - 1

                    break
    				
    	        }
    		}
    	
    	}

greetings! :grinning:

2 Likes

Hi! Yes! Now my test case works fine!
Thanks @Russ_Thomas

Hola, gracias por compartir este código, tenía un prblm similar y me sirvió de mucho :slight_smile: