1

cucumberとの組み合わせを使用してpageobject、Web アプリケーションをテストしています。要素を含むページの読み込みが開始される前であっても、スクリプトが要素をクリックしようとすることがあります。(失敗したシナリオのスクリーンショットをキャプチャすることでこれを確認しました)

この不一致は広範囲に及ぶものではなく、いくつかの要素に対してのみ繰り返し発生します。これらの要素に直接アクセスする代わりに、そうするとexample_element.when_visible.click、テスト スイートは常にパスします。

今のところ、link_name(呼び出し時にpageobjectモジュールによって生成された)を使用してリンクをクリックしますlink(:name, identifier: {index: 0}, &block)

上記のスニペットは編集せずに、link_name_element.when_visible.click. その理由は、テスト スイートが非常に大きく、すべてのオカレンスを変更するのは面倒であり、機能が既に存在していて、どういうわけかどこにも見当たらないからです。誰か助けてくれませんか?!

4

1 に答える 1

2

これは解決策のようで、非常にハッキリしているようで、いくつかのエッジケースを考慮していない可能性があります。ただし、他にまだ回答がないため、共有します。

watir-webdriver を使用していると仮定して、次のモンキー パッチを追加できます。これは、page-object を要求した後に追加されます。

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

基本的に、このパッチの意図は、Watirwhen_presentメソッドが常に呼び出されることです。たとえば、ページ オブジェクトの呼び出しは として Watir に変換されbrowser.link.when_present.clickます。理論的には、ページ オブジェクト要素で呼び出されるすべてのメソッドに対して呼び出される必要があります。

残念ながら、落とし穴があります。要素が存在するのを待ちたくない場合があります。たとえば、 をpage.link_element.when_not_visible実行する場合、要素が表示されないことを確認する前に、要素が表示されるのを待ちたくありません。このような場合、:wait => false要素ロケーターに含めることで、待機しないという標準的な動作を強制できます。

page.link_element(:wait => false).when_not_visible
于 2013-12-03T05:15:01.487 に答える