【问题标题】:Selenium webdriver with Ruby : Use existing session idSelenium webdriver with Ruby:使用现有的会话 ID
【发布时间】:2021-10-25 06:18:14
【问题描述】:

我是 Selenium Web 驱动程序的新手,目前正在使用 Ruby 编程语言。我目前有一个场景,我需要使用 selenium Web 驱动程序执行多个 ruby​​ 脚本,但它们必须使用相同的浏览器会话。我正在关注以下链接中提供的文档:https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings

目前,我的代码如下所示。

require 'selenium-webdriver'

# ---------------------------------------------------------
url = "http://localhost:4444/wd/hub"
driver1 = Selenium::WebDriver.for :remote, url: url, desired_capabilities: :firefox
driver1.get "http://www.msn.com"
puts driver1.title

# store the session id
sessionid = driver1.session_id

# ---------------------------------------------------------
#  Try using the existing session id from driver1
driver2 = Selenium::WebDriver.for :remote, url: url, desired_capabilities: :firefox

# The below statement gives error on assignment
driver2.session_id = sessionid
driver2.get "http://www.yahoo.com"

我阅读了这篇帖子 Can Selenium interact with an existing browser session? 并尝试按照此处提供的步骤操作,无法使用现有的网络驱动程序/浏览器会话。

有没有人成功地使用 selenium-webdriver 和 Ruby 重用现有会话?请让我知道此代码 sn-p 中遗漏了什么。

我能够在 python 中完成这项工作。

from selenium import webdriver
from selenium.webdriver.remote.webdriver import WebDriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities



executor_url = "http://localhost:4444/wd/hub"
# Create a desired capabilities object as a starting point.
capabilities = DesiredCapabilities.FIREFOX.copy()
capabilities['platform'] = "WINDOWS"
capabilities['version'] = "10"

# ------------------------ STEP 1 --------------------------------------------------


# driver1 = webdriver.Firefox()
driver1 = webdriver.Remote(command_executor=executor_url, desired_capabilities=capabilities)
driver1.get('http://google.com/')
url = driver1.command_executor._url       
print(driver1.command_executor._url)
print(driver1.session_id)
print(driver1.title)

# Serialize the session id in a file
session_id = driver1.session_id

# ------------------ END OF STEP 1 --------------------------------------------------

# Pass the session id from step 1 to step 2

# ------------------------ STEP 2 --------------------------------------------------
def attach_to_session(executor_url, session_id):
    original_execute = WebDriver.execute
    def new_command_execute(self, command, params=None):
        if command == "newSession":
            # Mock the response
            return {'success': 0, 'value': None, 'sessionId': session_id}
        else:
            return original_execute(self, command, params)
    
    # Patch the function before creating the driver object
    WebDriver.execute = new_command_execute

    temp_driver = webdriver.Remote(command_executor=executor_url)
    # Replace the patched function with original function
    WebDriver.execute = original_execute
    return temp_driver

# read the session id from the file
driver2 = attach_to_session(executor_url, session_id)
driver2.get('http://msn.com/')

print(driver2.command_executor._url)
print(driver2.session_id)

print(driver2.title)
driver2.close()

【问题讨论】:

  • 基本上,我正在使用 Ruby 编程语言寻找以下答案。 tarunlalwani.com/post/reusing-existing-browser-session-seleniumstackoverflow.com/questions/8344776/…
  • 您要附加浏览器吗?它实际上在 chrome 中是可能的,但在 Firefox 中是不可能的。
  • 大多数情况下你不能。我们不让它变得简单的原因是因为它很少是最好的解决方案。如果您可以执行您在示例中尝试执行的操作,驱动程序可能会认为它具有具有该 ID 的会话所没有的功能集。事情会很快变得丑陋。您需要从不同的 Ruby 进程访问相同的浏览会话的用例是什么?
  • @titusfortner:用例基本上是在运行不同的测试步骤时使用相同的浏览器会话。例如第 1 步 - 启动 Web 浏览器并导航到 URL,第 2 步将是单击页面中存在的特定链接。我在以下堆栈溢出链接stackoverflow.com/questions/8344776/… 中使用python 进行了这项工作。
  • 不同的测试步骤不应该需要不同的驱动程序会话。一个过程一个测试一个驱动程序会话。您应该能够在步骤之间将驱动程序作为实例变量传递。你用的是什么工具?

标签: ruby selenium-webdriver scripting


【解决方案1】:

我能够通过使用以下代码补丁解决此问题。

class RemoteWebDriver < Selenium::WebDriver::Driver
  def initialize(bridge)
    @bridge = bridge
  end
end

class RemoteBridge < Selenium::WebDriver::Remote::Bridge
  def self.handshake(**opts)
    capabilities = opts.delete(:desired_capabilities) { Capabilities.new }
    @session_id = opts.delete(:session_id)
    Selenium::WebDriver::Remote::W3C::Bridge.new(capabilities, @session_id, **opts)
  end
end

caps = Selenium::WebDriver::Remote::Capabilities.firefox()
remote_bridge = RemoteBridge.handshake(url: <YOUR_REMOTE_WEB_DRIVER_URL>, desired_capabilities: caps, session_id: <YOUR_SESSION_ID>)
remote_web_driver = RemoteWebDriver.new(remote_bridge)

【讨论】:

  • 像这样的猴子补丁是一种非常糟糕的做法,应该避免。一方面,使用此代码仅适用于这个特定版本的 Selenium。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 1970-01-01
  • 2014-11-29
  • 1970-01-01
相关资源
最近更新 更多