1

I am learning Selenium using python and was trying to automate form filling in some website.

However, I am unable to identify any element under a frame and it gave me NoSuchElementException error. I have tried using different find_element function e.g. CSS, XPATH (pretty sure the XPATH is correct as i copied it from Firebug) and also tried to include explicit wait using WebDriverWait. However, nothing came through.

The command I have tried before:

driver.find_element_by_id("testFormNumForLastAttempt"); 
driver.find_element_by_xpath("//input[@type='text' and @name='testFormNumForLastAttempt']");

wait = WebDriverWait(driver, 10)
wait.until(EC.presence_of_element_located((By.ID, "testFormNumForLastAttempt")));

I was trying to switch to another frame

    driver.switch_to.frame("main")
        raise exception_class(message, screen, stacktrace)
    NoSuchFrameException: Message: No frame found

I have extracted the relevant HTML code below and was looking for solution to identify the testFormNumForLastAttempt input parameter.

Thanks in advance. Any help will be much appreciate.

<html>

<frameset rows="0,0,*" frameborder="no" border="0">

  <frame name="applet_container" scrolling="no" marginwidth="0" marginheight="0" noresize src="">
    <frame name="javascript_container" scrolling="no" marginwidth="0" marginheight="0" noresize src="/repoes/td-es-app517/RETJSContainer_WOC.do?__AUTHENTICATION_REQUEST_PARAMETER_MECHANISM__=applet">
      <frame name="main" scrolling="yes" noresize src="/repoes/td-es-app517/Loading.do" marginwidth="0" marginheight="0" frameborder="0">

        <html>

        <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <meta http-equiv="Cache-Control" content="no-cache">
          <meta http-equiv="Expires" content="0">
          <meta http-equiv="Pragma" content="no-cache">


          <div id="authByTestForm">
            <table width="100%" cellspacing="0" cellpadding="0" border="0">
              <tbody>
                <tr>
                  <td>Test Form No. for Last Attempt <span class="star">*</span> </td>
                  <td>
                    <input type="text" size="10" maxlength="8" name="testFormNumForLastAttempt" id="testFormNumForLastAttempt" value="" class="uppercase" autocomplete="off">

                  </td>
                </tr>
                <tr>
                  <td valign="top">Date of Birth <span class="star">*</span></td>
                  <td>
                    <table class="example_table">
                      <tbody>
                        <tr>
                          <td colspan="7">
                            <input type="text" size="4" maxlength="4" id="testFormBirthYear" name="testFormBirthYear" onkeyup="moveOnMax(this,'testFormBirthMonth')" value="" autocomplete="off"> Year

                            <input type="text" size="2" maxlength="2" id="testFormBirthMonth" name="testFormBirthMonth" onkeyup="moveOnMax(this,'testFormBirthDay')" value="" autocomplete="off"> Month

                            <input type="text" size="2" maxlength="2" id="testFormBirthDay" name="testFormBirthDay" value="" autocomplete="off"> Day

                          </td>
                        </tr>
                        <tr>
                          <td>Example:</td>
                          <td class="example_cell">1995</td>
                          <td>Year</td>
                          <td class="example_cell">09</td>
                          <td>Month</td>
                          <td class="example_cell">08</td>
                          <td>Day</td>
                        </tr>
                      </tbody>
                    </table>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>

2
  • 1
    you may have to switch to external frame, next switch to middle frame, and finally switch to inner frame - Python Selenium Webdriver - Navigating nested frame sets Commented Jun 27, 2019 at 9:58
  • 1
    Thanks. I resolved it by adding driver.switch_to.default_content(); first and followed by switching to external, middle and finally the main frame. Commented Jun 27, 2019 at 14:52

1 Answer 1

1

The <input> tag with id as testFormNumForLastAttempt seems to be nested within 3 layers of <frame>.

So to click() within the element you have to:

  • Ignore (safely) the presence of parent or child <frameset> tags.
  • Induce WebDriverWait for the first layer of frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the second layer of _frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the third layer of frame_to_be_available_and_switch_to_it().
  • Induce WebDriverWait for the desired element_to_be_clickable().
  • You can use the following solution:

    • Code Block:

      from selenium import webdriver
      from selenium.webdriver.support.ui import WebDriverWait
      from selenium.webdriver.support import expected_conditions as EC
      from selenium.webdriver.common.by import By
      
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.NAME,"applet_container")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='javascript_container'][src$='__AUTHENTICATION_REQUEST_PARAMETER_MECHANISM__=applet']")))
      WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[@name='main' and contains(@src, 'Loading')]")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#testFormNumForLastAttempt[name='testFormNumForLastAttempt']"))).click()
      

You can find a relevant discussion in How to locate and click on an element which is nested within multiple frame and frameset through Selenium using Webdriver and C#


Outro

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I resolved it by adding driver.switch_to.default_content(); first and followed by switching to external, middle and finally the main frame.

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.