-1

I am trying to select the frame 'mainFrame'.

The page source is :

<frameset rows="89,*" frameborder="NO" border="0" framespacing="0">
    <frame name="topFrame" scrolling="NO" noresize src="inc-webpage/b-topnav.asp">
        <frameset rows="*,20" frameborder="NO" border="0" framespacing="0">
            <frameset cols="175,*" frameborder="NO" border="0" framespacing="0">
                <frame name="leftFrame" scrolling="AUTO" noresize src="inc-webpage/b-sidenav-3.asp">
                <frame name="mainFrame" src="b-default.asp">
            </frameset>
            <frame name="bottomFrame" scrolling="NO" noresize src="inc-webpage/b-footer.asp">
        </frameset>
</frameset>
<noframes>

The element I wish to select is in 'mainFrame'. Therefore my code is:

time.sleep(5)    
driver.switch_to.frame("mainFrame");
driver.find_element_by_xpath("//a[contains(text(),'I Agree')]").click()

Yes. time.sleep() is not ideal so I'm just using it for the time being.

Here is the HTML for the element I wish to select within 'mainFrame':

<input type="button" value="I Agree" 
class="btn" onmouseover="blueBtnOver(this)" onmouseout="blueBtnOut(this)" 
onclick="javascript:location.href='b-3c-pLessonBooking.asp?limit=pl'" style="background: rgb(0, 102, 204);">

Currently getting this Error:

NoSuchFrameException(frame_reference) selenium.common.exceptions.NoSuchFrameException: Message: mainFrame

I am an absolute beginner. The driver.find_element_by_xpath is probably wrong

Also why do some websites use frames//framesets while others use iframes and some don't use either?

JeffC
  • 22,180
  • 5
  • 32
  • 55
  • Button `I Agree` is not inside the frame you have posted. You need to check in DOM and parent of that button if there any frame?? it should be like `#document button element` – KunduK Mar 25 '21 at 17:05

2 Answers2

0

Basically wait for the frame switch to it and then click the input with matching value I agree.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC

WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("mainFrame"))
driver.find_element_by_xpath("//input[@value='I Agree']").click()
Arundeep Chohan
  • 9,779
  • 5
  • 15
  • 32
-1

The desired element is nested within multiple <frame> elements so you have to:

  • Induce WebDriverWait for the parent frame to be available and switch to it.

  • Induce WebDriverWait for the child frame to be available and switch to it.

  • Induce WebDriverWait for the desired element to be clickable.

  • You can use either of the following Locator Strategies:

    • Using CSS_SELECTOR:

      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='topFrame']")))
      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"frame[name='mainFrame']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.btn[value='I Agree']"))).click()
      
    • Using XPATH:

      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[@name='topFrame']")))
      WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[@name='mainFrame']")))
      WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@class='btn' and @value='I Agree']"))).click()
      
  • Note : You have to add the following imports :

     from selenium.webdriver.support.ui import WebDriverWait
     from selenium.webdriver.common.by import By
     from selenium.webdriver.support import expected_conditions as EC
    

Reference

You can find a couple of relevant discussions in:

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352