【问题标题】:Cannot select an element inside an iframe无法选择 iframe 内的元素
【发布时间】:2015-09-18 13:07:20
【问题描述】:

我正在尝试编写一个需要访问 iframe 中元素的测试。 (想象一个有 20 把椅子的房间,每把椅子都是它自己的对象,我需要能够使用这些椅子)。使用开发人员工具和元素查找器,它只突出显示 iframe,但不允许我访问。我对测试非常陌生,所以我很茫然。

高亮iframe时html中的元素是这样的:

<iframe name="daasFrame" class="daas-surface" frameborder="0" width="100%" height="100%" ng-src="/Drawing/EventDiagram/e020c975-6f1f-4c6c-bf34-34fa7221c8f3/?venueId=&amp;seatingStyle=theater&amp;language=en&amp;units=Imperial&amp;theme=default&amp;shiftHeader=true"
src="/Drawing/EventDiagram/e020c975-6f1f-4c6c-bf34-34fa7221c8f3/?venueId=&amp;seatingStyle=theater&amp;language=en&amp;units=Imperial&amp;theme=default&amp;shiftHeader=true"></iframe>

我认为仅在测试中我就可以切换到,但是我不知道将调用哪些元素进行交互。

【问题讨论】:

  • 您的意思是要使用量角器代码获取 iframe 中的元素?或者您想使用开发人员工具访问它们,以便您可以使用这些元素进行编码?
  • 我使用相反的方式...在 iframe 上,您可以使用 parent.anyFunction() 访问调用方的函数...然后,在 iframe init 上,我调用类似 parent.getConfig( ),然后我会执行所需的操作。
  • @Girish 我编写测试的方式是通过开发人员工具上的元素选择器。 Chrome 有一个元素定位器,它允许我单击一个元素并将代码带给我。但是我无法获取 iframe 的 html。我不知道如何
  • 我明白了,所以你想获取 iframe 中的元素,这样你就可以使用它们来自动化一些事情。正确的?如果是这样,你想如何得到它?是使用元素定位器还是使用量角器代码?

标签: javascript angularjs iframe selenium-webdriver protractor


【解决方案1】:

在使用我的自动化测试套件时,我遇到了一个实例,我需要在 iFrame 之外采取行动并验证 iFrame 内部是否发生了适当的更改。为了便于在框架之间来回跳转,我在页面对象中设置了 2 个函数,一个用于跳转到 iFrame,另一个用于跳转回主窗口。


要跳转到 iFrame,我使用了这个:

browser.switchTo().frame(0);

要切换回主窗口,我使用了这个:

browser.switchTo().defaultContent();

一旦我进入 iFrame,只要它是一个 AngularJS 页面,我就不必做任何特别的事情。所有element(by.___()) 查询都会引用 iFrame 并在其中进行搜索。如果它是一个标准网站,您需要在测试中使用未包装的 Selenium 语法 (http://ng-learn.org/2014/02/Protractor_Testing_With_Angular_And_Non_Angular_Sites/)。


你也可以试试这个来切换到特定的帧:

browser.switchTo().frame(element(by.className('daas-surface')));

【讨论】:

    【解决方案2】:

    有两种方法。首先使用 chrome 中的开发人员工具(如果使用 firefox,则 firebug 插件可以提供帮助)。如果您打开开发者工具,您可以随时访问整个 html。

    Open the webpage you want to test -> Click on the menu on the top right corner of chrome -> 
    select more tools -> developer tools
    

    您应该能够看到包括 iframe 在内的网页的完整 html。现在您可以转到 iframe 部分,然后在其中搜索 body 标记以查看已加载的元素。将鼠标悬停在它们上会给你元素。

    第二种方法有点困难,您可以使用 javascript 代码获取 html 元素。方法如下 -

    browser.executeScript("return document.getElementsByTagName('iframe')[0].contentWindow.document.body.innerHTML;").then(function(html){
        console.log(html);
    });
    

    或使用量角器代码获取元素的内部 Html,但请等到 iframe 中的 html 加载后再使用它:

    var ele = $('.daas-surface body'); //Make sure iframe element has body tag if not use some main element's tag within which you want to access the elements.
    browser.wait(protractor.ExpectedConditions.presenceOf(ele), 20000)
    .then(function(){
        ele.getInnerHtml().then(function(html){
            console.log(html);
        });
    });
    

    getElementsByTagName 以数组的形式返回 DOM 中具有该标签的所有元素,如果您有多个 iframe,则使用不同的值来获取不同的元素。上面的行将在 iframe 中打印完整的 html,但再次调试对您来说会很痛苦。我建议第一种方式。希望这会有所帮助。

    【讨论】:

    • 我收到错误:失败:未知错误:无法读取 null 的属性“contentWindow”
    • @NicolePhillips 抱歉,这是我的错误。在您执行的 javascript 函数中使用您的元素标识符。我更新了它以通过 html 标签名称获取元素。你也可以用类等来做......
    • 我可以切换到框架。有没有可以告诉它使用日志打印 html 的功能?
    • 是的.. 试试$('.daas-surface').getInnerHtml().then(function(html){console.log(html);})。也使用此功能更新了答案。注意 - 在 iframe 内的 html 加载之前等待几秒钟。如果未加载,则会导致问题。希望这会有所帮助。
    • 我在尝试访问不同的框架时遇到最大调用堆栈错误
    【解决方案3】:

    尝试执行脚本来获取您想要的信息可能不是最好的方法。 如果您使用量角器或 selenium,则可以使用 switchTo 将 selenium 命令的上下文更改为所需的帧。

    browser.switchTo().frame($('[name=daasFrame]'))
    
    $('#element-inside-frame').getText().then(function (text) {
     console.log(text)
    });
    
    // switch back to the "parent page" context
    browser.switchTo().defaultContent()
    

    如果你想要的只是 iframe 的 HTML 内容,这就足够了:

    $('[name=daasFrame]').getText().then(function (text) {
      console.log(text)
    })
    

    【讨论】:

      【解决方案4】:

      因为iframe 被视为一个新窗口。首先需要切换到iframe。简单的解决方案是

      browser.switchTo().frame( element( by.tagName( 'iframe' )).getWebElement());

      否则可以使用className 代替tagName 来获取元素。然后可以得到iframe中的任意元素。

      之后如果需要返回父框架

      browser.driver.switchToParentFrame();

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-15
        • 1970-01-01
        • 2018-07-13
        • 2013-07-17
        • 1970-01-01
        • 2017-06-26
        • 2018-08-05
        相关资源
        最近更新 更多