Reputation: 79
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
Upvotes: 0
Views: 1188
Reputation: 5139
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("...")
Upvotes: 0
Reputation: 52665
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)
Upvotes: 1