【问题标题】:How to use same browser window for automated test using selenium-webdriver (ruby)?如何使用 selenium-webdriver (ruby) 使用相同的浏览器窗口进行自动化测试?
【发布时间】:2024-04-24 17:30:02
【问题描述】:

我正在使用 ruby​​ 中的 selenium-webdriver 和 cucumber 为网站自动化测试用例。我需要每个功能以特定的顺序运行并使用相同的浏览器窗口。 Atm 每个功能都会创建一个新窗口来运行测试。尽管在某些测试用例中,这种行为是需要的——在许多情况下并非如此。到目前为止,从我的研究来看,关于是否可以在整个测试用例中使用 selenium 驱动相同的浏览器窗口,似乎有不同的答案。我遇到的大多数答案都是针对其他语言的,并且是特定于浏览器的解决方法(我在测试 IE 时正在开发我的测试,但预计会在其他浏览器中运行这些测试)。我在 Ruby 中工作,从我读过的内容来看,好像我必须为页面创建一个类?我很困惑为什么我必须这样做或者这有什么帮助。

我的 env.rb 文件:

require 'selenium-webdriver'
require 'rubygems'
require 'nokogiri'
require 'rspec/expectations'

Before do

    @driver ||= Selenium::WebDriver.for :ie
    @accept_next_alert = true
    @driver.manage.timeouts.implicit_wait = 30
    @driver.manage.timeouts.script_timeout = 30
    @verification_errors = []
  end

  After do
    #@driver.quit
    #@verification_errors.should == []
  end

到目前为止,我收集了一些关于有类似问题的人的信息: https://code.google.com/p/selenium/issues/detail?id=18 Is there any way to attach an already running browser to selenium webdriver in java?

如果我的问题不清楚,请向我提问。我有更多的测试要创建,但如果我的基础草率且缺少请求的功能,我不想继续创建测试。 (如果您在我的代码中发现任何其他问题,请在评论中指出)

【问题讨论】:

  • 请只发布代码的必要部分。哪一部分让你感到困惑,又是什么让你感到困惑?
  • 每个功能都会在 IE 中打开一个新窗口。我想我会删掉支持代码。它可能与之前和之后有关。虽然它可能不会。
  • 请重新编辑您的代码。并且只放置令人困惑的部分,即我们不需要的有效的部分。而不是无效的部分,只指出那部分。
  • 我已经编辑并删掉了多余的代码。
  • 好吧.. 假设您的代码以 A,B,C 的顺序打开浏览器窗口。现在你想按什么顺序关闭它们?您如何理解浏览器完成了任务,然后您将决定关闭它。

标签: ruby selenium cucumber selenium-webdriver automated-tests


【解决方案1】:

Before 挂钩在每个场景之前运行。这就是每次打开新浏览器的原因。

改为执行以下操作(在 env.rb 中):

require "selenium-webdriver"

driver = Selenium::WebDriver.for :ie
accept_next_alert = true
driver.manage.timeouts.implicit_wait = 30
driver.manage.timeouts.script_timeout = 30
verification_errors = []

Before do
  @driver = driver
end

at_exit do
  driver.close
end

在这种情况下,浏览器将在开始时打开(在任何测试之前)。然后每个测试都会抓取该浏览器并继续使用它。

注意:虽然在测试中重复使用浏览器通常是可以的。您应该注意需要以特定顺序运行的测试(即变得依赖)。依赖测试可能很难调试和维护。

【讨论】:

  • 我在After中取出了driver.close。它给了我这个错误:会话 1c7e2090-08f6-4dc9-aa4d-d407a8b2dea2 不存在(Selenium::WebDriver::Error::NoSuchDriverError)。知道这可能是什么吗?虽然我认为这可能只是答案。如果没有驱动程序。关闭测试在同一个 IE 窗口中运行。
  • 我会在稍后发现该错误的来源时进行更新。我认为目前这是由于我第一步的背景是检查@driver的当前url。看来我第一步中的代码是在 env.rb 之前执行的?
  • 对不起,我的错误。它应该是 at_exit 而不是 AfterAfter 将在每个场景之后运行 - 即在每个场景之后尝试关闭浏览器。在所有场景之后,at_exit 将在最后运行。请参阅Hooks 页面。
【解决方案2】:

我在创建 spec_helper 文件时遇到了类似的问题。为了我的目的,我做了以下(为本地运行的 firefox 简化),它工作得非常非常可靠。 RSpec 将为您的 _spec.rb 文件中的所有 it 块使用相同的浏览器窗口。

Rspec.configure do |config|
  config.before(:all) do
    @driver = Selenium::WebDriver.for :firefox
  end

  config.after(:all) do
    @driver.quit
  end
end

如果你切换到:each 而不是:all,你可以为每个断言块使用一个单独的浏览器实例......再次,:each RSpec 将为每个it 提供一个新的浏览器实例。两者都有用,视情况而定。

【讨论】:

    【解决方案3】:

    因为答案解决了问题,但不回答“如何连接到现有会话”的问题。

    我设法用以下代码做到了这一点,因为它不受官方支持。

    # monkey-patch 2 methods
    module Selenium
      module WebDriver
        class Driver
          # Be able to set the driver
          def set_bridge_to(b)
            @bridge = b
          end
    
          # bridge is a private method, simply create a public version
          def public_bridge
            @bridge
          end
        end
      end
    end
    
    
    caps = Selenium::WebDriver::Remote::Capabilities.send("chrome")
    
    driver = Selenium::WebDriver.for(
      :remote,
      url: "http://chrome:4444/wd/hub",
      desired_capabilities: caps
    )
    used_bridge = driver.bridge
    driver.get('https://www.google.com')
    
    # opens a new unused chrome window
    driver2 = Selenium::WebDriver.for(
      :remote,
      url: "http://chrome:4444/wd/hub",
      desired_capabilities: caps
    )
    
    driver2.close() # close unused chrome window
    driver2.set_bridge_to(used_bridge)
    
    driver2.title # => "Google"
    

    遗憾的是,这并没有测试 2 个救援工作之间的工作,将来当我让它适用于我自己的用例时会更新它。

    【讨论】:

      最近更新 更多