关于watir Webdriver:单击PageObject中的链接时的调用方法

Call method when clicking on a link in PageObject

我正在使用Watir-Webdriver和PageObject gem来自动执行测试。

我有一个这样定义的PageObject:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Page
  include PageObject

  div(:loading_indicator, :class => 'loading_indicator')

  div(:display_detail, :id => 'log_module_detail')

  # large number of links like this:
  link(:input1) { display_detail_element.link_element(:id => 'detailed_input1') }
  link(:input2) { display_detail_element.link_element(:id => 'detailed_input2') }
  # input3, input4, etc..

  def wait_on_loading_indicator
    loading_indicator_element.when_not_present # wait till loading indicator is gone
  end
end

当我按下input1时,loading_indicator出现,并且我想等待它消失后再继续。

我当然可以定义这样的方法:

1
2
3
4
def click_input1
  input1
  wait_on_loading_indicator
end

但是我必须为每个链接定义一个类似的方法...
理想情况下,我想要这样的东西:
link(:input1) { display_detail_element.link_element(:id => 'detailed_input1'); wait_on_loading_indicator }
但这是行不通的。有一些简单/干净的方法可以做到这一点吗?


一种方法是创建定义正常链接方法的访问器,并覆盖click方法以调用wait_on_loading_indicator方法。

页面对象为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class MyPage
  include PageObject

  def self.detailed_input(name, identifier={:index => 0}, &block)
    link(name, identifier, &block)
    define_method(name) do
      send("#{name}_element").click      
      wait_on_loading_indicator    
    end
  end

  div(:loading_indicator, :class => 'loading_indicator')
  div(:display_detail, :id => 'log_module_detail')

  detailed_input(:input1) { display_detail_element.link_element(:id => 'detailed_input1') }
  detailed_input(:input2) { display_detail_element.link_element(:id => 'detailed_input2') }

  def wait_on_loading_indicator
    loading_indicator_element.when_not_present
  end  
end

注意detailed_input类方法:
1.调用标准link访问器方法以设置标准链接方法。
2.重新定义单击链接的方法,以同时调用wait_on_loading_indicator方法。

需要等待指示符的链接将使用自定义访问器方法,而不是标准的link方法。换句话说,它们声明为:

1
2
detailed_input(:input1) { display_detail_element.link_element(:id => 'detailed_input1') }
detailed_input(:input2) { display_detail_element.link_element(:id => 'detailed_input2') }

您可以在页面上看到此作品:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html>
  <head>
    wait test
    <script type="text/javascript" charset="utf-8">
      function loading() {
        var e = document.getElementById("loading")
        e.style.display ="block";
        setTimeout(function() {
          e.parentNode.removeChild(e);
        }, 2000);
      }        
   
  </head>
  <body>
    loading
   
      detailed_input1
   
  </body>
</html>

针对页面对象运行以下代码时:

1
2
3
4
5
6
page = MyPage.new(browser)
puts page.loading_indicator_element.visible?
#=> false
page.input1
puts page.loading_indicator_element.visible?
#=> false (this would return `true` without the wait method)