pageobject - when_visible для всех элементов

Я использую комбинацию cucumber и pageobject для тестирования своего веб-приложения. Иногда скрипт пытается щелкнуть элемент еще до того, как страница, содержащая этот элемент, начнет загружаться. (Я подтвердил это, сделав скриншоты неудачных сценариев)

Эта несогласованность не является широко распространенной и повторяется только для нескольких элементов. Вместо прямого доступа к этим элементам, если я делаю example_element.when_visible.click, набор тестов всегда проходит.

На данный момент я нажимаю ссылку, используя link_name (сгенерированную модулем pageobject при вызове link(:name, identifier: {index: 0}, &block)

Я хотел бы не редактировать вышеупомянутый фрагмент, а вести себя так, как будто я позвонил link_name_element.when_visible.click. Причина в том, что набор тестов довольно большой, и было бы утомительно менять все вхождения, и я также считаю, что функциональность уже присутствует, и почему-то я ее нигде не вижу. Кто-нибудь может мне помочь?!


person x-treme    schedule 27.11.2013    source источник
comment
Я не думаю, что есть встроенный способ сделать это. Вам нужно делать when_present перед каждой командой или только при щелчке по элементам?   -  person Justin Ko    schedule 28.11.2013
comment
я хотел бы сделать это перед каждой командой, если это возможно   -  person x-treme    schedule 28.11.2013
comment
Вы используете Watir или Selenium в качестве драйвера?   -  person Cheezy    schedule 29.11.2013
comment
Я использую Watir-webdriver   -  person x-treme    schedule 01.12.2013
comment
Можете ли вы показать свои классы объектов страницы?   -  person Helga Chekh    schedule 02.12.2013
comment
это внутренний корпоративный проект, и мой менеджер говорит, что код должен оставаться конфиденциальным. Это макет установки, в которой у нас есть класс Page, включающий модуль PageObject, а также содержащий Browser instance для инициализации pageobject. Каждая страница, представляющая класс, наследуется от вышеупомянутого класса. class Menu < Page link(:buy, {link_text: 'buy from the source'}) end Ссылка, buy, является одним из мест, где скрипт часто ломается, когда я пытаюсь щелкнуть!! Он терпит неудачу примерно в 3 из 10 раз, и это один из самых первых шагов во всех файлах!   -  person x-treme    schedule 02.12.2013


Ответы (1)


Это решение кажется довольно хакерским и может не учитывать некоторые крайние случаи. Тем не менее, я поделюсь им, так как других ответов пока нет.

Вы можете добавить следующий патч для обезьян, предполагая, что вы используете 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

По сути, целью этого патча является то, что метод 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
person Justin Ko    schedule 03.12.2013
comment
я полагаю, вы хотели ввести link(:example_link, {id: 'ex_link', wait: false}), потому что page.link_element, насколько я знаю, не принимает никаких аргументов. Поправьте меня, если я ошибаюсь - person x-treme; 03.12.2013
comment
Использование when_present ломает мой набор тестов, когда я проверяю наличие элемента, который не принадлежит странице, используя метод ?, потому что вместо возврата false, когда он отсутствует, он вызывает ошибку. Чтобы установить это право, я написал свой собственный метод ожидания, который всегда возвращает себя (как только элемент появляется или тайм-аут, если элемент не существует), а затем работает вызов exists?. Насколько мне известно, это не нарушает никакой функциональности. - person x-treme; 03.12.2013
comment
я всегда проверял это для документации, и модуль NestedElements перечисляет только один метод!! Странный!! - person x-treme; 03.12.2013