【问题标题】:Capybara instance of "browser" for Page Object Model?页面对象模型的“浏览器”的水豚实例?
【发布时间】:2019-12-21 04:46:51
【问题描述】:

我正在为 Web 应用程序使用 Capybara 和页面对象模型编写框架。这是我第一次编写自己的框架并使用 PoM 进行自动化。

我的基础“页面对象”本质上是初始化驱动程序,并在所有其他页面对象子类中使用(用于单个页面)

class PageObject
    include Capybara::DSL
    BASE_URL = 'https://www.atesturl.com'
    Capybara.default_max_wait_time = 5

    def initialize

        Capybara.register_driver :selenium_chrome do |app|
            Capybara::Selenium::Driver.load_selenium
            browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
              # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
              opts.args << '--disable-site-isolation-trials'
            end
            Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
          end

        Capybara.register_driver :selenium_chrome_headless do |app|
            Capybara::Selenium::Driver.load_selenium
            browser_options = ::Selenium::WebDriver::Chrome::Options.new.tap do |opts|
              opts.args << '--headless'
              opts.args << 'window-size=2880,1800'
              opts.args << '--disable-gpu' if Gem.win_platform?
              #opts.args << '--remote-debugging-port=9222'
              # Workaround https://bugs.chromium.org/p/chromedriver/issues/detail?id=2650&q=load&sort=-id&colspec=ID%20Status%20Pri%20Owner%20Summary
              opts.args << '--disable-site-isolation-trials'
            end
            Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
          end

        Capybara.current_driver = :selenium_chrome
    end

    def visit_url
        visit BASE_URL
    end

  end

在大多数 PoM 示例中,我看到方法返回该页面对象的实例,但通常它们使用一些 @browser 传递的实例变量。在我的测试脚本中,我简单地通过let(:p) {PageObject.new} 调用基本页面对象类的实例,然后通过p.visit_url 然后通过new 创建其他页面对象的新实例......但这似乎是错误的做法它。

我究竟如何返回可以传递的@browser 或驱动程序的实例?我应该如何在我的规范中调用它?

【问题讨论】:

  • 试图理解你的问题......所以目前'浏览器'是一些不可见的全局(这就是为什么你在没有调用者的情况下调用visit)但你想让它成为一个你可以的变量绕过?
  • 基本上,这就是我看到人们做方法链接返回页面对象的方式。我假设我可能会在构造函数中调用@browser 的实例?
  • 好吧,你可以从 visit_url 之类的方法中返回 self,这将使其可链接

标签: ruby capybara pageobjects


【解决方案1】:

您不希望在基本 PageObject 的初始化中注册您的驱动程序,因为这意味着创建的每个对象都将注册新的驱动程序配置 - 这是不可取的。

当您将 Capybara::DSL 包含到您的类中时,您将包含最终调用 Capybara.current_session 上的方法的方法。即visit => Capybara.current_session.visitCapybara.current_session 的结果是您要询问的“@browser”实例,因为它封装了驱动程序/浏览器实例。您当前实现的方式的问题是,如果任何代码更改了当前会话,那么您的所有对象都会突然引用新会话。相反,如果您存储对您希望对象在每个对象中使用的会话的引用,并在该会话上调用 Capybara 方法而不是使用 Capybara::DSL (@session.visit ...),那么您可以确定对象正在使用的会话不不要意外改变。

另请注意,Capybara.default_max_wait_time、`Capybara.current_driver' 等都是全局设置,因此将它们设置在 PageObject 类中并不是一个好主意。

【讨论】:

  • 存储这些全局设置的合适位置在哪里(这不是 Rails 存储库)。你说“如果你存储对会话的引用,你希望对象在每个对象中使用”。我对你的意思或这个例子有点困惑,我具体做了什么导致这个问题?而且我不确定什么代码会改变当前会话? (到目前为止,我一直在使用这个示例,没有任何问题,但它并不“感觉”正确。
  • @msmith1114 通过使用using_session、更改当前驱动程序、调用session_name= 或设置Capybara.app,可以在任何地方更改当前会话 - 通常您不希望更改使用的会话现有的页面对象。至于全局设置 - 通常,无论您在为您的应用程序进行初始设置时,它们都会被设置一次。
  • @msmith1114 对于会话的实例 - 如果在您的初始化方法中设置 @session = Capybara.current_session 然后在 @session(@session.visit、@session.find 等)上调用所有水豚方法,您将不再有可能改变会话的问题。每个对象都会在创建对象时存储当前会话。更好的选择是在创建对象时传入会话 - 您可以在创建主页时最初传入 Capybara.current_session - 然后它可以在创建子对象时传递它
  • 所以也许只是在每个页面对象中我可以有一个初始化方法,该方法接受一个变量并将其存储在@browser@session 变量中(用于该页面对象)。我想在测试脚本中(使用 rspec)我可以在每个描述场景之前创建这个 @session 变量以在 let 中传递。在这种情况下,我需要删除我一开始假设的 Capybara::DSL 调用?只是想想想注册司机的最佳地点在哪里。因为这不是一个 rails 设置(而只是一个 ruby​​ 设置)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多