How to handle dynamic table?


#1

When I am refreshing the page the column number 14 has several rows so rows gets interchanged. If I want to click the column 16 where column14 has “D” option. How to handle it?


#2

I can recommend a couple of ways to handle this:

1.) Does your table have a “search” function? If so, then you can sometimes search the table in such a way as to narrow down the results to 1 row (your target row), then just click the 16th column of that row.

2.) You can implement a for loop to check each row until it finds the correct text in the correct cell. Something like:

// Get a list of all rows:
List<WebElement> rows = WebUiCommonHelper.findWebElements(findTestObject('path/to/rows/object'))

// Iterate rows:
for(WebElement row : rows) {

    // Get the text from the cell at the 14th column:
    String text = row.findElement(By.xpath('.//td[14]')).getText()

    // If text == 'D', click the cell at the 16th column:
    if(text.equals("D")) {
        row.findElement(By.xpath('.//td[16]')).click()
    }

}

Hopefully that gives you some ideas :slight_smile: Cheers!


#3

I am having a problem printing some text when the table is not present. Please see the following code and suggest what I need to change:

int numcolumns
String columns

WebUI.callTestCase(findTestCase('Smoke Testing/Login'), [:], FailureHandling.STOP_ON_FAILURE)

WebUI.click(findTestObject('Master Object Repository/B2B - My_CES Dropdown/My CES - B2B'))

WebUI.click(findTestObject('Master Object Repository/B2B - My_CES Dropdown/Favorites - B2B'))

// since the table needs to be located first, it should check for its existence
Boolean favtable = CustomKeywords.'com.ces.cesonline.favorites.FavoritesKeywords.locateTable'()

numcolumns = CustomKeywords.'com.ces.cesonline.favorites.FavoritesKeywords.allHeadersFavorites'()

columns = CustomKeywords.'com.ces.cesonline.favorites.FavoritesKeywords.columnNames'()

	
	if (favtable == true){
	 
		println ('No. of Columns: ' + numcolumns)
		
		println ('Names of the columns are: ' + columns)
				
	}
	else
		println('Favorites is empty!')
		
			
WebUI.closeBrowser()

This is what I have in the Keywords:

class FavoritesKeywords {

	@Keyword
	def locateTable(){

		// creating a variable 'driver' and assigning its value
		WebDriver driver = DriverFactory.getWebDriver()
		'To locate table'
		WebElement Table = driver.findElement(By.xpath("//table[@class='cart']"))

	}

When I run it, I get:

no such element: Unable to locate element: {“method”:“xpath”,“selector”:"//table[@class=‘cart’]"}

Thanks


#4

Hi Brandon,

Thanks for the reply.

I wanted to know Is there any way we can stop the Loop, the movement we find D and click on Actions.
I have use this script and I am able to print all the rows of that particular column Doms/Int
But I want to stop the loop in between the movement D shows the first time in the row? Is there any way to do it?

WebDriver wd = DriverFactory.getWebDriver()
// Grab the table
WebElement table = wd.findElement(By.xpath("//*[@id=‘row’]"));

List allRows = table.findElements(By.xpath("//*[@id=‘row’]/tbody/tr/td[16]"));
for (WebElement row : allRows) {
System.out.println(row.getText());

}


#5

Sure, with a break statement:

WebDriver wd = DriverFactory.getWebDriver()
// Grab the table
WebElement table = wd.findElement(By.xpath("//*[@id=‘row’]"));

List allRows = table.findElements(By.xpath("//*[@id=‘row’]/tbody/tr/td[16]"));
for (WebElement row : allRows) {
    String text = row.getText()
    System.out.println(text);
    if(text.equals("D")) {
        break
    }
}

#6

Hi Brandon,

The loop gets terminate the movement D appears, but I want to click the Action button on the last column pertaining to same row where D appears.

How to make the action column xpath dynamic so that the movement D appears it should click the Action item.
I have highlighted the action item.
The current xpath of the action item is coming as :
xpath=//*[@id=“row”]/tbody/tr[3]/td[21]/a/img

And where to apply this clickable item after break from the above code or after it?

Regards,
RAgrawal


#7

You would apply before the break:

if(text.equals("D")) {
    row.findElement(By.xpath(“./td[21]/a/img”)).click()
    break
}

#8

Hi Brandon,

Thanks for the wonderful help.

I have one more question that my one screen sometimes appears and sometimes does not because if I have duplicate orders in system then only it shows up otherwise not. I have to perform click option when that screen appears otherwise not, I have put in try block so what is happening when it didn’t search for try block my end result gets failed. I want to keep my try block optional when that screen appears then only click otherwise move to finally block. or any other way I can put that statement?

Currently I am putting that in try block and what you see in finally block we want those statement to execute always. and this another screen it will always appears.
How to handle this?

Here is the script…
try {
WebUI.verifyElementPresent(findTestObject(‘Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor’),
10)

WebUI.click(findTestObject('Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor'))

}
finally {
WebUI.click(findTestObject(‘Object Repository/Testcases3/Page_BWB - Review Sales Order - (aviationreviewFuelOrder)/button_Book the SO’))

successmsg = WebUI.getText(findTestObject('Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/li_The Sales Order 27047986 was booked successfully'))

WebUI.comment(successmsg)

WebUI.takeScreenshot()

}


#9

Since you are using the WebUI.verifyElementPresent() method, I would just do a traditional if statement. This would be much simpler and cleaner:

if(WebUI.verifyElementPresent(findTestObject(‘Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor’),
10)) {
    WebUI.click(findTestObject('Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor'))
}

WebUI.click(findTestObject(‘Object Repository/Testcases3/Page_BWB - Review Sales Order - (aviationreviewFuelOrder)/button_Book the SO’))
successmsg = WebUI.getText(findTestObject('Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/li_The Sales Order 27047986 was booked successfully'))
WebUI.comment(successmsg)
WebUI.takeScreenshot()

#10

Hi Brandon,

When I am using If statement then what’s happening here is - Wen the duplicate order are there if statement is working fine, because it can see that button appears but when the duplicate orders screen doesn’t come then my test case gets stuck at if statement test step and the test case gets failed because it doesn’t find that button on the screen.

Can you please guide me how to handle this.


#11

In your verifyElementPresent() method, provide a failure handling argument:

if(WebUI.verifyElementPresent(findTestObject(‘Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor’),
10, FailureHandling.CONTINUE_ON_FAILURE)) {
    WebUI.click(findTestObject('Object Repository/Testcases3/Page_BWB - Query Open Sales Order - (aviationbillingQuery)/Duplicate-aviation-Supervisor'))
}

This will still cause the script to “hang” for 10 seconds if the button is not present, but it will not fail the test. You can reduce the hang time by reducing the timeout argument.


#12

Hi Brandon,

When I am providing failure handling argument it is successfully going to next step, but end result is getting failed. Do you have any idea where my entire test case gets passed if the IF Statement test step works or not.
I mean that Duplicate button screen appears or not?

I am getting this error because this time there was no Duplicate button screen appears.
But the entire test case got failed due to one step.

I am sending you the screenshot .


#13

Hmmm instead of:

FailureHandling.CONTINUE_ON_FAILURE

try:

FailureHandling.OPTIONAL

I believe this will allow the test to continue, but just give a warning instead of failing that step. I don’t use the WebUI API at all (I use Selenium to do all of this stuff instead), so I apologize that I couldn’t provide a solution more quickly.

Give this a try, I think it will work.


#14

Hi Brandon, When you gave me the code.
if(text.equals (“D”)){
row.findElement(By.xpath("//td[21]a/img")).click()
break.
}

This is not working on D it is randomly clicking on Either I or D.
Can you please help me out ?


#15

Hi Brandon,

This is new thing where I got stuck.

When it is clicking the Action item D there is another element which is coming Waitng for Review in the action Item I have highlighted it. I don’t want it should click on that “Waiting for Review” but want the loop to move go further such for another D and then click the action item.Waiting for Review action item has Pop up also. If you see my code you will find it.It is just accepting the alert if that item is clicked.
I have written this code kindly guide me.

// Grab the table
WebDriver wd = DriverFactory.getWebDriver()

WebElement table = wd.findElement(By.xpath(’//*[@id=‘row’]’))

//String value = “D”
List allRows1 = table.findElements(By.xpath(’//*[@id=‘row’]/tbody/tr/td[16]’))

List allRows2 = table.findElements(By.xpath(’//*[@id=‘row’]/tbody/tr/td[21]’))

for (WebElement row : allRows1) {
for (WebElement cols : allRows2) {
String text = row.getText()

    String title = cols.getAttribute('Waiting for review')

    System.out.println(text)

    if (text.equals('D') && !(title.toString().equalsIgnoreCase('Waiting for review'))) {
		if (WebUI.verifyAlertPresent(0, FailureHandling.OPTIONAL)) {
			WebUI.acceptAlert()}
        
        row.findElement(By.xpath('//td[21]/a/img')).click()

        break
    }
}

}