How to select and click an element without the ID

But why it doesn’t work for me? :frowning:

We’re not creating Variables here; you need to create Test Objects for steps 1 and 2. Give this a read, then retry my guide:

https://docs.katalon.com/katalon-studio/docs/manage-test-object.html#create-a-test-object

The solutions for both of these topics are fundamentally the same (I believe that’s why you created the other topic?). This topic just has the added complexity of pagination.

I know about that…but I added the variables because I got this error:

immagine

You forgot to put the tag name in the XPath. The correct syntax is:

//a[@class='listing-read-more']

Also, not really sure how adding a variable would have fixed that problem :face_with_raised_eyebrow:

yes, you are right :stuck_out_tongue:

Now it’s working for the first link, than it goes back and I got an error again.

The error is: “WARNING: The server did not provide any stacktrace information)”.

There’s nothing else in the error log? The only problem I suspected you might have is a StaleElementReferenceException, since you are navigating away from the page, then back. This can cause the list of elements you grabbed before clicking the link to be considered “stale”. Can you give us the full error log? If it contains a “StaleElementReferenceException”, try this test code instead:

import org.openqa.selenium.WebElement

import com.kms.katalon.core.testobject.ObjectRepository
import com.kms.katalon.core.webui.common.WebUiCommonHelper
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

WebUI.openBrowser("https://www.3dprintingbusiness.directory/?s&where&company_category=bioprinting&cat=bioprinting&search_simple=Search#");

// Get a list of all pages in the pagination widget:
List<WebElement> pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("pageLink"), 30);

// Loop through each page in the pagination:
for(WebElement pageLink : pageLinks) {
	
	// Click the page link:
	pageLink.click();
	
	// Get a list of links for the current page:
	List<WebElement> searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("searchResultLink"), 30);
	
	// Loop through each result link in the page:
	for(WebElement searchResultLink : searchResultLinks) {
		
		// Click the result link:
		searchResultLink.click();
		
		// Do some validation? You haven't further specified what you're trying to do with each link...
		
		// Return to the search results page:
		WebUI.back();
		
		// To avoid StaleElementReferenceException...
		searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("searchResultLink"), 30);
	}
	
	// To avoid StaleElementReferenceException...
	pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("pageLink"), 30);
}

So, I tried you code, and error again.


Interesting because it finds the 20 elements, but than it doesn’t click the second click…

And log error is not providing any help:

immagine

“Stale element reference” means, by the time the test came to use the Test Object, it had been removed/changed in the DOM.

I haven’t been following this thread in detail since Brandon has been doing such a sterling job, perhaps he can see why this might be occurring. However, here’s a possible scenario:

Stale elements usually are caused by the page performing some kind of update “behind the scenes”, perhaps via ajax or similar. To the human eye, the page may look identical, but one or more elements (controls, etc) have been removed/destroyed and identical-looking elements used in their place – meanwhile, your test is trying to use the old element(s), which no longer exist.

“I can see the data has changed, but the controls are the same!"

Not always. Sometimes both the controls AND the data in them changes. And therein lies the problem – now you have a stale element. See?

Hope that moves you forward.

Interesting, so re-grabbing the list of elements between navigation isn’t protecting against a StaleElementReferenceException… I will need to dive into it a bit deeper :thinking: I’ll try and carve out some time today and see if I can come up with something.

Eureka! I should have seen this earlier, but the enhanced for loop:

for(WebElement searchResultLink : searchResultLinks)

will ALWAYS reference the original searchResultLinks list, even if you refresh the list with newly-located elements between page navigations:

// To avoid StaleElementReferenceException...
		searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("searchResultLink"), 30);

The solution was to use the legacy for loop for both the pagination and the result links. Try this code instead:

import org.openqa.selenium.WebElement

import com.kms.katalon.core.testobject.ObjectRepository
import com.kms.katalon.core.webui.common.WebUiCommonHelper
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

import internal.GlobalVariable

WebUI.openBrowser("www.3dprintingbusiness.directory/?s&where&company_category=bioprinting&cat=bioprinting&search_simple=Search#");

// Get a list of all pages in the pagination widget:
List<WebElement> pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("pageLink"), 30);

// Loop through each page in the pagination:
for(int i = 0; i < pageLinks.size(); i++) {
	WebElement pageLink = pageLinks.get(i);
	
	// Click the page link:
	pageLink.click();
	
	// Get a list of links for the current page:
	List<WebElement> searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("searchResultLink"), 30);
	
	// Loop through each result link in the page:
	for(int j = 0; j < searchResultLinks.size(); j++) {
		WebElement searchResultLink = searchResultLinks.get(j);
		
		// Click the result link:
		searchResultLink.click();
		
		// Do some validation? You haven't further specified what you're trying to do with each link...
		
		// Return to the search results page:
		WebUI.back();
		
		// To avoid StaleElementReferenceException...
		searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("searchResultLink"), 30);
	}
	
	// To avoid StaleElementReferenceException...
	pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject("pageLink"), 30);
}
2 Likes

Hi,

thanks for the code. Unfortunately, it doesn’t work for me…I don’t know why.

The error is:

Test Cases/3D FAILED because (of) (Stack trace: groovy.lang.MissingPropertyException: No such property: pageLinks for class: Script1547632760446
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:53)
at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:52)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:307)

I don’t know…it doesn’t do anything.

Thanks

Post your script as well.

It looks like there’s a syntax error somewhere around the pageLinks variable declaration. As @Mate_Mrse said, share your script so we can see what went wrong.

Ok:

import static com.kms.katalon.core.checkpoint.CheckpointFactory.findCheckpoint
import static com.kms.katalon.core.testcase.TestCaseFactory.findTestCase
import static com.kms.katalon.core.testdata.TestDataFactory.findTestData
import static com.kms.katalon.core.testobject.ObjectRepository.findTestObject
import com.kms.katalon.core.checkpoint.Checkpoint as Checkpoint
import com.kms.katalon.core.cucumber.keyword.CucumberBuiltinKeywords as CucumberKW
import com.kms.katalon.core.mobile.keyword.MobileBuiltInKeywords as Mobile
import com.kms.katalon.core.model.FailureHandling as FailureHandling
import com.kms.katalon.core.testcase.TestCase as TestCase
import com.kms.katalon.core.testdata.TestData as TestData
import com.kms.katalon.core.testobject.TestObject as TestObject
import com.kms.katalon.core.webservice.keyword.WSBuiltInKeywords as WS
import internal.GlobalVariable as GlobalVariable
import org.openqa.selenium.Keys as Keys
import org.openqa.selenium.WebElement
import com.kms.katalon.core.testobject.ObjectRepository
import com.kms.katalon.core.webui.common.WebUiCommonHelper
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI
import internal.GlobalVariable

WebUI.openBrowser(“www.3dprintingbusiness.directory/?s&where&company_category=bioprinting&cat=bioprinting&search_simple=Search#”);

WebUI.scrollToPosition(0, 1000)

if(WebUI.click(findTestObject(‘Object Repository/3D/Page_3D London 3D Printing 3D Prin/a__snp-close snp_nothanks’), FailureHandling.OPTIONAL))

if(WebUI.click(findTestObject(‘Object Repository/3D/Page_You searched for 3D Printing/a_I decline’), FailureHandling.OPTIONAL))
WebUI.scrollToPosition(0, 1000)

if(WebUI.click(findTestObject(‘Object Repository/3D/Page_You searched for 3D Printing/a_I decline’), FailureHandling.OPTIONAL))
// Get a list of all pages in the pagination widget:
List pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject(‘Object Repository/3D/pageLink’), 10);

// Loop through each page in the pagination:
for(int i = 0; i < pageLinks.size(); i++) {
WebElement pageLink = pageLinks.get(i);

// Click the page link:
pageLink.click();

// Get a list of links for the current page:
List searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject(‘Object Repository/3D/searchResultLink’), 10);

// Loop through each result link in the page:
for(int j = 0; j < searchResultLinks.size(); j++) {
WebElement searchResultLink = searchResultLinks.get(j);

  // Click the result link:
  searchResultLink.click();
  
  // Do some validation? You haven't further specified what you're trying to do with each link...
  
  // Return to the search results page:
  WebUI.back();
  
  // To avoid StaleElementReferenceException...
  searchResultLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject('Object Repository/3D/searchResultLink'), 10);

}

// To avoid StaleElementReferenceException…
pageLinks = WebUiCommonHelper.findWebElements(ObjectRepository.findTestObject(‘Object Repository/3D/pageLink’), 30);
}

Its the same code…