0

I want to write a method that can help me locate an element on a webpage that contains multiple iframes. Currently, I have to manually search through these iframes every time I need to find a specific element. I want to automate this process so that I only need to know the name of the element I am looking for.

I have written a method to accomplish this

def find_elem(self, xpath):
    try:
        sleep(2)
        # Try to find the element using the given XPath
        element = self.driver.find_element(By.XPATH, xpath)
        return element
    except  (NoSuchElementException, InvalidSelectorException) as e:
        # If the element is not found, search for it recursively in all iframes on the page
        element = None
        sleep(2)
        iframes = self.driver.find_element(By.XPATH, "//iframe") 
        for iframe in iframes:
            try:
                self.driver.switch_to.frame(iframe)
                element = self.find_elem(xpath)
                if element is not None:
                    break
            except NoSuchElementException:
                pass
            finally:
                self.driver.switch_to.default_content()
        # If the element is not found after searching all iframes, raise an exception
        if element is None:
            raise NoSuchElementException("Element not found: " + xpath)
        return element
...
self.driver.switch_to.default_content()
found_elem = self.find_elem('//span[@id="gotItButton"]')
found_elem.send_keys(Keys.TAB) # execute some action on the element

but it is crashing with an error: pydevd warning getting attribute webelement.screenshot_as_base64 was slow

Can anyone help me figure out how to locate an element when I do not know exactly which frame it is in? (I mean to help write a method using python)

P.S. I have also tried using the DevTools -> Recorder tool in Google Chrome, but it does not work with frames. An error occurred while attempting to interact with the element: 'waiting for target failed, timeout of 5000ms exceeded'.

Oleksandr Myronchuk
  • 155
  • 1
  • 2
  • 10

1 Answers1

0
def find_elem(self, xpath):
    sleep(1)
    iframes = self.driver.find_elements(By.TAG_NAME,'iframe')
    if iframes:
        for iframe in iframes:
            sleep(1)
            try:
                self.driver.switch_to.frame(iframe)
            except:
                continue

            try:
                elem = WebDriverWait(self.driver, 1).until(EC.presence_of_element_located((By.XPATH, xpath)))
                if elem is not None:
                    return elem, iframe
            except:
                ''

            elem, tempF = self.find_elem(xpath)
            if elem is not None:
                #self.driver.switch_to.default_content()
                return elem, tempF
            sleep(1)
            self.driver.switch_to.default_content()
    try:
        elem = WebDriverWait(self.driver, 1).until(EC.presence_of_element_located((By.XPATH, xpath)))
        return elem, None
    except:
        return None, None

...

elem, iframe = self.find_elem("//*[@id='nextTipButton']/span") 
elem.click() 
Oleksandr Myronchuk
  • 155
  • 1
  • 2
  • 10