pageobject - 所有元素的when_visible

时间:2013-11-27 19:39:00

标签: ruby cucumber watir-webdriver page-object-gem

我正在使用cucumberpageobject的组合来测试我的网络应用程序。有时,脚本会在包含元素的页面开始加载之前尝试单击元素。 (我通过捕获失败场景的屏幕截图确认了这一点)

这种不一致性并不广泛,只是针对少数元素重复发生。如果我执行example_element.when_visible.click,测试套件总是通过,而不是直接访问这些元素。

截至目前,我点击使用link_name的链接(由调用link(:name, identifier: {index: 0}, &block)的页面对象模块生成

我不想编辑上面提到的代码段,但就像我调用link_name_element.when_visible.click一样。原因是,测试套件非常大,改变所有出现的情况会很繁琐,而且我也相信功能已经存在,不知何故我在任何地方都看不到它。任何人都可以帮助我吗?!

1 个答案:

答案 0 :(得分:2)

这似乎解决方案似乎非常hacky,可能不会考虑一些边缘情况。但是,我会分享它,因为还没有其他答案。

假设您使用的是watir-webdriver,则可以添加以下猴子补丁。这将在您需要页面对象后添加。

require 'watir-webdriver'
require 'page-object'

module PageObject
  module Platforms
    module WatirWebDriver
      class PageObject
        def find_watir_element(the_call, type, identifier, tag_name=nil)
          identifier, frame_identifiers, wait = parse_identifiers(identifier, type, tag_name)
          the_call, identifier = move_element_to_css_selector(the_call, identifier)

          if wait
            element = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}.when_present"
          else
            element = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
          end
          switch_to_default_content(frame_identifiers)
          type.new(element, :platform => :watir_webdriver)
        end        

        def process_watir_call(the_call, type, identifier, value=nil, tag_name=nil)
          identifier, frame_identifiers, wait = parse_identifiers(identifier, type, tag_name)
          the_call, identifier = move_element_to_css_selector(the_call, identifier)

          if wait
            modified_call = the_call.dup.insert(the_call.rindex('.'), '.when_present')
            value = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{modified_call}"
          else
            value = @browser.instance_eval "#{nested_frames(frame_identifiers)}#{the_call}"
          end

          switch_to_default_content(frame_identifiers)
          value
        end

        def parse_identifiers(identifier, element, tag_name=nil)
          wait = identifier.has_key?(:wait) ? false : true
          identifier.delete(:wait)

          frame_identifiers = identifier.delete(:frame)
          identifier = add_tagname_if_needed identifier, tag_name if tag_name
          identifier = element.watir_identifier_for identifier
          return identifier, frame_identifiers, wait
        end        
      end
    end
  end
end

基本上,此补丁的目的是始终调用Watir when_present方法。例如,您的页面对象调用将转换为Watir browser.link.when_present.click。从理论上讲,应该调用在页面对象元素上调用的任何方法。

不幸的是,有一个问题。在某些情况下,您可能不希望等待元素出现。例如,在执行page.link_element.when_not_visible时,您不希望在检查元素未显示之前等待元素出现。在这些情况下,您可以通过在元素定位器中包含:wait => false来强制不等待的标准行为:

page.link_element(:wait => false).when_not_visible