Looping through and clicking all links contained within a div

I need to loop through and click all buttons contained within a particular div element.
I’m wondering how best to do this?

We don’t know how many links will be contained within the div, it could vary, which is why I need to loop through.

Any help would be much appreciated.

1.) Create a Test Object that identifies all links within the div. Without seeing the HTML you are working with, you could do it with an XPath that looks something like:

//div[@id='myDiv']//a

2.) Your test code would look something like:

List<WebElement> links = WebUiCommonHelper.findWebElements(findTestObject('path/to/my/object'), 30);
for(WebElement link : links) {
    link.click();
}
3 Likes

That was a super-fast reply, thanks!

Another thing I wanted to try was to be able to verify that numbers in a table column add up to a certain number. I’ll try this out myself, but if I need help I’ll ask for it here in another question.

Thanks again.

Hello again,
Unfortunately, I’m getting the following error:-

FAILED.
Reason:
org.openqa.selenium.StaleElementReferenceException: 
stale element reference: element is not attached to the page document

The code so far is as follows:-

WebUI.openBrowser('')
WebUI.navigateToUrl('https://www.google.com/')
WebUI.setText(findTestObject('Page_Google/input_Sign in_q'), 'Spider-Man')
WebUI.sendKeys(findTestObject('Page_Google/input_Sign in_q'), Keys.chord(Keys.ENTER))
WebUI.delay(2)
title = WebUI.getWindowTitle()
WebUI.verifyMatch(title, 'Spider-Man - Google Search', true)

List<WebElement> links = 
WebUiCommonHelper.findWebElements(findTestObject('Google_Search/div_header_links'), 
    10)

for(WebElement link : links) {
	link.click();
	WebUI.delay(2)
 }

I’ve defined div_header_links as:-

//div[@id='hdtb-msb-vis']//a

Makes sense, as the link is most likely redirecting you, the DOM is changed/wiped out completely, and the list of links becomes “stale”. You will probably need to re-locate the links after each click:

List<WebElement> links = 
WebUiCommonHelper.findWebElements(findTestObject('Google_Search/div_header_links'), 
    10)

for(WebElement link : links) {
	link.click();
	WebUI.delay(2)
    links = WebUiCommonHelper.findWebElements(findTestObject('Google_Search/div_header_links'), 10)
 }

Unfortunately, even by doing the above, I’m still getting that ‘StaleElementReferenceException’. I suspect it could be something to do with the test object I’m using? The first link gets clicked, after which that exception occurs.

I might have to give up and just let someone else have a go.
By seeing their solution, I might learn more about how all this works.

All I’m trying to do is to click on the first 4 top links on a google search page (e.g. Images, Videos, News etc). But I wanted to do it by looping through their parent div and clicking on each link (whatever they may be), rather than hard coding their individual link paths.

The page can be seen here:-
https://www.google.co.uk/search?source=hp&ei=0NZ6XMSlLsqclwT42Qw&q=Spider-Man

Thanks,

Thanks for linking the page you are working with. FFR, if you are able to link to the AUT, do so in your original post (or, at the very least, provide an HTML snapshot). It will improve your turnaround time. This solution works:

Use this xpath:

//div[@role=‘tab’ and @aria-selected=‘true’]/following-sibling::div/a

List<WebElement> links = WebUiCommonHelper.findWebElements(findTestObject('New Test Object'), 10);

while(links.size() > 0) {
	links.get(0).click();
	WebUI.delay(2);
	links = WebUiCommonHelper.findWebElements(findTestObject('New Test Object'), 10);
}

Your problem was that when a link is clicked, it disappears from the DOM, which causes the StaleElementReferenceException.

1 Like

I Have the similar issue. I want to click on the first table row and perform action on the row .Once the action is performed the row will be disappeared. Want to perform the same actions on all the rows until table is empty. below is the code. I am stuck.

def approvetasks(List tasks, String Name,int a){
for (int i =0; i<tasks.size();i++) {
WebUI.click(findTestObject(//a[text()=“‘+tasks[i]+’”]//parent::p//parent::div//parent::td//parent::tr//td[10]/div/p/a)[‘+a+’]', true))
WebUI.delay(5)

		// clicking on 2nd link 
		WebUI.click((findTestObject('//a[text()="'+Activetasks[i]+'"]', true))

First thing, there is no click method that takes a second parameter as boolean.
Second thing, if you want to use parameterization as you have it above, you should create a TestObject in your Object Repository and put in a Value of xpath with a Name of ${index} (see how they do it in the link)
Third thing, what is the [‘+a+’]' supposed to be??? You need to verify your pathway before you try to parameterize it.

Another way you could perhaps do this

import org.openqa.selenium.WebDriver as WebDriver
import org.openqa.selenium.WebElement as WebElement
import com.kms.katalon.core.webui.driver.DriverFactory as DriverFactory
import com.kms.katalon.core.webui.keyword.WebUiBuiltInKeywords as WebUI

WebDriver driver = DriverFactory.getWebDriver();

for (int i = 0; i < tasks.size(); i++) {
    myItem = driver.findElement(By.xpath("//a[text()='${tasks[i]}']//parent::p//parent::div//parent::td//parent::tr//td[10]/div/p/a)"));
    myItem.click();
    WebUI.delay(5)
}

Thanks for answering.
1.If I click on my first table row and perform actions, the row will disappear and the second row becomes the first row and follows.
2.[+a+] is another interactive column in the row.