PageObject“wait element”方法不起作用

时间:2013-04-12 04:50:53

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

我正在使用黄瓜,selenium-webdriver和page-object gem进行测试自动化。 当我尝试运行简单的测试黄瓜时,请注意以下错误:

  Scenario: Going to billing                # features/test.feature:10
    When I click 'Платные услуги'           # features/step_definitions/test_steps.rb:13
      Unable to locate element: {"method":"link text","selector":"Платные услуги"} (Selenium::WebDriver::Error::NoSuchElementError)
      [remote server] file:///tmp/webdriver-profile20130412-21410-z4p1ez/extensions/fxdriver@googlecode.com/components/driver_component.js:8405:in `FirefoxDriver.prototype.findElementInternal_'
      [remote server] file:///tmp/webdriver-profile20130412-21410-z4p1ez/extensions/fxdriver@googlecode.com/components/driver_component.js:8414:in `FirefoxDriver.prototype.findElement'
      [remote server] file:///tmp/webdriver-profile20130412-21410-z4p1ez/extensions/fxdriver@googlecode.com/components/command_processor.js:10421:in `DelayedCommand.prototype.executeInternal_/h'
      [remote server] file:///tmp/webdriver-profile20130412-21410-z4p1ez/extensions/fxdriver@googlecode.com/components/command_processor.js:10426:in `DelayedCommand.prototype.executeInternal_'
      [remote server] file:///tmp/webdriver-profile20130412-21410-z4p1ez/extensions/fxdriver@googlecode.com/components/command_processor.js:10366:in `DelayedCommand.prototype.execute/<'
      ./features/pages/job_main_page.rb:38:in `go_to_billing'
      ./features/step_definitions/test_steps.rb:14:in `/^I click 'Платные услуги'$/'
      features/test.feature:11:in `When I click 'Платные услуги''

这是黄瓜特色:

Scenario: Going to billing
    When I click 'Платные услуги'
    Then I should see "Коммерческие услуги"

测试失败的步骤定义:

When(/^I go to billing$/) do
    @job_myroom_billing = @job_myroom.billing_element.when_visible.go_to_billing
end

页面对象:

class BasePage
    include PageObject
    include RSpec::Matchers
end

class JobMyroom < BasePage 
    link :billing, link: 'Платные услуги'

    def go_to_billing
        billing
        JobMyroomBilling.new @browser
    end
end

class JobMyroomBilling < JobMyroom    
     #some code
end

什么错了?司机不等待元素存在

3 个答案:

答案 0 :(得分:3)

我认为Sheg在这里给出了一些好的建议,尽管我倾向于略微不同:

wait_until do
  billing_element.visible?
end 

你可以做的另一件非常相似的事情是用你的方法替换你方法中的代码:

def go_to_billing
  billing_element.when_present.click
  JobMyroomBilling.new @browser
end

在这种情况下,我们要等到链接存在,当when_present方法返回元素时,我们只需单击它。

我可能建议的另一件事是使用watir-webdriver作为驱动程序而不是selenium-webdriver。 watir-webdriver是建立在selenium-webdriver之上的,但似乎有更好的处理等待实际加载到DOM上的项目。如果使用Ajax动态添加链接,那么在实际与之交互之前,您必须编写一些代码,直到它存在。要使用其他gem,您唯一需要做的就是将Before块中的代码更改为:

Before do
  @browser = Watir::Browser.new :firefox
end

我会给你的另一个指针是没有一个页面对象返回下一个页面对象的实例。我在这里吃自己的话,因为几年前我就是这样做的,但随着时间的推移,我发现这是一种脆弱的方法。相反,我会使用PageObject::PageFactory来管理正确页面的创建,当你有一个通用步骤时,你可以简单地使用@current_page实例变量。

我将给你的最后一个指针是从页面对象中删除断言。我希望页面对象只提供抽象并在步骤定义中执行所有验证。这是一个更清晰的关注点分离,并将使您的测试更容易保持一段时间。

答案 1 :(得分:0)

你可以使用try catch从java中使用sleep方法。或隐含等待selenium webdriver。 Webdriver永远不会等待元素显示......基本上你需要延迟。

答案 2 :(得分:0)

页面对象when_visible方法意味着等待Ajax事件完成加载,如https://github.com/cheezy/page-object/wiki/Ajax-Calls所述。

如果webdriver在完全呈现之前尝试单击link元素,并且与Ajax无关,请考虑等到元素首先显示webdriver。例如:

wait.until { driver.find_element(:link_text => "Платные услуги").displayed? }
@job_myroom.go_to_billing

你可以(强烈推荐)通过在实例化你的webdriver后立即调用以下内容来隐式地对所有元素执行此操作:

driver.manage.timeouts.implicit_wait = 3

此外,在许多情况下,我发现通过href定位链接比link_text更好。也许这些可以解决您的元素计时问题。