0

I'm trying to click on each item in a span using Selenium. Is it possible to specify this in a for loop and how could I do this?

This is how I currently click on the first span item:

 _open_actieve_polis = {"by": By.CSS_SELECTOR, "value": "td:nth-child(2)"}

self._click(self._open_actieve_polis)

in the base page this is how i implemented the _click method.

def _find(self, locator):
    return self.driver.find_element(locator["by"], locator["value"])

 def _click(self, locator):
        self._find(locator).click()

these are the other span items I want to click:

tbody > tr:nth-child(2) > td:nth-child(2) > span > a
tbody > tr:nth-child(3) > td:nth-child(2) > span > a
tbody > tr:nth-child(4) > td:nth-child(2) > span > a
tbody > tr:nth-child(5) > td:nth-child(2) > span > a
tbody > tr:nth-child(6) > td:nth-child(2) > span > a

This is what I tried after applying feedback:

This in a method:

for link in self._open_actieve_polis:
        self._click_all(link)
        self.driver.back()

I declared the locator in an attribute:

_open_actieve_polis = ({"by": By.CSS_SELECTOR, "value": "td:nth-child(2)"})

the following in base page:

 def _find_all(self, locator):
        return self.driver.find_elements(locator["by"], locator["value"])

    def _click_all(self, locator):
        self._find_all(locator).click()

is currently resulting in:

     line 18, in _find_all
    return self.driver.find_elements(locator["by"], locator["value"])
TypeError: string indices must be integers
4
  • Show your implementation of _click() method Commented Feb 9, 2018 at 10:29
  • i edited the original post. Commented Feb 9, 2018 at 10:49
  • Can you please share more html code for link Commented Feb 9, 2018 at 10:52
  • Can you provide the stacktrace for the error? Commented Feb 9, 2018 at 13:33

2 Answers 2

1

You need to implement another method. Something like

def _find_all(self, locator):
    return self.driver.find_elements(locator["by"], locator["value"])

that intend to return you list of elements instead of single element...

With this method you can try to get list of links

self.links = self._find_all({"by": By.CSS_SELECTOR, "value": "tbody > tr > td:nth-child(2) > span > a"})

and loop through it with this

for link in self.links:
    link.click()

or add new method to click each element in list:

def _click_all(self, locator):
    [element.click() for element in self._find_all(locator)]

and call it as

self._click_all({"by": By.CSS_SELECTOR, "value": "tbody > tr > td:nth-child(2) > span > a"})

Note that to get list of links for each table row you should remove tr index from you selector:

tr:nth-child(2) > td:nth-child(2)  -->  tr > td:nth-child(2)
Sign up to request clarification or add additional context in comments.

14 Comments

I feel like I'm almost there But I'm receiving a type error. I edited my original post. Am I interpreting wrongly?
It seem that you're trying to pass locator variable as string, but not dictionary and so locator["by"] gives you TypeError
now i'm getting AttributeError: 'list' object has no attribute 'click'. my head is spinning been looking at it all day.
On which line you got it?
How your locator looks like? Is it string or dict?
|
0

Selenium's find_elements() method (as well as its find_elements_by_*() methods, all return a simple list of elements. Lists don't have a click() method.

Instead, you'll need to iterate over the elements, clicking each one in turn.

elements = driver.find_elements(By.CSS, "...")
for element in elements:
    element.click()

Note: Selenium has a find_elements_by_css_selector() method that you can use instead of find_elements():

elements = driver.find_elements_by_css_selector("...")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.