3

I'm attempting to use Selenium WebDriver to select a link named cslLogin on a web page. It's located in a child frame called topframe but I can't access it, even after I switch to its parent frame TopLevelFrame which I can do successfully. The html page has this basic layout:

<html>
 <head>...</head>
  <frameset name="ATopLevelFrameSet">
   <frame name="TopLevelFrame">
    #document
     <html>
      <head></head>
       <frameset name="Aframeset">
        <frame name="topframe">
         #document
          <html>
           <head>...</head>
           <body class="clsBgColor">
            <table id="tblTitle">
             <tbody>
              <tr class="clsBackYellow"">
               <td class="clsDeviceStatusLink">
                <a class="clsLogin" href="javascript:void(0);"
                onclick="javascript:fnnLoginClick();">Login</a> == $0
               etc...

I can successfully switch to TopLevelFrame using self.driver.switch_to.frame("TopLevelFrame") but I cannot then access topframe or clsLogin (I get NoSuchFrameException and NoSuchElementException, respectively)

I've tried find_element_by_name, find_element_by_xpath, find_element_by_link_text, find_element_by_css_selector, and have also used

try:
    element = WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((By.NAME, "TopLevelFrame"))
            )
finally:
    self.driver.quit()

in case it was a time/page loading issue, but it times out long after the page loads.

I know from other posts that I need to switch to the nearest frame first before I can access the element, but of course this isn't working. Any suggestions? Thanks in advance.

1
  • Post the full code, not just names of methods. Read through minimal reproducible example guide. Commented Feb 20, 2018 at 23:41

3 Answers 3

1

To click the link cslLogin first you have to switch to the TopLevelFrame <frame> then to topframe <frame> and then click on the link as follows :

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"TopLevelFrame"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.NAME,"topframe"))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.LINK_TEXT, "Login"))).click()
# Or
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//tr[@class='clsBackYellow']/td[@class='clsDeviceStatusLink']/a[@class='clsLogin']"))).click()
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I had tried waits for a few frames/elements, but it turns out I needed the waits for everything.
0

You should use "find_element_by_xpath" Just open the website, press "ctrl+shift+c" and inspect it what do you want to extract. Find the row in elements, right click and copy xpath, paste in function.

For instance, consider this page source:

<html>
 <body>
  <form id="loginForm">
   <input name="username" type="text" />
   <input name="password" type="password" />
   <input name="continue" type="submit" value="Login" />
   <input name="continue" type="button" value="Clear" />
  </form>
</body>
<html>

The form elements can be located like this:

login_form = driver.find_element_by_xpath("/html/body/form[1]")
login_form = driver.find_element_by_xpath("//form[1]")
login_form = driver.find_element_by_xpath("//form[@id='loginForm']")

For more information, check out http://selenium-python.readthedocs.io/locating-elements.html

1 Comment

It still doesn't seem to be working. Here is an example of the code I last ran: top_level_frame = self.driver.find_element_by_xpath('/html/frameset/frame') self.driver.switch_to.frame(top_level_frame) top_frame = self.driver.find_element_by_xpath('/html/frameset/frame[1]') self.driver.switch_to.frame(top_frame) element = self.driver.find_element_by_xpath('//*[@id="tblTitle"]/tbody/tr[1]/td[3]/a') I still receive a NoSuchElementFound exception when finding topframe. It switched to TopLevelFrame perfectly fine.
0

Try this, since you have nested iframes, switch to TopLevelFrame and then switch to topframe and carry out your find_element_* calls

driver.switch_to.frame(driver.find_element_by_name('TopLevelFrame'))
driver.switch_to.frame(driver.find_element_by_name('topframe'))
driver.find_element_by_class_name('clsLogin').click()

let me know if this works

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.