简体   繁体   English

如何在 capybara 中使用我自己的 cookie?

[英]How do I use my own cookies in capybara?

I'm trying to (ab)use the capybara web testing framework to automate some tasks on github that are not accessible via the github API and which require me to be logged in and click on buttons to send AJAX requests.我正在尝试(ab)使用 capybara web 测试框架来自动化 github 上的一些任务,这些任务无法通过 github API 访问,并且需要我登录并单击按钮以发送 AJAX 请求。

Since capybara/selenium is a testing framework it helpfully creates a temporary session which has no cookies in it.由于 capybara/selenium 是一个测试框架,它有助于创建一个没有 cookie 的临时会话。 I'd like to either stop it from doing that, or else I'd like to know how to load my cookie store into the browser session that it creates.我想阻止它这样做,或者我想知道如何将我的 cookie 存储加载到它创建的浏览器会话中。

All I'm trying to do is this:我要做的就是:

#!/usr/bin/env ruby

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome
driver.navigate.to "https://github.com"

Or this:或这个:

#!/usr/bin/env ruby

require 'capybara'

Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, :browser => :chrome)
end

session = Capybara::Session.new(:selenium)
session.visit "https://www.github.com"

In both cases I get the github.com landing page you'd see as a logged-out user or incognito mode in the browser.在这两种情况下,我都会获得 github.com 登录页面,您会在浏览器中看到作为注销用户或隐身模式。 I'd like to get my logged-in landing page like I just fired up a web browser myself and navigated to that URL.我想获得我的登录登录页面,就像我自己启动一个网络浏览器并导航到那个 URL 一样。

Since I have 2FA setup on github that makes automating the login process from the github landing page somewhat annoying, so I'd like to avoid automating logging into github.由于我在 github 上设置了 2FA,这使得从 github 登录页面自动登录过程有些烦人,所以我想避免自动登录 github。 The tasks that I want to automate do not require re-authenticating via 2FA.我想要自动化的任务不需要通过 2FA 重新验证。

ANSWER:回答:

For MacOSX+Ruby+Selenium this works:对于 MacOSX+Ruby+Selenium 这有效:

#!/usr/bin/env ruby

require 'selenium-webdriver'

caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"debuggerAddress" => "127.0.0.1:20480"}, detach: false)
driver = Selenium::WebDriver.for :chrome, :desired_capabilities => caps
driver.navigate.to "https://github.com"

Then fire up chrome with this:然后用这个启动chrome:

% /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=/Users/lamont/Library/Application\ Support/Google/Chrome --profile-directory=Default --remote-debugging-port=20480

Obviously the paths will need to be adjusted because they're OSX-centric and have my homedir in them.显然这些路径需要调整,因为它们以 OSX 为中心并且有我的 homedir。

There is also a bug in the selenium-webdriver gem for ruby where it inserts a 'detach' option which gets into a fight with 'debuggerAddress': ruby 的 selenium-webdriver gem 中还有一个错误,它插入了一个“分离”选项,该选项与“调试器地址”发生冲突:

/Users/lamont/.rvm/gems/ruby-2.2.4/gems/selenium-webdriver-2.53.0/lib/selenium/webdriver/remote/response.rb:70:in `assert_ok': unknown error: cannot parse capability: chromeOptions (Selenium::WebDriver::Error::UnknownError)
from unknown error: unrecognized chrome option: detach

The lib/selenium/webdriver/chrome/bridge.rb file can be edited to take that out as a quick hack:可以编辑lib/selenium/webdriver/chrome/bridge.rb文件以将其作为快速破解:

      chrome_options['binary']                   = Chrome.path if Chrome.path
      chrome_options['nativeEvents']             = true if native_events
      chrome_options['verbose']                  = true if verbose
      #chrome_options['detach']                   = detach.nil? || !!detach
      chrome_options['noWebsiteTestingDefaults'] = true if no_website_testing_defaults
      chrome_options['prefs']                    = prefs if prefs

To implement something similar in Ruby, check out this page that goes over that.要在 Ruby 中实现类似的东西,请查看该页面 Thanks to lamont for letting me know in the comments.感谢 lamont 在评论中让我知道。

You can start chrome using a specific Chrome profile.您可以使用特定的 Chrome 配置文件启动 chrome。 I am not sure what the ruby implementation would look like, but in python it looks something like:我不确定ruby​​ 实现会是什么样子,但在python中它看起来像:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options as ChromeOptions

options = ChromeOptions()
# more on this line here later.
options.add_experimental_option('debuggerAddress', '127.0.0.1:7878')
driver = webdriver.Chrome(chrome_options=otpions)

In order for this to work you need to do a few things.为了使它起作用,您需要做一些事情。

manually start chrome from terminal/command prompt with these command line arguments --user-data-dir=/path/to/any/custom/directory/home/user/Desktop/Chromedir --profile-directory="Profile 1" --remote-debugging-port=7878使用这些命令行参数从终端/命令提示符手动启动 chrome --user-data-dir=/path/to/any/custom/directory/home/user/Desktop/Chromedir --profile-directory="Profile 1" --remote-debugging-port=7878

  1. make sure "Profile 1" is already existing in the same --user-data-dir (make sure user Profile 1 has necessary chrome://components/ to run any apps that require those components)确保“配置文件 1”已存在于同一 --user-data-dir 中(确保用户配置文件 1 具有必要的 chrome://components/ 来运行需要这些组件的任何应用程序)
  2. you can use any free port in place of 7878 verify that http://localhost:7878 is running and returns value.您可以使用任何空闲端口代替 7878 验证http://localhost:7878是否正在运行并返回值。

This should manually launch chrome with the "Profile 1" profile, and so long as it has logged into the site in question, it will stay logged in like a normal user so long as you follow these instructions to run the tests.这应该使用"Profile 1"配置文件手动启动 chrome,只要它已登录到相关站点,只要您按照这些说明运行测试,它就会像普通用户一样保持登录状态。

I used this to write a quick netflix bot that clicks the "continue playing" button when it pops up, and it's the only way to get DRM content to play as far as I have found.我用它编写了一个快速的netflix 机器人,当它弹出时单击“继续播放”按钮,这是我发现的唯一可以播放 DRM 内容的方法。 But it retains the cookies for the login, and also launches chrome with whatever components the profile is set up to have.但它保留了用于登录的 cookie,并使用配置文件设置的任何组件启动 chrome。

I have tried launching chrome with specific profiles before using different methodologies, but this was the only way to really force it to work how I wanted it to.在使用不同的方法之前,我曾尝试使用特定配置文件启动 chrome,但这是真正强制它按我想要的方式工作的唯一方法。

Edit: There are methods for saving cookie info as well although I don't know how well they work.编辑:虽然我不知道它们的工作情况如何,但也有保存 cookie 信息的方法。 Check out this link for more info, as my solution is probably not the best solution even if it works.查看此链接以获取更多信息,因为我的解决方案可能不是最好的解决方案,即使它有效。

The show_me_the_cookies gem provides cross-driver cookie manipulation and can let you add new cookies. show_me_the_cookies gem 提供跨驱动程序 cookie 操作,可以让您添加新的 cookie。 The one thing to be aware of when using selenium is that you need to visit the domain before you can create cookie for it, so you'll need to do something like使用 selenium 时要注意的一件事是,您需要先访问域,然后才能为其创建 cookie,因此您需要执行类似的操作

visit "https://www.github.com"
create_cookie(...)
visit "https://www.github.com"

for it to work - first visit just puts the browser/driver in a state where you can create the cookie, second visit actually goes to the page with the cookies set.让它工作 - 第一次访问只是将浏览器/驱动程序置于可以创建 cookie 的状态,第二次访问实际上是转到设置了 cookie 的页面。

I had to tweak the OP's answer (from within her question) to get this going with Ruby in 2022.我不得不调整 OP 的答案(从她的问题中)以在 2022 年与 Ruby 一起实现这一点。

Prerequisites先决条件

Chromedriver installed and allowed to run even though it's not signed: Chromedriver 已安装并允许运行,即使它没有签名:

> brew install chromedriver
> xattr -d com.apple.quarantine /usr/local/bin/chromedriver

Chrome launched and accepting commands on a specific port: Chrome 在特定端口上启动并接受命令:

> /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --user-data-dir=~/Library/Application\ Support/Google/Chrome --profile-directory=Default --remote-debugging-port=20480

This created a new profile in Chrome so I signed in to my account and got the browser set up, ready to start interacting with the (legacy EdTech) site I'm trying to automate.这在 Chrome 中创建了一个新的配置文件,因此我登录了我的帐户并设置了浏览器,准备开始与我试图自动化的(旧版 EdTech)网站进行交互。

Actual use实际使用

require 'selenium-webdriver'

caps = Selenium::WebDriver::Remote::Capabilities.chrome("goog:chromeOptions" => {"debuggerAddress" => "127.0.0.1:20480"})
driver = Selenium::WebDriver.for :chrome, capabilities: caps

driver.navigate.to "https://www.google.com"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM