Selenium WebDriver实现两个程序操作同一个浏览器即操作之前已经打开的浏览器

背景

在使用Selenium WebDriver实现web自动化测试的过程中,有一个场景:需要在一个自动化用例中,操作其他用例已经打开的浏览器即接着上一个用例的操作,继续执行。

简述原理

Selenium Webdriver是使用server-client结构实现的,server端使用浏览器驱动程序来启动浏览器并且创建一个命令执行器,client端实现一个http的客户端与命令执行器通信,将按照selenium定义的格式的http请求和参数发送给命令执行器,命令执行器识别这些命令后对浏览器进行操作,而server的命令执行器和client之间的通信凭证就是sessionid

实现

使用python

from selenium import webdriver


driver = webdriver.Chrome()

print driver.command_exector._url
print driver.session_id

执行后,输出

http://127.0.0.1:23417             // 命令执行器的url
fe6fda53626f08b1cde42e76f05f47     // session id

此时,可以看到已经打开了一个浏览器,且我们的程序已经执行结束了。
接下来,在这个已经打开的浏览器里,打开 百度 的首页,使用postman 发送post请求
url: http://127.0.0.1:23417/session/fe6fda53626f08b1cde42e76f05f47/url
body json/application

{
     
   "url":"https://www.baidu.com"
}

发送请求后,可以看到在之前打开的浏览器上,已经打开了百度的首页。
至于别的操作,可以查看文档来发送对应的请求。
参考:https://www.w3.org/TR/webdriver/

改进

上面的方式,要求我们去查询文档,来发送相应请求来实现相应目的。这样工作量太大,太繁琐,不易维护。接下来我们从编码上直接去实现。

假设:已知 executor_url = “http://127.0.0.1:23417”
session_id = “fe6fda53626f08b1cde42e76f05f47”

使用python

from selenium import webdriver
​
executor = "http://127.0.0.1:23417"
session_id = "fe6fda53626f08b1cde42e76f05f47"
​
driver = webdriver.Remote(command_executor=executor , desired_capabilities={
     })
​
driver.session_id = session_id
​
print driver.current_url

执行之后,有的版本可以实现,有何版本能够重新连接上一个会话,但却打开了一个新的空白会话。
查看Remote类的源码,发现每次实例化都会调用start_session这个方法新建一个会话。

解决方法:集成并重现这个类,自定义一个ReuseChrome这个类重写start_session方法使它不再新建session,使用传入的session_id

from selenium.webdriver import Remote
from selenium.webdriver.chrome import options
from selenium.common.exceptions import InvalidArgumentException
​
class ReuseChrome(Remote):def __init__(self, command_executor, session_id):
       self.r_session_id = session_id
       Remote.__init__(self, command_executor=command_executor, desired_capabilities={
     })def start_session(self, capabilities, browser_profile=None):
       """
      重写start_session方法
      """
       if not isinstance(capabilities, dict):
           raise InvalidArgumentException("Capabilities must be a dictionary")
       if browser_profile:
           if "moz:firefoxOptions" in capabilities:
               capabilities["moz:firefoxOptions"]["profile"] = browser_profile.encoded
           else:
               capabilities.update({
     'firefox_profile': browser_profile.encoded})
​
       self.capabilities = options.Options().to_capabilities()
       self.session_id = self.r_session_id
       self.w3c = False
import ReuseChrome
​
driver = ReuseChrome(command_executor=executor_url, session_id=session_id)print(driver.current_url)

成功了!

你可能感兴趣的:(软件测试,自动化测试,测试工程师,selenium,python)