2

我正在使用 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 有没有办法将已经运行的浏览器附加到 java 中的 selenium webdriver ?

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

4

3 回答 3

9

钩子在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

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

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

于 2013-07-12T21:21:25.307 回答
2

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

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

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

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

于 2014-09-16T19:00:09.007 回答
0

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

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

# 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"

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

于 2020-05-08T12:41:41.470 回答