watir-webdriver - execute_script抛出javascript错误

时间:2014-08-08 05:37:17

标签: javascript ruby watir-webdriver

以下javascript代码获取以" opt1"开头的所有div元素的id和内部文本。我用javascript做这个,因为这个div是不可见的,webdriver不支持访问不可见的元素。

以下代码在irb上执行时工作正常,但在" JavaScript错误"当我运行整个脚本。我还在IE控制台上执行了javascript代码,以确保javascript正确并且没有错误。

   mn = $browser.execute_script <<-JS
   var eles = window.frames[1].document.getElementsByTagName('div');
   var dom = [];
   for ( var i = 0; i < eles.length; i++) {
     if (eles[i].id.indexOf("opt1_") === 0) {
       dom.push(eles[i].id + "--" + eles[i].innerText);
     }
   }
   return dom;
   JS

任何人都可以帮我这个。

提前致谢..

1 个答案:

答案 0 :(得分:2)

问题可能在于Selenium处理帧的方式。看起来当尝试​​对帧执行任何操作时会发生Javascript错误 - 即错误发生的原因是:

window.frames[1].document

解决方案 - 在框架的上下文中执行Javascript

一种解决方案是在框架的上下文中运行Javascript。

假设主页面使用的是iframe(尽管可以用框架完成):

<html>
  <body>
    <iframe src="test.htm"></iframe>
    <iframe src="frame_content.htm"></iframe>
  </body>
</html>

frame_content.htm有一些可见和不可见的div:

<html>
  <body>
    <div>irrelevant content</div>
    <div id="opt1_visible">visible content</div>
    <div id="opt1_hidden" style="display:none;">hidden content</div>
  </body>
</html>

然后在Watir中,您可以针对框架对象(而不是浏览器)执行脚本(修改为删除window.frames[1]):

frame = browser.iframe(:index => 1) # Use .frame if the page is using frames instead
mn = frame.execute_script <<-JS
   var eles = document.getElementsByTagName('div');
   var dom = [];
   for ( var i = 0; i < eles.length; i++) {
     if (eles[i].id.indexOf("opt1_") === 0) {
       dom.push(eles[i].id + "--" + eles[i].innerText);
     }
   }
   return dom;
   JS
p mn
#=> ["opt1_visible--visible content", "opt1_hidden--hidden content"]

解决方案 - 仅使用Watir

虽然Watir无法对隐形元素执行操作,但您仍可以检查它们。唯一困难的是获取文本,因为Element#文本只返回可见文本。解决方法是改为使用Element#attribute_value

您可以通过以下方式获得与Javascript方法相同的结果:

frame = b.iframe(:index => 1) # Use .frame if the page is using frames instead
mn = b.divs(:id => /^opt1_/).map do |div|
  "#{div.id}--#{div.attribute_value('innerText')}"
end
p mn
#=> ["opt1_visible--visible content", "opt1_hidden--hidden content"]

请注意.attribute_value('innerText')适用于IE。如果您使用的是Firefox,则需要执行.attribute_value('textContent')。我相信Chrome支持两种属性。