IFramesとフレームの操作

フレームは、現在では非推奨となっている、同一ドメイン上の複数のドキュメントからサイトレイアウトを構築する手段です。HTML5 より前のウェブアプリを操作する場合を除き、フレームを操作することはほとんどないでしょう。IFrame は、完全に異なるドメインからのドキュメントの挿入を可能にし、現在でも一般的に使用されています。

フレームまたは iframe を操作する必要がある場合、WebDriver は同じ方法で操作できます。iframe 内のボタンを考えてみましょう。ブラウザの開発ツールを使用して要素を検査すると、次のようになるかもしれません。

<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>

iframe がなければ、次のようなものを使用してボタンをクリックすることを期待するでしょう。

コードを移動

//This won't work
driver.findElement(By.tagName("button")).click();
  
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
    # This won't work
driver.find_element(:tag_name,'button').click
  
// This won't work
await driver.findElement(By.css('button')).click();
  
//This won't work
driver.findElement(By.tagName("button")).click()
  

ただし、iframe の外にボタンがない場合、「no such element」エラーが発生する可能性があります。これは、Selenium がトップレベルドキュメント内の要素のみを認識しているために発生します。ボタンを操作するには、ウィンドウを切り替えるのと同様の方法で、最初にフレームに切り替える必要があります。WebDriver は、フレームへの切り替えに 3 つの方法を提供しています。次のコード例は、ライブウェブの例を使用して、その方法を示しています。

WebElement の使用

WebElement を使用した切り替えは、最も柔軟なオプションです。お好みのセレクタを使用してフレームを見つけ、それに切り替えることができます。

コードを移動

         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE= driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
    # Store iframe web element
iframe = driver.find_element(By.CSS_SELECTOR, "#modal > iframe")

    # switch to selected iframe
driver.switch_to.frame(iframe)

    # Now click on button
driver.find_element(By.TAG_NAME, 'button').click()
  
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
    # Store iframe web element
iframe = driver.find_element(:css,'#modal > iframe')

    # Switch to the frame
driver.switch_to.frame iframe

    # Now, Click on the button
driver.find_element(:tag_name,'button').click
  
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  

名前または ID の使用

フレームまたは iframe に id 属性または name 属性がある場合、代わりにこれらを使用できます。名前または ID がページ上で一意でない場合は、最初に見つかったものが切り替えられます。

コードを移動

         //switch To IFrame using name or id
         driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email=driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
    # Switch frame by id
driver.switch_to.frame('buttonframe')

    # Now, Click on the button
driver.find_element(By.TAG_NAME, 'button').click()
  
            //switch To IFrame using name or id
            driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
    # Switch by ID
driver.switch_to.frame 'buttonframe'

    # Now, Click on the button
driver.find_element(:tag_name,'button').click
  
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  

インデックスの使用

JavaScript で window.frames を使用してクエリできるインデックスを使用することも可能です。

コードを移動

         //switch To IFrame using index
         driver.switchTo().frame(0);
    # Switch to the second frame
driver.switch_to.frame(1)
  
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
// Switches to the second frame
await driver.switchTo().frame(1);
  
// Switches to the second frame
driver.switchTo().frame(1)
  

フレームから出る

iframe または frameset から出るには、次のようにしてデフォルトコンテンツに戻ります。

コードを移動

         //leave frame
         driver.switchTo().defaultContent();
    # switch back to default content
driver.switch_to.default_content()
  
            //leave frame
            driver.SwitchTo().DefaultContent();
    # Return to the top level
driver.switch_to.default_content
  
// Return to the top level
await driver.switchTo().defaultContent();
  
// Return to the top level
driver.switchTo().defaultContent()