Jul*_*lie 3 ruby selenium selenium-chromedriver google-chrome-headless
我正在使用Capybara Selenium运行无头Chrome,这很好用,但我无法弄清楚如何使用远程调试。当我添加--remote-debugging-port=4444或--remote-debugging-port=9222或时--remote-debugging-port=9521,Selenium不再连接到浏览器以运行测试。
如何使远程调试工作?这是我的代码供参考:
Capybara.register_driver :selenium do |app|
# from https://github.com/SeleniumHQ/selenium/issues/3738
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: {browser: 'ALL'})
options = Selenium::WebDriver::Chrome::Options.new
options.add_argument '--disable-infobars' # hide info bar about chrome automating test
# if we don't use this flag, every selenium test will die with the error:
# "unknown error: Chrome failed to start: exited abnormally"
options.add_argument '--no-sandbox'
# BREAKS THINGS if uncommented
# options.add_argument '--remote-debugging-port=4444'
options.add_argument '--headless'
options.add_argument '--window-size=1600,2400'
options.add_preference('profile.default_content_settings.popups', 0)
options.add_preference('download.default_directory', DownloadHelpers::PATH.to_s)
Capybara::Selenium::Driver.new(
app,
clear_local_storage: true,
clear_session_storage: true,
browser: :chrome,
options: options,
desired_capabilities: capabilities,
)
end
Run Code Online (Sandbox Code Playgroud)
从chrome 67和chromedriver 2.39开始,chromedriver现在可以正确使用您指定的端口--remote-debugging-port。这从上面的回答中消除了很多麻烦。我现在采取的步骤(对于需要使用chrome_remote配置下载设置的用例)适用于以下情况:
它利用nodejs库crmux-允许多个客户端同时连接到chrome的远程调试端口。
npm install crmux -g之前您开始chromedriver( Capybara::Selenium::Driver.new),您需要spawn一个单独的线程会火起来crmux,这将让你和chromedriver通过港口铬本身传达你的水豚(4444)中规定:
crmux --port=4444 --listen=4444
您可能希望在主脚本/线程中sleep 3的spawn命令后添加一个,以便在继续测试启动之前给crmux启动时间。
然后,您可以使用chrome_remote(例如)在capybara进行操作时使用端口4444访问chrome 。
更新:如果使用 Chrome 67/chromedriver 2.39 之后的版本,我上面的替代答案提供了一个更简单的解决方案
这里的核心问题是 Chromedriver 还使用远程调试端口连接与 Chrome 进行通信。这使用了 websocket 协议,该协议仅支持一次连接一个客户端。通常,当chromedriver启动chromedriver进程时,它会选择一个随机的空闲TCP端口号并使用它来访问远程调试端口。但是,如果您指定--remote-debuggging-port=9222,Chrome 将使用您请求的调试端口打开,但 chromedriver 将默默地继续尝试使用此随机端口号打开连接。
我最终得到的解决方案很大程度上受到了chromedriver issues 中第 20 条评论的启发。它需要相当多的代码才能使其工作,但工作稳定。它使用了一个nodejs库crmux——它允许多个客户端同时连接到chrome的远程调试端口。
npm install crmux -gCapybara::Selenium::Driver.new,您需要spawn一个单独的线程来执行一些操作:查找 chromedriver 尝试用于连接到 chrome 的远程调试端口,然后使用它来启动crmux。一旦发生这种情况,水豚等就会正常工作。其代码是:
$chrdrv_wait_timeout = 60
$chrdrv_exe = "chromedriver.exe"
def get_netstat_output
stdout = `netstat -a -b -n`
stat_lines = stdout.split("\n")
stat_lines
end
def try_get_requested_port
socket_state = "SYN_SENT" # i.e. sent with no reply
statout = get_netstat_output
n = statout.length
i = 0
loop do
i += 1
# find lines relating to chromedriver
exe_match = /^ +\[#{$chrdrv_exe}\]$/.match statout[i]
if exe_match != nil
# check preceeding lines which should contain port info
port_match = /TCP.*:([0-9]+)\W+#{socket_state}/.match statout[i-1]
if port_match != nil
return port_match[1].to_i
end
end
break unless i < n
end
return nil
end
def get_tcp_port_requested_by_chromedriver
i = 1
loop do
puts "Waiting for #{$chrdrv_exe}: #{i}"
port = try_get_requested_port
if port != nil
return port
end
break unless i < $chrdrv_wait_timeout
sleep 1
i += 1
end
raise Exception, "Failed to get TCP port requested by #{$chrdrv_exe} (gave up after #{$chrdrv_wait_timeout} seconds)"
end
Run Code Online (Sandbox Code Playgroud)
(我在 Windows 中工作:对于 Mac/Linux,netstat 语法/输出可能不同,因此代码需要调整;关键是你需要它输出每个连接条目的可执行所有者- 并解析与chromedriver 获取有问题的端口)。
一旦找到随机端口(我将使用12225作为示例),后台 ruby 脚本就可以执行 crmux 进程,该进程将通过您在 Capybara 中指定的端口(4444)将 chromedriver 与 chrome 本身重新组合:
crmux --port=4444 --listen=12225
最后,这个单独的脚本将发现的侦听端口保存到文本文件中。这允许运行水豚的主脚本/线程知道它可以通过从该文件读取端口来访问 chrome(通过 crmux 的多路复用连接)的端口号。因此,您可以使用chrome_remote来使用端口12225访问 chrome ,例如,当水豚正在执行其操作时。
| 归档时间: |
|
| 查看次数: |
4082 次 |
| 最近记录: |