Ruby pageobject-当所有元素都可见时

Ruby pageobject-当所有元素都可见时,ruby,cucumber,watir-webdriver,page-object-gem,Ruby,Cucumber,Watir Webdriver,Page Object Gem,我正在使用cucumber和pageobject的组合来测试我的web应用程序。有时,脚本甚至在包含元素的页面开始加载之前就尝试单击该元素。(我通过捕捉失败场景的截图证实了这一点) 这种不一致性并没有广泛传播,而且只在少数元素中重复出现。如果我使用示例元素,而不是直接访问这些元素。当元素可见时,单击,测试套件始终通过 现在,我使用link\u name单击一个链接(由调用link(:name,identifier:{index:0},&block)的pageobject模块生成) 我不想编辑上面

我正在使用
cucumber
pageobject
的组合来测试我的web应用程序。有时,脚本甚至在包含元素的页面开始加载之前就尝试单击该元素。(我通过捕捉失败场景的截图证实了这一点)

这种不一致性并没有广泛传播,而且只在少数元素中重复出现。如果我使用
示例元素,而不是直接访问这些元素。当元素可见时,单击
,测试套件始终通过

现在,我使用
link\u name
单击一个链接(由调用
link(:name,identifier:{index:0},&block)的pageobject模块生成)


我不想编辑上面提到的代码段,而是像调用了
link\u name\u元素一样。当\u可见时,单击
。原因是,测试套件非常大,更改所有出现的情况将非常繁琐,而且我还相信该功能已经存在,不知何故,我在任何地方都看不到它。有人能帮我修改吗ut?!

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

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

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 as
browser.link。when_present.click
。理论上,对于页面对象元素上调用的任何方法,都应该调用它

不幸的是,这里有一个陷阱。在某些情况下,您可能不想等待元素出现。例如,在执行
页面链接\u元素时。当\u不可见时
,您不想在检查元素是否出现之前等待元素出现。在这些情况下,您可以强制执行标准beh通过在元素定位器中包含
:wait=>false来避免等待:

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

我不认为有一种内置的方法可以做到这一点。你需要在每个命令之前或单击元素时执行
吗?我想在每个命令之前执行,如果可能的话。你可以使用Watir或Selenium作为驱动程序吗?我正在使用Watir Webdriver你可以显示你的页面对象类吗?我相信你是想ype
link(:example\u link,{id:'ex\u link',wait:false})
因为
page.link\u元素
据我所知不接受任何参数。如果我错了
page,请纠正我。link\u元素
接受参数-请参阅。注意,此示例是在使用
link\u元素
查找嵌套元素时出现的。如果您在页面对象访问器中执行此操作,则示例为corr当我使用
方法检查页面中是否存在不属于该页面的元素时,使用
出现时会中断我的测试套件,因为当不存在时,它不会返回false,而是会引发错误。为了正确设置,我编写了自己的等待方法,该方法始终返回self(只要元素出现,或者如果元素不存在,则超时)然后调用
存在?
工作。就我所知,这不会破坏任何功能。我总是检查文档,NesteElements模块只列出一种方法!!奇怪!!