Selenium WebDriver executeScript的问题(在Ruby中使用watir-webdriver)

时间:2013-05-15 23:41:02

标签: ruby selenium-webdriver watir-webdriver legacy-code page-object-gem

我无法使用Watir WebDriver的browser.execute_script命令执行特定的JavaScript代码段:

以下是相关的Javascript:

  var bodyFrame = document.getElementsByName("BodyFrame")[0];
  var bodyFrameDoc = bodyFrame.contentDocument || bodyFrame.contentWindow.document;
  var mainFrame = bodyFrameDoc.getElementById("MainFrame");
  var mainFrameDoc = mainFrame.contentDocument || mainFrame.contentWindow.document;
  var row = mainFrameDoc.getElementById("DETAIL_1");
  var rowNodes = row.childNodes;
  var index;
  for (index = 0; index < rowNodes.length; index++) {

        if (rowNodes[index].firstChild.id === 'ID1') {
            rowNodes[index].firstChild.value = 'ACCRUL';
        }


        if (rowNodes[index].firstChild.id === 'ID2') {
            rowNodes[index].firstChild.value = 'OP';
        }


        if (rowNodes[index].firstChild.id === 'ID3') {
            rowNodes[index].firstChild.value = 'Z';
        }


        if (rowNodes[index].firstChild.id === 'ID4') {
            rowNodes[index].firstChild.value = 'FIRST';
        }


        if (rowNodes[index].firstChild.id === 'ID5') {
            rowNodes[index].firstChild.value = 'AUT';
        }


        if (rowNodes[index].firstChild.id === 'ID6') {
            rowNodes[index].firstChild.value = 'AU1000';
        }


        if (rowNodes[index].firstChild.id === 'ID7') {
            rowNodes[index].firstChild.value = 'm tax m entity m jc';
        }


        if (rowNodes[index].firstChild.id === 'ID8') {
            rowNodes[index].firstChild.value = 'MR5001100';
        }


        if (rowNodes[index].firstChild.id === 'ID9') {
            rowNodes[index].firstChild.value = 'T';
        }


        if (rowNodes[index].firstChild.id === 'ID10') {
            rowNodes[index].firstChild.value = '453.36';
        }

  }

为什么我必须使用这样的暴行?好吧,因为我正在开发测试的产品是那么糟糕。每个单元格使用相同的id属性,因此我不能直接将文档中的对象区域化。更糟糕的是,该文件深入两帧。 Frameception。

使用明显的解决方案(使用watir-webdriver的API)是不可行的,因为填充32个网格行的任务占用了一半!一个小时。

我可以在浏览器的开发者工具中运行上面的Javascript。 (此产品支持的唯一浏览器是IE8,9,在兼容模式下。)我无法访问jQuery或任何花哨的JavaScript库。使用这个javascript几乎可以立即填充行。

当我使用browser.execute_script命令运行时,我得到了一个

  Selenium::WebDriver::Error::JavascriptError: JavaScript error

奇怪的是,如果我刚刚使用

  return document.getElementsByName("BodyFrame")[0];

然后我收到Net :: HTTP库的错误,Selenium在堆栈的某个地方使用它来向浏览器来回发送命令。 (更具体地说:ERRNO :: ERRCONNREFUSED)

帮助?

编辑:这是我用来执行代码的直接脚本(并生成一小部分Javascript):

    def quick_fill(data = {})
      reference_element.focus;
      quick_filler = ->(element_id, value) {
        "if (rowNodes[index].firstChild.id === '#{element_id}') {
           rowNodes[index].firstChild.value = '#{value}';
         }"
      }
      row_id = row.attribute(:id)
      element_ids = Hash[data.keys.map { |key| [key, send("#{key}_element").attribute(:id)] }]
      javascript = <<-JAVASCRIPT
      var bodyFrame = document.getElementsByName("BodyFrame")[0];
      var bodyFrameDoc = bodyFrame.contentDocument || bodyFrame.contentWindow.document;
      var mainFrame = bodyFrameDoc.getElementById("MainFrame");
      var mainFrameDoc = mainFrame.contentDocument || mainFrame.contentWindow.document;
      var row = mainFrameDoc.getElementById("DETAIL_1");
      var rowNodes = row.childNodes;
      var index;
      for (index = 0; index < rowNodes.length; index += 1) {
        #{element_ids.map { |method, element_id| quick_filler.call(element_id, data[method]) }.join("\n") }
      }
      JAVASCRIPT
      puts javascript
      sleep(0.500)
      browser.execute_script(javascript)
    end

此方法的数据参数是键值对的哈希值,其中键是提供给页面对象访问器的方法的名称,值是我要填写的值。作为在中间过程中,我从页面对象元素(每个元素作为标识符提供)中获取id元素。

页面类的设置方式有一些奇特的结构:这是基本的想法:

class MyPage
  include PageObject

  table(:some_table, ...)

  def add_line_item(data = {})
    GridRow.new(some_table_element.last_row, browser).quick_fill(data)
  end

  class GridRow
    include PageObject

    #page object accessors
    text_field(:my_field) { row.text_field_element(id: 'ID1') }
    #etc

    def quick_fill(data = {})
      #see above
    end

    def initialize(row, browser, visit = false)
      @row = row
      super(browser, visit) 
    end
  end
end

所以示例调用将是(来自黄瓜测试)

on_page(MyPage) do |page|
  page.add_line_item(:my_detail => 'myValue')
end

除此之外,还有一个令人遗憾的问题,即到达此页面需要几个“attach_window”调用(由于页面位于各种模式对话框中)。这个问题可能主要与这种互动有关。这是我能想到的唯一会导致问题的事情。

这个问题的关键在于希望只有第二眼可以排除任何明显错误。我有另一种解决方法,我打算雇用。

0 个答案:

没有答案