无法在iframe中选择元素

时间:2015-09-18 13:07:20

标签: javascript angularjs iframe selenium-webdriver protractor

我正在尝试编写一个需要访问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>
&#13;
&#13;
&#13;

我只在测试中想到了我可以切换到,但是我不知道要调用哪些元素进行交互。

4 个答案:

答案 0 :(得分:3)

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

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

up()

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

browser.switchTo().frame(0);

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

您也可以尝试将其切换到特定的框架:

element(by.___())

答案 1 :(得分: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,但再次调试将是一件痛苦的事。我会建议第一种方式。希望这会有所帮助。

答案 2 :(得分:2)

尝试执行脚本来获取所需信息可能不是最好的方法。 如果您使用的是量角器或硒,您可以使用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)
})

答案 3 :(得分:2)

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

  

browser.switchTo()。frame(element(by.tagName)&#39; iframe&#39;   ))getWebElement());

或者可以使用className来获取元素而不是tagName。然后可以获取iframe中的任何元素。

之后如果需要回到父框架

  

browser.driver.switchToParentFrame();