Enabling HTML5 cache manifest in Poltergeist/PhantomJS tests - ruby

My app is using HTML5 cache manifest file and caches several js/css/html files on the client side. We are having problems with Poltergeist testing - same tests run with Selenium pass. With Poltergeist the first test passes (the files are not yet cached) but the second and all the rest fail, the page is blank as if the cache is not working. I tried to enable the PhantomJS disk cache by passing options to Poltergeist, in test_helper.rb (Rails' Test::Unit) I declared the poltergeist driver as:
Capybara.register_driver :poltergeist do |app|
Capybara::Poltergeist::Driver.new(MyRailsAppName, { phantomjs_options: ['--disk-cache=true' ] } )
end
Capybara.javascript_driver = :poltergeist
But this doesn't help. Any ideas?
[edit]: don't know if this is relevant but when I pause the test in the failing run and manually visit the page with cached content with
visit '/mobile'
=> {"status"=>"fail"}
status is failing, but when I visit a non-cached page, it works.

Ok, so guys at PhantomJS are working on enabling localStorage support, it hasn't been merged yet.

Related

How to use ruby to scrape a react website from a remote linux server?

I want to scrape a react website using the ruby watir gem on a remote linux server but keep getting the following error:
/var/lib/gems/2.3.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/firefox/binary.rb:134:in
path': can't modify frozen String (RuntimeError) from
/var/lib/gems/2.3.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:45:in
firefox'
Here is my code:
require 'watir'
browser = Watir::Browser.new :firefox, headless: true
browser.goto("https://www.pinterest.com")
There is a similar question here but the links either return 404 or are archived and the code deprecated.
I need to login, then get a new page and push buttons on that page to download a report file for a date range.
You'll get that error if Firefox isn't installed, or isn't accessible on your path. Reinstall if you already have it.
Source: selenium/webdriver/firefox/binary.rb:134:in `path': can't modify frozen String (FrozenError)
So, you might want to use Firecast, a reinstall might help. In case you have a different browser, you could test with Chrome for instance.
Some more things to look at:
You might also need to install the right webdriver. You can also use https://github.com/titusfortner/webdrivers
I have got the same error as you posted, then I ran gem install webdrivers and used it in the code, also I switched to chrome:
require 'watir'
require 'webdrivers'
browser = Watir::Browser.new :chrome, headless: true
browser.goto("https://www.pinterest.com")
Finally, without webdrivers you get something like
C:/tools/ruby26/lib/ruby/gems/2.6.0/gems/selenium-webdriver-3.142.3/lib/selenium/webdriver/common/service.rb:136:in `binary_path': Unable to find chromedriver. Please download the server from (Selenium::WebDriver::Error::WebDriverError)
https://chromedriver.storage.googleapis.com/index.html and place it somewhere on your PATH.
More info at https://github.com/SeleniumHQ/selenium/wiki/ChromeDriver.
and with all set up correctly you might get something like (most likely related to Chrome):
DevTools listening on ws://127.0.0.1:57725/devtools/browser/34a42518-c3d9-4e14-af8e-9a137b11625b
[0808/012434.304:INFO:CONSOLE(0)] "The Content-Security-Policy directive 'prefetch-src' is implemented behind a flag which is currently disabled.
", source: https://www.pinterest.com/ (0)
[0808/012437.286:INFO:CONSOLE(240)] "No signed in Google accounts available - visit accounts.google.com to ensure that at least one account is signed in, otherwise no data will be returned from this API.", source: https://www.gstatic.com//mss/boq-identity//js/k=boq-identity.IdentityYoloWebModuleset.en_US.fUFh6X86RzU.es5.O/am=Aw/d=1/rs=AOaEmlH5BdY58S_qoulxSYv6tYMpThlVYw/m=yolo_frame_library (240)

Capybara with headless chrome doesn't clear session between test cases which use different subdomains

I switched my rails tests from capybara-webkit to headless chrome. When I run a test which visits not the default Capybara host the first case passes but the second one fails because the user are already logged in when they try to login
I use chromedriver v2.45, selenium-webdriver (3.141.0) and capybara (2.18.0)
I have the following setup:
require 'selenium-webdriver'
Capybara.register_driver :chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new(
args: %w[headless disable-gpu no-sandbox]
)
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
Capybara.javascript_driver = :chrome
I tried to change the app host to the default domain after visiting another domain
using_app_host("http://another.lvh.me") do
visit '/'
# do something
end
where using_app_host is
def using_app_host(host)
original_host = Capybara.app_host
Capybara.app_host = host
yield
ensure
Capybara.app_host = original_host
end
but it didn't help.
The spec structure looks the following way:
feature "Use another subdomain", js: true do
before { login } # use default Capybara app host http://root.lvh.me
scenario "case 1" do
using_app_host("http://another.lvh.me") do
# do something
end
end
scenario "case 2" do
using_app_host("http://another.lvh.me") do
# do something else
end
end
end
Any ideas why capybara/headless chrome doesn't clean the user session between the test cases when navigating to another domain?
Are you storing session information in the browsers window.localStorage and/or window.sessionStorage? If so you can set those to be cleared via options passed to the driver (Note: these settings are the default for the selenium driver in Capybara 3.12+)
Capybara.register_driver :chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new(args: %w[no-sandbox])
options.headless!
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options, clear_local_storage: true, clear_session_storage: true)
end
Even I was facing same issue.
After adding the steps to clear the cookies, session it is not working either. I added below code in env.rb to start a new session every time for a new test
May be you can try this.
Before do
Capybara.session_name = ":session_#{Time.zone.now.to_i}"
end
After do
Capybara.current_session.driver.quit
end
Also, you can add in chrome options to open the session in incognito window
I found this thread useful in a reverse context. I have a test setup wherein I'm storing session credentials in local storage. And so upgrading from capybara v3.11 to v3.12 broke the suite such that only the first scenario would pass and the rest of the scenarios would fail on the login page every time.
That's because the local storage was getting cleared based on the default behavior of capybara 3.12
I updated my suite to set clear_local_storage and clear_session_storage to false explicitly at time of registering the driver.
Capybara.register_driver :selenium_chrome do |app|
Capybara::Selenium::Driver.new(app,
browser: :chrome,
clear_local_storage: false,
clear_session_storage: false)

Blacklist URLs with headless Chrome

I'm trying to block URLs in my specs, achieving something like I had when using capybara_webkit:
Capybara::Webkit.configure do |config|
config.block_url("*google*")
config.allow_url('*my_website.com')
end
After reading this article, I tried to do something like:
require 'webmock/rspec'
module WebmockConfig
def self.default_disabled_urls
[
'*google*'
]
end
end
WebMock.disable_net_connect!(allow_localhost: true)
WebMock.disable_net_connect!(allow: WebmockConfig.default_disabled_urls)
but I'm getting
Real HTTP connections are disabled. Unregistered request: POST http://127.0.0.1/session
even if that should be solved by WebMock.disable_net_connect!(allow_localhost: true).
When running the specs without WebMock.disable_net_connect!(allow: WebmockConfig.default_disabled_urls), everything is working fine.
The capybara-webkit white/blacklisting affects the requests made by the browser, whereas WebMock can only affect requests made by your app. This means WebMock is useless for what you want since it wouldn't actually stop your browser from loading anything from google, etc. To do that while using the selenium driver you need to use a programmable proxy like puffing-billy which will allow you to customize the responses for any matching requests the browser makes.
To configure a driver using headless chrome and puffing_billy you could do something like
Capybara.register_driver :headless_chrome do |app|
browser_options = ::Selenium::WebDriver::Chrome::Options.new
browser_options.headless!
browser_options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
Capybara::Selenium::Driver.new(app, browser: :chrome, options: browser_options)
end
Whether or not you need any other options is dependent on your system config, etc but you should be able to tell by looking at your current driver registration.
The allow_localhost: true settings are overwritten by allow: WebmockConfig.default_disabled_urls you have to call WebMock.disable_net_connect! once with both settings or by adding 'localhost', '127.0.0.1' entries into self.default_disabled_urls

Exclude not working for Rack::SSL

I currently have a sinatra project that I am trying to add SSL to so I tried to add Rack::SSL which worked fine, but I'd like to have it disabled in development mode.
class Blog < Sinatra::Base
use Rack::SSL, :exclude => lambda { |env| ENV['RACK_ENV'] != 'production' }
...
This is the code I have and ENV['RACK_ENV'] is returning 'development' when I pry, but for some reason when I try to hit my site locally it's still trying to redirect to https.
I got caught out by this last week. Turns out I'd enabled HTTP Strict Transport Security (HSTS) too, which meant once a cookie for the site had been served over HTTPS the browser would prevent any future requests to the non-HTTPS version of the site.
Thought I'd mention it just incase you've got the same.
This works, chrome just had the redirect cached from before I added this so I thought it wasn't working. Worked fine in an incognito window.

Watir-webdriver doesnt store all cookies

When I goto the following link on firefox (V-12), the browser on my Ubuntu machine allows me to login normally.
https://r.espn.go.com/members/v3_1/login?language=en&forwardUrl=&appRedirect=http%3A%2F%2Fgames.espn.go.com
However, if I use watir-webdriver, I get the message: "Cookies must be enabled in order to login."
Here is the code to reproduce this issue with Watir:
require 'watir-webdriver'
browser = Watir::browser.new
browser.goto "https://r.espn.go.com/members/v3_1/login?language=en&forwardUrl=&appRedirect=http%3A%2F%2Fgames.espn.go.com"
You will notice that the browser displays the "Cookies must be enabled" error message below the "email address or member name" field. When I looked at the cookies stored, I noticed that not all cookies that were stored in the normal mode are available. I compared this by searching for "go.com" in the stored cookies.
Any idea what would cause the discrepancy in cookies stored between the two modes, using the same browser?
Thanks!
There is no problem or discrepancy with watir-webdriver. What is happening here is a result of how the website is coded.
The page you are accessing (https://r.espn.go.com/members/v3_1/login?language=en&forwardUrl=&appRedirect=http%3A%2F%2Fgames.espn.go.com) is intended to be an overlay on http://espn.go.com. Whoever coded the site assumed that the overlay page would always be accessed after a hit to the main page. So, the main page (http://espn.go.com) sets a cookie in order to test whether your user agent has cookies enabled. The overlay page with the sign in form then checks to see if the test cookie is present and, if not, displays the warning you are seeing.
What is important to understand is that watir-webdriver defaults to a clean profile for each new browser instance. This means that the browser does not have any of your cookies, extensions, preferences or browsing history. Because the clean profile has never visited http://espn.go.com to receive the test cookie, the warning is being displayed.
There are two ways to avoid this warning:
You can visit the main page prior to the sign-in page, like so:
require 'watir-webdriver'
browser = Watir::Browser.new
browser.goto "espn.go.com"
browser.goto "https://r.espn.go.com/members/v3_1/login?language=en&forwardUrl=&appRedirect=http%3A%2F%2Fgames.espn.go.com"
Or, you can use your default Firefox profile, which (presumably) already has the test cookie:
require 'watir-webdriver'
browser = Watir::Browser.new :firefox, :profile => "default"
browser.goto "https://r.espn.go.com/members/v3_1/login?language=en&forwardUrl=&appRedirect=http%3A%2F%2Fgames.espn.go.com"
Hope that helps!

Resources