Code Monkey home page Code Monkey logo

apparition's Introduction

Apparition - A Chrome driver for Capybara

Build Status

Apparition is a driver for Capybara. It allows you to run your Capybara tests in the Chrome browser via CDP (no selenium or chromedriver needed) in a headless or headed configuration. It started as a fork of Poltergeist and attempts to maintain as much compatibility with the Poltergeist API as possible. Implementing the capybara-webkit specific driver methods has also begun.

Getting help

Questions should be posted on Stack Overflow, using the 'capybara' tag and mentioning you are using the apparition driver.

Bug reports should be posted on GitHub (and be sure to read the bug reporting guidance below).

Installation

Add either

gem 'apparition'

or

gem 'apparition', github: 'twalpole/apparition'

to your Gemfile and run bundle install.

In your test setup add:

require 'capybara/apparition'
Capybara.javascript_driver = :apparition

If you were previously using the :rack_test driver, be aware that your app will now run in a separate thread and this can have consequences for transactional tests. See the Capybara README for more detail.

What's supported?

Apparition supports all Capybara features, and the following extended features:

  • page.status_code
  • page.response_headers
  • page.driver.render_base64(format, options)
  • page.driver.scroll_to(left, top)
  • page.driver.basic_authorize(user, password)
  • page.driver.set_proxy(host, port, type, user, password, bypass: [bypass list passed to chrome])
  • cookie handling
  • extra headers

There are some additional features:

Taking screenshots with some extensions

You can grab screenshots of the page at any point by calling save_screenshot('/path/to/file.png').

By default, only the viewport will be rendered (the part of the page that is in view). To render the entire page, use save_screenshot('/path/to/file.png', full: true).

You also have an ability to render selected element. Pass option selector with any valid CSS element selector to make a screenshot bounded by that element save_screenshot('/path/to/file.png', selector: '#id').

If the desired image format is not identifiable from the filename passed you can also pass in a format: option with accepable values being :png or :jpeg

If, for some reason, you need a base64 encoded screenshot you can simply call render_base64 which will return your encoded image. Additional options are the same as for save_screenshot.

Clicking precise coordinates

Sometimes its desirable to click a very specific area of the screen. You can accomplish this with page.driver.click(x, y), where x and y are the screen coordinates.

Remote debugging (not yet implemented)

If you use the :inspector => true option (see below), remote debugging will be enabled.

When this option is enabled, you can insert page.driver.debug into your tests to pause the test and launch a browser which gives you the WebKit inspector to view your test run with.

You can register this debugger driver with a different name and set it as the current javascript driver. By example, in your helper file:

Capybara.register_driver :apparition_debug do |app|
  Capybara::Apparition::Driver.new(app, :inspector => true)
end
# Capybara.javascript_driver = :apparition
Capybara.javascript_driver = :apparition_debug

Read more here

Manipulating request headers

You can manipulate HTTP request headers with these methods:

page.driver.headers # => {}
page.driver.headers = { "User-Agent" => "Apparition" }
page.driver.add_headers("Referer" => "https://example.com")
page.driver.headers # => { "User-Agent" => "Apparition", "Referer" => "https://example.com" }

Notice that headers= will overwrite already set headers. You should use add_headers if you want to add a few more. These headers will apply to all subsequent HTTP requests (including requests for assets, AJAX, etc). They will be automatically cleared at the end of the test. You have ability to set headers only for the initial request:

page.driver.headers = { "User-Agent" => "Apparition" }
page.driver.add_header("Referer", "http://example.com", permanent: false)
page.driver.headers # => { "User-Agent" => "Apparition", "Referer" => "http://example.com" }
visit(login_path)
page.driver.headers # => { "User-Agent" => "Apparition" }

This way your temporary headers will be sent only for the initial request, and related 30x redirects. All subsequent request will only contain your permanent headers. If the temporary headers should not be sent on related 30x redirects, specify permanent: :no_redirect.

Inspecting network traffic

You can inspect the network traffic (i.e. what resources have been loaded) on the current page by calling page.driver.network_traffic. This returns an array of request objects. A request object has a response_parts method containing data about the response chunks.

You can inspect requests that were blocked by a whitelist or blacklist by calling page.driver.network_traffic(:blocked). This returns an array of request objects. The response_parts portion of these requests will always be empty.

Please note that network traffic is not cleared when you visit new page. You can manually clear the network traffic by calling page.driver.clear_network_traffic or page.driver.reset

Manipulating cookies

The following methods are used to inspect and manipulate cookies:

  • page.driver.cookies - a hash of cookies accessible to the current page. The keys are cookie names. The values are Cookie objects, with the following methods: name, value, domain, path, secure?, httponly?, samesite, expires.
  • page.driver.set_cookie(name, value, options = {}) - set a cookie. The options hash can take the following keys: :domain, :path, :secure, :httponly, :samesite, :expires. :expires should be a Time object.
  • page.driver.remove_cookie(name) - remove a cookie
  • page.driver.clear_cookies - clear all cookies

Customization

You can customize the way that Capybara sets up Apparition via the following code in your test setup:

Capybara.register_driver :apparition do |app|
  Capybara::Apparition::Driver.new(app, options)
end

options is a hash of options. The following options are supported:

  • :headless (Boolean) - When false, run the browser visibly
  • :remote (Boolean) - When true, connect to remote browser instead of starting locally (see [below](#Remote Chrome Driver))
  • :debug (Boolean) - When true, debug output is logged to STDERR.
  • :logger (Ruby logger object or any object responding to puts) - When present, debug output is written to this object
  • :browser_logger (IO object) - This is where your console.log statements will show up. Default: STDOUT
  • :timeout (Numeric) - The number of seconds we'll wait for a response when communicating with Chrome. Default is 30.
  • :inspector (Boolean, String) - See 'Remote Debugging', above.
  • :js_errors (Boolean) - When false, JavaScript errors do not get re-raised in Ruby.
  • :window_size (Array) - The dimensions of the browser window in which to test, expressed as a 2-element array, e.g. [1024, 768]. Default: [1024, 768]
  • :screen_size (Array) - The dimensions the window size will be set to when Window#maximize is called in headless mode. Expressed as a 2-element array, e.g. [1600, 1200]. Default: [1366, 768]
  • :extensions (Array) - An array of JS files to be preloaded into the browser. Useful for faking or mocking APIs.
  • :url_blacklist (Array) - Default session url blacklist - expressed as an array of strings to match against requested URLs.
  • :url_whitelist (Array) - Default session url whitelist - expressed as an array of strings to match against requested URLs.
  • :ignore_https_errors (Boolean) - Ignore certificate errors when connecting to https URLs.
  • :browser_options (Hash) - Extra command line options to pass to Chrome when starting
  • :skip_image_loading (Boolean) - Don't load images

Remote Chrome Driver

Apparition can connect to already running instance of chrome. Remote mode is useful when running tests in CI and chrome is available as separate docker container.

In order to use remote browser - set up apparition in the following way:

Capybara.register_driver :apparition do |app|
  browser_options = { 'remote-debugging-address' => '127.0.0.1', 'remote-debugging-port' => 9999 }
  Capybara::Apparition::Driver.new(app, remote: true, browser_options: browser_options)
end

Linux Server Configuration

In order to use Apparition on a Linux server, you need to install the chrome binary and set certain :browser_options.

Install Chrome
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -f ./google-chrome-stable_current_amd64.deb

Browser Options

Capybara.register_driver :apparition do |app|
  Capybara::Apparition::Driver.new(app, browser_options: { 'no-sandbox' => nil, 'disable-web-security' => nil, 'disable-features' => 'VizDisplayCompositor' })
end

This will enable your scripts to visit remote websites.

URL Blacklisting & Whitelisting

Apparition supports URL blacklisting, which allows you to prevent scripts from running on designated domains:

page.driver.browser.url_blacklist = ['http://www.example.com']

and also URL whitelisting, which allows scripts to only run on designated domains:

page.driver.browser.url_whitelist = ['http://www.example.com']

If you are experiencing slower run times, consider creating a URL whitelist of domains that are essential or a blacklist of domains that are not essential, such as ad networks or analytics, to your testing environment.

Emulating a mobile device

Desktop Chrome often won't let you set the window width narrower than 500px without also enabling mobile emulation, even when Chrome appears to accept the width.

To test with mobile widths, it's necessary to enable mobile emulation via CDP with all the required parameters.

nexus_5_metrics = {
  mobile: true,
  screenWidth: 412,
  screenHeight: 660,
  width: 412,
  height: 660,
  positionX: 0,
  positionY: 0,

  scale: 1,
  deviceScaleFactor: 2.625,
  screenOrientation: {
    angle: 0,
    type: "portraitPrimary",
  },
}

page.driver.browser.current_page.command(
  "Emulation.setDeviceMetricsOverride",
  **nexus_5_metrics,
)

page.driver.browser.current_page.command(
  "Emulation.setTouchEmulationEnabled",
  { enabled: true },
)

These settings put Chrome in mobile emulation mode in the same fashion as enabling the emulation mode from the developer tools.

Timing problems

Sometimes tests pass and fail sporadically. This is often because there is some problem synchronising events properly. It's often straightforward to verify this by adding sleep statements into your test to allow sufficient time for the page to settle.

If you have these types of problems, read through the Capybara documentation on asynchronous JavaScript which explains the tools that Capybara provides for dealing with this.

Filing a bug

If you can provide specific steps to reproduce your problem, or have specific information that might help track down the problem, then please file a bug on Github.

Include as much information as possible. For example:

  • Specific steps to reproduce where possible (failing tests are even better)
  • The output obtained from running Apparition with :debug turned on or ENV['DEBUG'] set
  • Screenshots
  • Stack traces if there are any Ruby on JavaScript exceptions generated
  • The Apparition, Capybara, and Chrome version numbers used
  • The operating system name and version used

Changes

Version history and a list of next-release features and fixes can be found in the changelog.

License

Copyright (c) 2019 Thomas Walpole

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

apparition's People

Contributors

ajjahn avatar baffers avatar coreyhaines avatar dabrowt1 avatar geoffharcourt avatar jordanfbrown avatar ridiculous avatar shiftyp avatar skyeagle avatar stelmashchuk avatar titusfortner avatar tricknotes avatar twalpole avatar volodymyr-mykhailyk avatar y-yagi avatar zealot128 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apparition's Issues

Node#click is flaky?

When I tried this Gem with the example spec below, Apprition driver passes only 8/10 where capybara selenium driver passes 10/10.

RSpec.describe 'github search' do
  around do |example|
    prev_host = Capybara.app_host
    Capybara.app_host = 'https://github.com'
    begin
      example.run
    ensure
      Capybara.app_host = prev_host
    end
  end

  10.times { # repeat and repeat and repeat...!!
  it 'should search repository' do
    visit '/'

    fill_in('q', with: 'selenium')
    find('a[data-item-type="global_search"]').click

    output = all('.repo-list-item').map do |li|
      li.all('a').first.text
    end
    puts output
    expect(output).to include(match(/selenium/i))
  end
  }

end
Failures:

  1) github search should search repository
     Failure/Error: find('a[data-item-type="global_search"]').click
     
     Capybara::ElementNotFound:
       Unable to find visible css "a[data-item-type=\"global_search\"]"
     # ./spec/feature/github_search_spec.rb:44:in `block (2 levels) in <top (required)>'
     # ./spec/feature/github_search_spec.rb:8:in `block (2 levels) in <top (required)>'

  2) github search should search repository
     Failure/Error: find('a[data-item-type="global_search"]').click
     
     Capybara::ElementNotFound:
       Unable to find visible css "a[data-item-type=\"global_search\"]"
     # ./spec/feature/github_search_spec.rb:70:in `block (2 levels) in <top (required)>'
     # ./spec/feature/github_search_spec.rb:8:in `block (2 levels) in <top (required)>'

The link is shown only during the text field is focused.

image

Using `.option_select` causes test to never finish

Hello, I tried invoking .option_select on an <option> node - while it worked, there was a side effect of the chrome window never closing and the test never moving on to the next test despite all of the code in the test being finished.

Removing the call to .option_select fixed the issue, however, I was not able to programmatically select it using the capybara driver. I was able to select my option via bootstrap-select methods (see block below), mostly because my use case is a bootstrap-select enabled select field that maps customer names to their id in the database. I need to make a call to that library anyway, pretty much... however I did in earnest try to use .select_option.

Complicating this matter is that the option was/is invisible due to using bootstrap-select.

This happens if I use headless and if I don't use headless.

My code:

    def self.set_select(page, desired_value, selectpicker_css_selector)
      # <select ... >
      select_element = page.find(selectpicker_css_selector, visible: :all)
      option = select_element.find('option', text: desired_value, visible: :all)

      # If I was able to use this line, I could then use select_element.value() instead of option.value().
      # However, enabling this line below causes the test to never finish.
      # option.select_option 

      sleep 2
      script = "$('#{selectpicker_css_selector}').selectpicker('val', '#{option.value}')"
      page.execute_script(script)
    end

Errno::ECONNREFUSED:Connection refused

Getting exception Errno::ECONNREFUSED:Connection refused - connect(2) for "127.0.0.1" port 55031 when running RSPEC examples with Capybara using Apparition driver. Selenium works just fine. Port changes with each run, fails the same way.

Ubuntu 18.04 WSL 1
ChromeDriver 81.0.4044.138

fill_in slower?

Is there a way to get fill_in to type more slowly? I have a form that uses some javascript form Stripe to verify credit card checksums or whatever it does and that seems to be slow enough that numbers are skipped when filling in that field.

fill_in "cc-number", with: "4242424242424242"

image
Notice the repeated 4s when the literal is all alternating.

When running in not-headless, it doesn't fail, I guess because actually rendering the input is slow enough, whereas in headless it can go faster.

In the meantime I've worked around this by making a helper that cheats by directly setting the value property, but I'm wondering if there is another way that would be "better"?

  def cheat_fill_in(id, opts)
    page.driver.evaluate_script "document.getElementById('#{id}').value = '#{opts[:with]}'"
  end

Capybara `fill_in` does not trigger `blur` event

This caused some specs to stop working after moving from Poltergeist to Apparition.

I'm not sure if it's sensible or not for fill_in to trigger the blur event, but if this lib aims to be drop-in compatible with Poltergeist, maybe it's worth considering.

I fixed it by adding and using this method:

def fill_in_then_blur(field_name, value)
  fill_in field_name, with: value

  # Trigger a JS blur event.
  find("body").click
end

Does not submit empty form parameters

Hi!

I've got this GET form, submitted via Turbolinks: https://auctionet.com/search/start_for_apps

I checked in Chrome, an iOS web view and Firefox – they all include empty params in the URL if I search for "foo" and leave the other fields at their default values. E.g. "…query=foo&category_id=&…".

But Apparition does not. The path will be just "/search?utf8=%E2%9C%93&is=&q=foo", without those extra params.

This recently meant a bug slipped through into production that would have been caught in tests if they had included these empty params, too.

I don't know what browser specs say about this, but I thought I'd raise it as a potential issue, anyway :)

Capybara::Apparition::CDPError Invalid parameters

Hello there! Thanks for your work on this gem.

I'm running into an issue intermittently when trying to click on an element in an RSpec spec. Using debugger I was able to get more details about the error.

Here's the error that I get via rspec:

  1) The description of our spec :)
     Failure/Error: super

     Capybara::Apparition::CDPError:
       Invalid parameters
     # ./spec/support/capybara_patches.rb:20:in `synchronize'
     # ./spec/features/our_spec.rb:292:in `block (4 levels) in <top (required)>'
     # ./spec/features/our_spec.rb:291:in `block (3 levels) in <top (required)>'
     # ./spec/features/our_spec.rb:133:in `block (3 levels) in <top (required)>'
     # ./spec/support/database_cleaner.rb:38:in `block (2 levels) in <main>'

Not very helpful, haha. But I added a debugger call to the Apparition gem, and was able to get some more details:

[10, 19] in /Users/me/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/response.rb
   10:       end
   11:
   12:       def result
   13:         response = @msg_ids.map do |id|
   14:           resp = @client.send(:wait_for_msg_response, id)
=> 15:           handle_error(resp['error']) if resp['error']
   16:           resp
   17:         end.last
   18:         puts "Processed msg: #{@msg_ids.last} in #{Time.now - @send_time} seconds" if ENV['DEBUG'] == 'V'
   19:
(byebug) resp
{"id"=>5713, "error"=>{"code"=>-32602, "message"=>"Invalid parameters", "data"=>"Failed to deserialize params.y - BINDINGS: double value expected at position 57"}}
(byebug) up

[8, 17] in /Users/me/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/response.rb
    8:         @msg_ids = msg_ids
    9:         @client = client
   10:       end
   11:
   12:       def result
=> 13:         response = @msg_ids.map do |id|
   14:           resp = @client.send(:wait_for_msg_response, id)
   15:           handle_error(resp['error']) if resp['error']
   16:           resp
   17:         end.last
(byebug) up

[360, 369] in /Users/me/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/apparition-0.5.0/lib/capybara/apparition/page.rb
   360:       wait_for_loaded
   361:       _raw_evaluate('document.title')
   362:     end
   363:
   364:     def command(name, **params)
=> 365:       @browser.command_for_session(@session.session_id, name, params).result
   366:     end
   367:
   368:     def async_command(name, **params)
   369:       @browser.command_for_session(@session.session_id, name, **params).discard_result
(byebug) name
"Input.dispatchMouseEvent"
(byebug) params
{:type=>"mouseMoved", :button=>"none", :buttons=>0, :x=>975.46875, :y=>0.377334671020507825e3, :modifiers=>0, :clickCount=>1}
(byebug) params[:y]
0.377334671020507825e3
(byebug) params[:y].class
BigDecimal
(byebug) params[:x].class
Float
(byebug)

So it looks like the error details are:

"error"=>{"code"=>-32602, "message"=>"Invalid parameters", "data"=>"Failed to deserialize params.y - BINDINGS: double value expected at position 57"}

I guess somehow the y value of 0.377334671020507825e3 (which is a Ruby BigDecimal) is not able to be deserialized by CDP? Does that seem right?

I wonder if rounding that to the closest integer would help? Is there any reason to keep the decimal version of the coordinates when firing mouse events?

Unexpected inner loop exception: missing keyword: has_browser_handler:

Hello! Thanks for your work on this gem.

I'm working on getting my project running on CircleCI and I'm running into this exception. I saw this closed issue (#18) for a similar exception message, but in my case I believe it has to do with a dialog because the trace points to handling the Page.javascriptDialogOpening event.

There seems to be a required keyword argument here, has_browser_handler: which I'd guess is not being passed to Ruby (?):

@session.on 'Page.javascriptDialogOpening' do |type:, message:, has_browser_handler:, **params|
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/page.rb:428:in `block in register_event_handlers'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:211:in `block in process_handlers'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:207:in `each'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:207:in `process_handlers'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:185:in `block in process_messages'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:175:in `loop'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:175:in `process_messages'
/home/circleci/project/vendor/bundle/ruby/2.4.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:217:in `block in start_threads'

Any suggestions?

Page#wait_for_loaded not reliable?

Background

I use Apparition to automatically detect the presence of certain JavaScript frameworks on different websites. Basically, I load the site (using #visit), and then I run a script (using #evaluate_script) that tries to obtain the version number (for instance, jQuery.fn.jquery would return the jQuery version on a page that has jQuery installed).

Issue

I've noticed that this method is not always reliable. Specifically, I can sometimes re-run the same script (on a site where jQuery is present) up to three times and get different results each time (either a JavascriptError, nil, or the expected result).

Discussion

I've looked around the source code and noticed that Apparition tries to detect page load by periodically attempting to run JavaScript (in Page#wait_for_loaded), and when it succeed, it assumes the page is loaded.

Before using Apparition, I've used the ChromeRemote gem to interface with Chrome, but for many reasons, Capybara with Apparition seems preferable. However, using the other gem, I was able to detect page loads more reliably by listening for the Page.loadEventFired event.

I'm curious as to why Apparition does not use this approach, especially since a comment in Page#wait_for_loaded seems to indicate that it is known that the current method is not reliable?

[feature request] Support more structured logging from the browser

In our application, we have a bunch of junk messages from third-party components that we can't turn off.

Sample
info: %cDownload the React DevTools for a better development experience: https://fb.me/react-devtools font-weight:bold
warning: Warning: componentWillMount has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.
 

 
* Move code with side effects to componentDidMount, and set initial state in the constructor.
 
* Rename componentWillMount to UNSAFE_componentWillMount to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

For our Selenium tests, we have a bit of glue code to get the browser logs and clean the things we don't care about:

errors = page.driver.browser.manage.logs.get(:browser)
errors.reject! { |e| e.message.include? 'React DevTools' }
errors.reject! { |e| e.message.match? REACT_DEPRECATED_WARNING }

The Apparition documentation states that the way to control output from console.* statements is via browser_logger, much the same as Poltergeist:

:browser_logger (IO object) - This is where your console.log statements will show up. Default: STDOUT

Unfortunately, by being IO-based, it becomes difficult to perform any filtering. For example, the write call might include data unrelated to the target message or the target message might be split into multiple calls.

Examples
write: "this is a very important message\nAnd this is a different one from React DevTools"
write: "React "
write: "DevTools"

Would it be possible to transfer these browser messages in a more structured manner so that they are easier to work with?

Hang with JRuby

Currently the apparition driver hangs with JRuby when starting Chrome

Capybara::Apparition::WrongWorld when waiting for a page to redirect

First time using this instead of any other JS drivers, so thanks for the framework and exciting!

I'm trying to write a test for a Stripe checkout.js page (subscribing to a plan) and get intermittent failures. I'm trying to use capybara matchers that wait for the page to change before asserting that things happen. I haven't tried with a chromedriver based setup yet, but I imagine it will work.

For the script below, a sleep will cause capybara to wait and the assertions work. If I try to use the content changing on the page (content or css) then it fails intermittently. It appears the page object is stale while the redirect is happening?

Any thoughts or recommendations?

require 'rails_helper'

RSpec.feature 'Subscriptions' do
  let(:user) { create(:user) }

  background do
    login_user(user)
  end

  context 'as a new customer' do
    background do
      visit organization_path
    end

    scenario 'I can subscribe', js: true do
      click_link 'Subscribe Now'

      expect do
        within 'form.new_pay_subscription' do
          select 'Freelancer Plan', from: 'Subscription Plan'
          fill_in 'Name on Card', with: 'Johnny Appleseed'
          fill_stripe_elements(card: '4111 1111 1111 1111') # stripe elements for interacting with iframe contents

          click_link_or_button 'Create Subscription'
        end

        # ----HERE----
        #
        # If I simply sleep after the button is clicked, enough time is given for the
        # page to redirect and my assertions below pass.
        #
        # If I am a "good" capybara dev and wait for visual or DOM changes to indicate my
        # operation has completed instead, I get failures.  I have tried several with the same outcome.
        #

        # WORKS, not ideal obviously and brittle
        # sleep 2 

        # all of the following will fail and raise an exception about being in the wrong world
        # they are not consistent about failing with this error.  I'm assuming that the faster the operation
        # completes and the page moves one (without the sleep of course) that the failure occurrs. 

        # expect(page).to have_no_css('form.new_pay_subscription')
        # expect(page).to_not have_css('form.new_pay_subscription')
        # expect(page).to have_current_path(after_registration_path)

      end.to change { user.organization.subscriptions.count }.by(1)
    end
  end

Unable to get all cookies

page.driver.cookies does not give me cookies as described in the readme. I see that it returns a CookieJar which initialises as the browser. I see there are tests for the cookie functions but not one for getting all cookies. I'm just migrating from Poltergeist and using ShowMeTheCookie (I forked it to create apparition adapter), and encountered this issue. Perhaps I'm misunderstanding something but it seems to be missing here?

property(:validity) is always nil

When using a Selenium driver, I'm able to check the validity state of an input with element.native.property(:validity). But with Apparition driver, property(:validity) always returns nil. Why is that? And can it be fixed?

Example

As an example, I have an input in my tests that I wanted to test transitioned from "valid"=>false to "valid"=>true after changing the input in a certain way.

This is what it returned when it was invalid:

element.native.property(:validity)={"badInput"=>false, "customError"=>false, "patternMismatch"=>false, "rangeOverflow"=>false, "rangeUnderflow"=>false, "stepMismatch"=>false, "tooLong"=>false, "tooShort"=>false, "typeMismatch"=>false, "valid"=>false, "valueMissing"=>true}

This is what it returned when it was invalid:

element.native.property(:validity)={"badInput"=>false, "customError"=>false, "patternMismatch"=>false, "rangeOverflow"=>false, "rangeUnderflow"=>false, "stepMismatch"=>false, "tooLong"=>false, "tooShort"=>false, "typeMismatch"=>false, "valid"=>true, "valueMissing"=>false}    

I can't figure out how to do this with apparition since it always returns nil.

validationMessage property is available

Interestingly, I noticed that the validationMessage property is available for the same element, so as a workaround I was able to check whether validationMessage was present? or not (seems to return "" when input is valid).

I'm curious why apparition has is able to get validationMessage but not validity. In the developer tools console, you can see that the validity property does exist and is not null.

Some related test helpers

  def element_validity(element)
    element.native.property(:validity).with_indifferent_access
  end

  def element_validitation_message(element)
    element.native.property(:validationMessage)
  end

  def element_valid?(element)
    if selenium?
      element_validity(element)[:valid]
    else
      element_validitation_message(element).blank?
    end
  end

  def expect_invalid(element)
    #expect_validity_match(element, valid: false)
    expect(element_valid?(element)).to eq false
  end

  def expect_valid(element)
    #expect_validity_match(element, valid: true)
    expect(element_valid?(element)).to eq true
  end

  def expect_validity_match(element, expected)
    raise NotImplementedError unless selenium?
    expect(element_validity(element)).to include expected
  end

Filling the "ß" Character causes Error

Hey there, thanks for your project 👍
I ran into an issue when filling the german letter ß. The error shown by rspec is

Failure/Error: fill_in "Street", with: "Retourestraße"

Capybara::Apparition::KeyError:
       Unknown key: ß

The screenshot generated shows that fill_in successfully filled every character until the ß:
Screen Shot 2019-03-21 at 16 09 58
This happens in any spec where we use this character and it also happens for other german special characters like ü.
Here is the stacktrace from the point where fill_in is called with that character:

     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:106:in `key_description'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:22:in `press'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:76:in `block (2 levels) in type_with_modifiers'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:75:in `each_char'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:75:in `block in type_with_modifiers'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:72:in `each'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:72:in `type_with_modifiers'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/page/keyboard.rb:14:in `type'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/node.rb:238:in `send_keys'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/node.rb:432:in `set_text'
     # ./vendor/bundle/ruby/2.5.0/gems/apparition-0.1.0/lib/capybara/apparition/node.rb:121:in `set'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/node/element.rb:119:in `block in set'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/node/base.rb:83:in `synchronize'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/node/element.rb:119:in `set'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/node/actions.rb:90:in `fill_in'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/session.rb:744:in `block (2 levels) in <class:Session>'
     # ./vendor/bundle/ruby/2.5.0/gems/capybara-3.14.0/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
     # ./spec/features/some_spec:120:in `fill_in_address'

Versions:
apparition: 0.1.0 and 1f57ba0
capybara: 3.14.0
chrome: 73.0.3683.67 (Official Build) beta (64-bit)
OS: MacOS 10.14.3 (18D109)

The same specs run fine with selenium and chromedriver-helper. Thanks for any help 👍

Capybara::Apparition::WrongWorld error when trying to evaluate script

Thank you for the great project! We just converted our test suite (2,500 feature tests) from chromedriver and were able to uncover a bunch of real bugs in our product.

We have a couple of hacks that have emerged over time, one of which evaluates some Javascript and jQuery to make assertions about pending AJAX calls. The first part of that check looks like:

page.evaluate_script('window.jQuery != undefined')

However, that line is sometimes throwing an error:

Failure/Error: page.evaluate_script('window.jQuery != undefined')

Capybara::Apparition::WrongWorld:
  The element you are trying to access is not from the current page

Do you have any insight into why we would see an error like that just using page.evaluate_script, since it doesn't appear to be accessing an element at all?

Also, worth nothing that this error happens inconsistently. Maybe it has to do with the page refreshing?

Ruby 2.3 support?

Thanks for this new project, which I'm eager to try in replacement of poltergeist!

I tried installing it on a legacy codebase, still on Ruby 2.3, and I wondered why it required 2.4+? Are there specific features of Ruby that you really need, or is it in anticipation of the fact that 2.3 is EOL in 2 months?

(I can always fork in the mean time, but since apparition is likely to change a bit these days, it would be easier to just target your repo directly!).

Thanks for your feedback!

"set_proxy" doesn't seem to have an effect for external resources

An existing app of mine uses puffing-billy to stub out XHR/JSONP external calls (e.g. Stripe/Recurly) for payments.

When using poltergeist (my "legacy" driver), I'm able to define stubs in puffing-billy, and the calls made by the browser to these external resources will then be returned as defined by the stubs.

This allows completely isolated yet "full integration" testing of payments scenarios.

When trying out apparition (but this same issue happens with cuprite), setting the proxy to puffing-billy works fine, I believe, for all localhost calls.

But the external resources, which I normally stub out, are not stubbed out, resulting in real calls.

It's like if the proxy has a bypass for those external resources, for some reason.

I don't have a small reproduction yet, but I can try making one (unless someone is faster than me!).

Ajax request returns empty string

Changing an old project from PhantomJS to Apparition.

We're seeing a failing test in Apparition where an Ajax request often returns an empty-string success response instead of a JSON success response. But sometimes returns the correct response.

It passes with PhantomJS, and the code works in Chrome in development.

We stripped the problematic spec down to something smaller:

it "foo", :js do
  visit root_path
  sleep 1  # Ensure jQuery has loaded
  click_link "My foo link"
  expect(page).to have_content("AJAX done")
end

The link is:

<a class="js-foo" href="#">My foo link</a>

With some jQuery code in CoffeeScript:

$ ->

  $(".js-foo").click (e) ->
    e.preventDefault()
    console.log("clicked")
    $.get
      url: "/foo"
      success: (a,b,c) ->
        console.log("GET success via jQuery", JSON.stringify(a),JSON.stringify(b), JSON.stringify(c))
        $(document.body).append("<p>AJAX done</p>")
      error: (a,b,c) -> console.log("error", a,b,c)

The /foo endpoint is:

def foo
  puts "about to return 123"
  render json: { number: 123 }
end

What we're seeing is that most of the time, the spec says

log: clicked
about to return 123
log: GET success via jQuery "" "success" {"readyState":4,"responseText":"","status":200,"statusText":"OK"}

So it fires the Ajax request, the controller says "about to return 123", but jQuery only sees an empty-string response text.

Sometimes (maybe once in 5-10 spec runs or so?) it does what we wanted, saying

log: clicked
about to return 123
log: GET success via jQuery {"number":123} "success" {"readyState":4,"responseText":"{\"number\":123}","responseJSON":{"number
":123},"status":200,"statusText":"OK"}

If we add dataType: "json" to the jQuery AJAX request, it also fails sometimes and passes sometimes, with slightly different messages, but it seems to amount to the same thing – it gets an empty-string response sometimes, which then can't be parsed as JSON.

We used jQuery in this simplified example, but the real project uses AngularJS's $http (it's an old project that we're modernising, starting with the tests), and runs into the same issue, so I'm guessing this applies to all Ajax requests.

Any ideas what could be going on here, that could cause Ajax requests to respond with an empty string, even though the server seems to provide the correct response?

Warning: redefining `object_id' may cause serious problems

❯ bin/rspec spec
Running via Spring preloader in process 71021
/ruby/2.6.2/lib/ruby/gems/2.6.0/bundler/gems/apparition-dcd9d74b34cf/lib/capybara/apparition/dev_tools_protocol/remote_object.rb:52: warning: redefining `object_id' may cause serious problems

Works in dev but not production: No live threads left. Deadlock?

Running on master. Works in dev environment, MacOS. In production, Amazon Linux, I get this error the first time I invoke Capybara's "visit". Any ideas?

Running it via a rake task.

fatal: No live threads left. Deadlock?
1 threads, 1 sleeps current:0x0000000001072470 main thread:0x0000000001072470
* #<Thread:0x000000000109f370 sleep_forever>
   rb_thread_t:0x0000000001072470 native:0x00007f26dc927740 int:0
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver/launcher.rb:93:in `pop'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver/launcher.rb:93:in `block in ws_url'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver/launcher.rb:92:in `loop'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver/launcher.rb:92:in `ws_url'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver.rb:71:in `client'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver.rb:50:in `browser'
../ruby/2.6.0/bundler/gems/apparition-f34790959e64/lib/capybara/apparition/driver.rb:93:in `visit'
../ruby/2.6.0/gems/capybara-3.32.1/lib/capybara/session.rb:278:in `visit'
../ruby/2.6.0/gems/capybara-3.32.1/lib/capybara/dsl.rb:58:in `block (2 levels) in <module:DSL>'

Does it run on hosted CI e.g. CircleCI, TravisCI?

Hi, can anyone confirm if this new driver runs properly on hosted CI such as CircleCI, TravisCI etc?

I'm just started to test it on CircleCI, my RSpec test suite just hang and timed out.

RSpec is shutting down and will print the summary report... Interrupt again to force quit.
Too long with no output (exceeded 10m0s)

Unexpected inner loop exception

Firstly, thank you for making this. Years of Selenium's and Chromedriver's nonsense has worn me down. Apparition really seems like an improvement. I switched eola's whole test suite over (hundreds of tests) and it mostly seems to be working now, faster of course.

This is an odd little issue I've noticed. It doesn't actually cause specs to fail so it's not urgent, this message just gets printed as the suite runs. Not really sure what's going on.

Unexpected inner loop exception: undefined method `[]' for nil:NilClass: undefined method `[]' for nil:NilClass: ["/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/page.rb:609:in `block in register_js_error_handler'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:209:in `block in process_handlers'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:207:in `each'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:207:in `process_handlers'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:185:in `block in process_messages'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:175:in `loop'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:175:in `process_messages'", "/Users/sfcgeorge/.rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/apparition-0.3.0/lib/capybara/apparition/driver/chrome_client.rb:215:in `block in start_threads'"]

Feature request: add a "speed" option for click()

Hi there!

I don't know if this feature request should go into Capybara or Apparition, but here goes.

I'm testing a webpage which is sensitive to the speed at which a button is clicked. Weird, I know, but well, it's kinda simple actually : we just listen for "mouseup" and "mousedown" events, and act accordingly.

It would be awesome if we could do something like:

find("button").click(speed: 0.5)

and this would yield a 0.5 second pause between down and up in Capybara::Apparition::Mouse#click_at 😄

Hangs with no output

Hey All. I'm trying to use Apparition as my driver. When I go to run the tests, rspec just hangs indefinitely. There's some console output from Apparition however:

Capybara starting Puma...
* Version 5.2.1 , codename: Fettisdagsbulle
* Min threads: 0, max threads: 4
* Listening on http://127.0.0.1:63172      
info: %cDownload the React DevTools for a better development experience: https://fb.me/react-devtools font-weight:bold
warning: Warning: componentWillReceiveProps has been renamed, and is not recommended for use. See https://fb.me/react-unsafe-component-lifecycles for details.

* Move data fetching code or side effects to componentDidUpdate.
* If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state
* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. To rename all deprecated lifecycles to their new names, you can run `npx react-codemod rename-unsafe-lifecycles` in your project source folder.

Please update the following components: %s Lightbox, Motion

Here is my config:

Capybara.register_driver :apparition_debug do |app|
  Capybara::Apparition::Driver.new(app, {
    headless: true,
    debug: true,
    timeout: 5,
    browser_options: {
      'disable-gpu' => nil,
      'no-sandbox' => nil
    }
  })
end

Capybara.configure do |config|
  config.default_max_wait_time = 10
  config.always_include_port = true
  config.default_driver = :apparition_debug
  config.javascript_driver = :apparition_debug
end

Window management not working /window handles not returned when headless=false

Hello 👋

Was having some trouble getting #switch_to_window working when migrating to this gem. Turns out even though the new window is opening, page.driver.browser.window_handles size is still 1 and it's as if the driver is unaware of the 2nd tab. I later tried to migrate to the newer Capybara #window_opened_by, but the block would never return the window and hang indefinitely (even if specifying wait: 1). If I would close the tab manually, the block would exit with an error expected block to open 1 windows but 0 were opened.

I was able to replicate this within the Apparition spec suite by setting headless: false in the spec helper and executing

bundle exec rspec spec/integration/session_spec.rb:649

  1) Capybara::Session with apparition driver Window support #size should switch to original window if invoked not for current window
     Failure/Error:
       @other_window = @session.window_opened_by do
         @session.find(:css, '#openWindow').click
       end

     Capybara::WindowError:
       block passed to #window_opened_by opened 0 windows instead of 1

This test doesn't fail indefinitely like mine did, but the error is consistent. I was also able to fix my suite by going back to headless: true. SImilarly, I have this same problem with the Cuprite driver as I'm evaluating both at this time. It may be something with a recent CDP update. Here's some machine info:

OS: Mac OS Big Sur 11.0.1
Google Chrome: Version 87.0.4280.88

"NodeNotAttachedError" is defined twice

Ruby warned me about that:

/Users/thbar/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/bundler/gems/apparition-5aeacaea1075/lib/capybara/apparition/errors.rb:138: warning: already initialized constant Capybara::Apparition::NodeNotAttachedError
/Users/thbar/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/bundler/gems/apparition-5aeacaea1075/lib/capybara/apparition/errors.rb:131: warning: previous definition of NodeNotAttachedError was here

And indeed this shows up in the code:

NodeNotAttachedError = ObsoleteNode
class WrongWorld < ObsoleteNode
def message
'The element you are trying to access is not from the current page'
end
end
NodeNotAttachedError = ObsoleteNode

Intermittent error: The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported

About 6 months ago I replaced capybara-webkit with apparition in an app I'm working on and started seeing this error coming up intermittently in the CI and also locally: The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported. According to RSpec's docs, it happens when a stub is created outside of the example context, but I'm not doing that.

The backtrace:

Randomized with seed 9970
..............*......#<Thread:0x000056402ed09688@/home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:221 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	13: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:222:in `block in start_threads'
	12: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:161:in `cleanup_async_responses'
	11: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:161:in `loop'
	10: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:162:in `block in cleanup_async_responses'
	 9: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:162:in `synchronize'
	 8: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:164:in `block (2 levels) in cleanup_async_responses'
	 7: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:164:in `each'
	 6: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:165:in `block (3 levels) in cleanup_async_responses'
	 5: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/method_double.rb:64:in `block (2 levels) in define_proxy_method'
	 4: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/verifying_proxy.rb:161:in `proxy_method_invoked'
	 3: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/method_double.rb:77:in `proxy_method_invoked'
	 2: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/proxy.rb:342:in `message_received'
	 1: from /home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/space.rb:27:in `any_instance_recorders_from_ancestry_of'
/home/circleci/repo/vendor/bundle/ruby/2.6.0/gems/rspec-mocks-3.9.1/lib/rspec/mocks/space.rb:51:in `raise_lifecycle_message': The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported. (RSpec::Mocks::OutsideOfExampleError)
F.

If I rerun the same specs with the same seed it might pass or fail. The error doesn't always come from the same test, it can fail randomly on any test. When it causes one failure, it affects also other tests. Apparently database_cleaner ends up committing changes and not clearing the database on such failure.

I've tried updating RSpec to version 3.9, which fixes a thread-safety issue, and apparition to version 0.5.0, but the problem seems to persist. Any clue on what could be causing this? It seems like some kind of thread safety issue.

My app is using:

  • ruby 2.6.5
  • rails 5.2.4.2
  • apparition 0.5.0
  • rspec-rails 4.0.0
  • rspec 3.9
  • rspec-mocks 3.9.1
  • capybara 3.3.0.0

Started seeing error: Capybara::Apparition::CDPError: Invalid parameters

Hi there, firstly thanks for an incredible gem, we're a non-profit based in South India and your work with this gem is really helping us with our work.

We've run into an issue and we were wondering if you would be able to guide us. We're running a job on Heroku to do some work on a partner website which doesn't have an API. Recently when running this job we've started seeing the error Capybara::Apparition::CDPError: Invalid parameters. Below is the full stack trace...

Having played around with our codebase, we're not sure how to progress to debug further and was hoping you could provide some guidance. We're not sure if it's a Chrome issue, an issue with the response from the partner website, Capybara, or Apparition – despite the error message.

Any pointers would be much appreciated. Please let us know if we can provide any further information 🙏

2019-05-27T11:11:44.122549+00:00 app[worker.1]: 4 TID-gnledsk88 WARN: Capybara::Apparition::CDPError: Invalid parameters
2019-05-27T11:11:44.122643+00:00 app[worker.1]: 4 TID-gnledsk88 WARN: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/driver/response.rb:40:in `handle_error'
2019-05-27T11:11:44.122646+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/driver/response.rb:15:in `block in result'
2019-05-27T11:11:44.122648+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/driver/response.rb:13:in `map'
2019-05-27T11:11:44.122650+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/driver/response.rb:13:in `result'
2019-05-27T11:11:44.122651+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/page.rb:352:in `command'
2019-05-27T11:11:44.122653+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/page.rb:409:in `frame_offset'
2019-05-27T11:11:44.122654+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/page.rb:293:in `element_from_point'
2019-05-27T11:11:44.122656+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/node.rb:511:in `mouse_event_test'
2019-05-27T11:11:44.122658+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/node.rb:188:in `click'
2019-05-27T11:11:44.122659+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/node.rb:260:in `send_keys'
2019-05-27T11:11:44.122668+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/node.rb:455:in `set_text'
2019-05-27T11:11:44.122670+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/apparition-0.2.0/lib/capybara/apparition/node.rb:133:in `set'
2019-05-27T11:11:44.122671+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/capybara-3.21.0/lib/capybara/node/element.rb:119:in `block in set'
2019-05-27T11:11:44.122672+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/capybara-3.21.0/lib/capybara/node/base.rb:83:in `synchronize'
2019-05-27T11:11:44.122674+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/capybara-3.21.0/lib/capybara/node/element.rb:119:in `set'
2019-05-27T11:11:44.122676+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/capybara-3.21.0/lib/capybara/node/actions.rb:91:in `fill_in'
2019-05-27T11:11:44.122678+00:00 app[worker.1]: /app/vendor/bundle/ruby/2.6.0/gems/capybara-3.21.0/lib/capybara/session.rb:748:in `block (2 levels) in <class:Session>'

This happens when we do

@browser.find_field("join_neu_email_field").set(USER_NAME)
@browser.find_field("join_neu_password_field").set(PASSWORD)

cannot launch Chrome app if test suite is interrupted

Mac OS X 10.10.5
Chrome Version 79.0.3945.130 (Official Build) (64-bit)

Steps to reproduce:

  1. Chrome icon is on dock
  2. Capybara test is started
  3. Chrome icon on dock bounces a single time, test is running
  4. Press ctrl-c to stop test in progress
  5. Click Chrome icon on dock

Observe the chrome icon bounces a single time but app does not launch.

ps shows that chrome is not running, yet it will not launch without a reboot.

Be able to increase timeout in wait_for_loaded

Hi, thanks for a great gem!

Would it be possible to make the expire_in value sent to Capybara::Helpers.timer in wait_for_loaded configurable?

def wait_for_loaded(allow_obsolete: false)
timer = Capybara::Helpers.timer(expire_in: 10)

The README says that it is possible to use :timeout (and that default is 30 seconds), but I was consistently getting the error below until I went into the apparition directory in ~/.gem/ and raised expire_in. I could also see that my test never ran for 30 seconds, it was always somewhere around 15 seconds.

Failures:

  1)
     Failure/Error: visit(URL)

     Capybara::Apparition::StatusFailError:
       Request to '<URL>' failed to reach server, check DNS and/or server status
     # /Users/dentarg/.gem/ruby/2.6.2/gems/apparition-0.1.0/lib/capybara/apparition/page.rb:269:in `rescue in visit'
     # /Users/dentarg/.gem/ruby/2.6.2/gems/apparition-0.1.0/lib/capybara/apparition/page.rb:257:in `visit'
     # /Users/dentarg/.gem/ruby/2.6.2/gems/apparition-0.1.0/lib/capybara/apparition/driver.rb:91:in `visit'
     # /Users/dentarg/.gem/ruby/2.6.2/gems/capybara-3.16.1/lib/capybara/session.rb:277:in `visit'
     # /Users/dentarg/.gem/ruby/2.6.2/gems/capybara-3.16.1/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
     # ./scrape.rb:109:in `block (2 levels) in <top (required)>'
     # ------------------
     # --- Caused by: ---
     # Capybara::Apparition::TimeoutError:
     #   Timed out waiting for response to wait_for_loaded. It's possible that this happened because something took a very long time (for example a page load was slow). If so, setting the Apparition :timeout option to a higher value will help (see the docs for details). If increasing the timeout does not help, this is probably a bug in Apparition - please report it to the issue tracker.
     #   /Users/dentarg/.gem/ruby/2.6.2/gems/apparition-0.1.0/lib/capybara/apparition/page.rb:238:in `wait_for_loaded'

(I'm loading a page from the internet, not an app running locally, so that's why I would like to give everything some more time.)

Unexpected caching issues conflicting with CORB

Hi,

I'm trying to pull together enough telemetry to help explain what's going on, but we have a very specific error we see with Apparition that we don't see in our other use of Chrome or with Selenium + Chromedriver.

The issue happens when certain system specs try to make GET API requests. The server performs the render/response and returns data, but Chrome/Apparition tries to return the data from cache. The result (presumably returned from cache) is missing the Content-Type header that's normally present in the response, and Chrome 73's CORB blocking returns an empty response instead of the JSON our API sent back. I am also unclear as to how there's anything in the cache at all at this point.

Here's an example of the console log response:

Cross-Origin Read Blocking (CORB) blocked cross-origin response http://127.0.0.1:51183/api/v1/texts?locale=en with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.

The request for the network tab for this request is 200 OK with these headers:

Provisional headers are shown
Accept: application/json, text/plain, */*
Referer: http://127.0.0.1:51183/assignments/in-progress
Sec-Fetch-Mode: cors
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36
X-CSRF-Token: [object Object]
X-Requested-With: XMLHttpRequest

If we do a hard-reload in the browser re-execute this request, it always succeeds on the second attempt. We're at a loss for what's pre-populating the cache with the result of this API request since the session runs in incognito mode, and shouldn't have any cache to start.

When we hard-reload, we get the same request headers (except without the Provisional Headers warning, as the request succeeds), and the response comes back with the data we expect:

Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
ETag: W/"d37bdcc5c109f4a02f3fd13d24d30cce"
Referrer-Policy: strict-origin-when-cross-origin
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Request-Id: 1774dc8b-65c0-498d-a094-6a3b0ccd9ebf
X-Runtime: 0.328993
X-XSS-Protection: 1; mode=block

Do you have any ideas as to what might be wrong here that we can fix? We can't produce this in other drivers, but we very much want to transition over to Apparition.

Capybara's "visit" hangs on Amazon Linux

Here's a snippet of what I get running a rake task that scrapes a website. It hangs after the warning and the rest of the output is after I hit control-C.. It hangs on the first visit request.

Works great locally on my macbook.

Amazon Linux setup info:

  • Linux 4.4.19-29.55.amzn1.x86_64
  • google-chrome version 80.0.3987.163
  • I dont think it's needed but I also have ChromeDriver 2.37.544315 installed.

Where did i go wrong?

../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/dev_tools_protocol/remote_object.rb:47: warning: redefining `object_id' may cause serious problems
^Crake aborted!
Interrupt:
../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver/launcher.rb:90:in `pop'
../2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver/launcher.rb:90:in `block in ws_url'
../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver/launcher.rb:89:in `loop'
../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver/launcher.rb:89:in `ws_url'
../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver.rb:69:in `client'
../2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver.rb:48:in `browser'
../ruby/2.3.0/gems/apparition-0.1.0/lib/capybara/apparition/driver.rb:91:in `visit'
../ruby/2.3.0/gems/capybara-3.15.1/lib/capybara/session.rb:277:in `visit'
../ruby/2.3.0/gems/capybara-3.15.1/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'

Let me know if I missed anything.

Thank you in advance.

Google Chrome quit unexpectedly.

Thanks for the fantastic gem!

Everything looks fine except one thing. Chome periodically crashes at the end of the process of running specs and Mac creates a crash report.

The issue does exist for non-headless mode on Mac. I tried to debug it and seems like Chrome's process gets killed before a proc of process killer gets executed.

A simple repro is to run this spec in non-headless mode (I've changed it to false in spec/spec_helper.rb)

rspec spec/capybara-webkit/driver_rendering_spec.rb:50

Any ideas of how it could be fixed? I'd love to help and provide any needed info.

Thanks in advance!

'within_frame' working in headless but not when using Chrome driver

We use Braintree's Drop-in UI to handle credit card payments. They use hosted fields to render some of the sensitive inputs in an iframe.

Our feature tests run successfully when using headless: true, but we receive the following error when using headless: false:

Screen Shot 2019-11-19 at 2 25 17 PM

This occurs at the point in the code where we invoke within_frame('braintree-hosted-field-number')

We did some digging in Capybara::Apparition::Page.push_frame, and this led us to some logic for @session.on 'Page.frameNavigated' in the same class (being the place where @frames.add() is called).

We could be seeing things incorrectly, but it appears that the iframe in question is successfully added to the @frames object when using headless mode, but not when using Chrome driver.

Here's some GitGists showing how we landed there:

Perhaps we're seeing things incorrectly while debugging. In any case, we've never been able to get within_frame to properly switch to an iframe which is clearly in the DOM (including after adding a sleep 20 for good measure).

For reference, here's how we're registering the driver:

Capybara.register_driver :apparition do |app|
  Capybara::Apparition::Driver.new(app,
    browser_options: {
      'no-sandbox' => nil,
      'disable-web-security' => nil,
      'disable-features' => 'VizDisplayCompositor'
    },
    headless: headless,
    js_errors: false,
    window_size: [1440, 900]
  )
end

Thanks in advance for any guidance!

page.find(xyz).click intermittently does not work...

I (frustratingly) ran into this problem years and years ago when using poltergeist, and so I had switched to capybara-webkit which eliminated it... Now wanting to use chrome for integration testing, I have been working on switching over from webkit to apparition, and unfortunately am seeing this behavior once again.

It appears related to this recently closed issue: #34

And you can see others had reported this same bug way back when in the poltergeist repo but mistakingly thought that it has something to do with animations: teampoltergeist/poltergeist#530

I have an angular + rails app, and am rendering a simple angular directive which is basically a div container that has a checkbox input within it. For testing purposes, I made the on-click event for the checkbox input execute a function which adds a class of "clicked" to its div container.

My test is simply doing:

page.find('checkbox input').click
expect(page).to have_selector('.clicked')

The majority of test runs, this fails saying there was no .clicked selector found, but sometimes it passes.

If I change this test to do page.find('checkbox input').trigger(:click) then it works 100% of the time...

So in my case, there are no animations, nothing asynchronous happening what-so-ever---

As per Jordoh's answer in the checkbox issue-- he suggested this 'wait_for_document_load_complete' method, but prior to clicking I have output page.driver.evaluate_script('document.readyState') and the value is complete so that is not the issue...

Chrome Version 85 fails to load resources

hi @twalpole,

thank you for amazing work on this gem!

We hit an interesting issue with the latest chrome version 85 and the driver...

The browser starts and successfully makes the first request. Right after that, all subsequent requests fail with net::ERR_INVALID_ARGUMENT and no other clue to what's happening. It only happens on the first page loading and if you reload the page everything seems to be working.

There is our configuration:

      Capybara::Apparition::Driver.new(app,
        browser_options: {
          'no-sandbox' => nil,
          'disable-web-security' => nil,
          'disable-features' => 'VizDisplayCompositor'
        },
        headless: headless,
        js_errors: false,
        window_size: [1440, 900]
      )

Things we have already tried:

In the meantime, we would like to stay with the apparition driver but this issue bothers us a lot b/c it prevents us to run any feature tests.

Any help would be really appreciated!
Thank you again for the amazing contribution and commitment to this gem!

Missing switch_to API

Thanks for creating and maintaining apparition! We also tried to create a new driver that bypasses selenium and chromedriver (we called it https://github.com/carbonfive/shimmer), but didn't get very far... we're excited to see something else maturing. :)

It looks like an API that is supported by selenium-webdriver might be missing in apparition. Perhaps we were using a non-standard API?

Failure/Error: page.driver.browser.switch_to.alert.accept

     NoMethodError:
       undefined method `switch_to' for #<Capybara::Apparition::Browser:0x000000010d770bb0>
       Did you mean?  https://github.com/carbonfive/shimmer

Do you have any suggestions? Thanks!

Screenshots occasionally have a blank white rectangle at the top

When a test fails, we take a screenshot to aid in debugging. Sometimes, the screenshot has a white box that covers the entire screen, other times it's just the top:

image

This does not occur on every failure in our application, and I'm not even sure if it's consistent for a specific test.

I haven't been able to create a minimized reproduction case yet, but figured I'd open an issue early in case other people have experienced something similar.

  • apparition (0.6.0)
  • capybara (3.33.0)
  • Google Chrome 83.0.4103.116
  • macOS 10.15.5 (19F101)

Checkbox sometimes not checked after `check …`

I realise this may be hard to do anything about without a repro, but I thought I'd mention it on the off-chance that the maintainer(s) can think of an explanation, or at least in case anyone else runs into it in the future.

This happens on a fairly complex page in our app, and I can't currrently take the time to try to make a minimal repro, but the nut of it is that if I do

# Other code…

check "My checkbox"
expect(find_field("My checkbox").checked?).to be true

Then sometimes the expectation fails.

When it fails, screenshots are completely white. When it passes, I can see the checked checkbox in the screenshot.

Adding a sleep 0.1 before checking the box seems to consistently fix it. Adding a sleep 0.01 fixes it some of the time. With no sleep, it fails almost every time. So clearly there's a timing thing going on.

The preceding code in the test changes two other forms on the same page and submits them with Ajax. The page is not rewritten much by those submissions – it only toggles some classes on those other forms. If I remove either one (or both) of the two Ajax submissions, it starts passing without the sleep.

Happy to screen share with a maintainer, but again, afraid I won't be able to take the time to make a distributable or minimal repro out of this :/

`attach_file` not working with remote browser

Running a remote browser on a different host (e.g. Docker) and calling attach_file results in a file not found error. It would be useful to either somehow support file uploads or show an error message that they not supported on remote browsers.

Spec that passed with Poltergeist fails without sleep to ensure JS runs first

We've got a Capybara spec that essentially does

visit my_path
click_link "Add the thing"
fill_in "the_thing"

We've got JavaScript like

$(function() {
  $(".add-the-thing").on("click", append_the_thing_to_the_page);
});

This test runs fine on Poltergeist, but with Apparition it fails unless we add e.g. sleep 0.1 like so:

visit my_path
click_link "Add the thing"
sleep 0.1
fill_in "the_thing"

After some console.loging, it seems that Apparition runs the click_link too soon – before the on click event has been attached.

Even if Apparition retries the fill_in, that won't help, because the problem is the click.

We could (and probably will) work around it by not showing the link until the JS event has been loaded or something similar (maybe waiting for some selector to be added to body), but I still thought I'd report this as one possible issue if the lib aims to be as close as possible to a drop-in replacement for Poltergeist.

If you've got any better ideas for how to solve or work around it, we'd love to hear them :)

This is quite a big project, so maybe pages and JS takes longer to load than it would in a minimal project. We haven't tried reproducing it in a small project and probably won't if we can work around it :/

CircleCi fails to finish

The following commit is preventing for CircleCi from completing:

9043f02

I am guessing it is something to do with the way it is writing out to stderr / stdout

WebSocket frame length too large (RuntimeError)

I'm using apparition as my javascript driver for capybara in a suite of cucumber tests. I've got the tests running OK locally in both headless and non-headless mode, but I'm not having a problem on CI (codeship) which I'm not entirely sure how to fix.

here are the versions of the relevant gems being used (in no particular order other than perceived relevancy)

apparition (0.5.0)
      capybara (~> 3.13, < 4)
      websocket-driver (>= 0.6.5)
websocket-driver (0.7.1)
      websocket-extensions (>= 0.1.0)
    websocket-extensions (0.1.4)
capybara (3.31.0)
      addressable
      mini_mime (>= 0.1.3)
      nokogiri (~> 1.8)
      rack (>= 1.6.0)
      rack-test (>= 0.6.3)
      regexp_parser (~> 1.5)
      xpath (~> 3.2)
puma (4.3.3)
      nio4r (~> 2.0)
cucumber (3.1.2)
      builder (>= 2.1.2)
      cucumber-core (~> 3.2.0)
      cucumber-expressions (~> 6.0.1)
      cucumber-wire (~> 0.0.1)
      diff-lcs (~> 1.3)
      gherkin (~> 5.1.0)
      multi_json (>= 1.7.5, < 2.0)
      multi_test (>= 0.1.2)
cucumber-api-steps (0.14.0)
      cucumber (>= 2.0.2)
      jsonpath (>= 0.1.2)
cucumber-core (3.2.1)
      backports (>= 3.8.0)
      cucumber-tag_expressions (~> 1.1.0)
      gherkin (~> 5.0)
cucumber-expressions (6.0.1)
cucumber-rails (1.7.0)
      capybara (>= 2.3.0, < 4)
      cucumber (>= 3.0.2, < 4)
      mime-types (>= 1.17, < 4)
      nokogiri (~> 1.8)
      railties (>= 4.2, < 7)
webpacker (4.0.7)
      activesupport (>= 4.2)
      rack-proxy (>= 0.6.1)
      railties (>= 4.2)
rails (6.0.2.1)
      actioncable (= 6.0.2.1)
      actionmailbox (= 6.0.2.1)
      actionmailer (= 6.0.2.1)
      actionpack (= 6.0.2.1)
      actiontext (= 6.0.2.1)
      actionview (= 6.0.2.1)
      activejob (= 6.0.2.1)
      activemodel (= 6.0.2.1)
      activerecord (= 6.0.2.1)
      activestorage (= 6.0.2.1)
      activesupport (= 6.0.2.1)
      bundler (>= 1.3.0)
      railties (= 6.0.2.1)
      sprockets-rails (>= 2.0.0)

here is my capybara driver configuration file

require 'capybara/apparition'

Capybara.default_max_wait_time = 10
Capybara.exact = false

Capybara.register_driver :apparition do |app|

  options = {
    headless: true,
    timeout: 15,
    browser_options: [
      :no_sandbox,
      :disable_gpu,
      { disable_features: 'VizDisplayCompositor' },
    ]
  }

  Capybara::Apparition::Driver.new(app, options)
end

Capybara.javascript_driver = :apparition
Capybara.server = :puma

chrome version on codeship: Google Chrome 80.0.3987.149 (not sure if this is relevant, this is the same as my local which is working fine)

here is the error I am presented with when starting any cucumber tests

#<Thread:0x0000564aab624390@/home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:226 run> terminated with exception (report_on_exception is true):
Traceback (most recent call last):
	17: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:228:in `block in start_threads'
	16: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:139:in `listen'
	15: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:128:in `read_until'
	14: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:128:in `loop'
	13: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:129:in `block in read_until'
	12: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/chrome_client.rb:143:in `read_msg'
	11: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/web_socket_client.rb:24:in `read_msg'
	10: from /home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/web_socket_client.rb:58:in `parse_input'
	 9: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/client.rb:63:in `parse'
	 8: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/hybi.rb:104:in `parse'
	 7: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/hybi.rb:327:in `parse_extended_length'
	 6: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/hybi.rb:334:in `check_frame_length'
	 5: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/hybi.rb:266:in `fail'
	 4: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/hybi.rb:260:in `shutdown'
	 3: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/event_emitter.rb:38:in `emit'
	 2: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/event_emitter.rb:38:in `each'
	 1: from /home/rof/cache/bundler/ruby/2.5.0/gems/websocket-driver-0.7.1/lib/websocket/driver/event_emitter.rb:39:in `block in emit'
/home/rof/cache/bundler/ruby/2.5.0/gems/apparition-0.5.0/lib/capybara/apparition/driver/web_socket_client.rb:40:in `block in setup_driver': WebSocket frame length too large (RuntimeError)

thanks!

Feature request: use CDP to get mobile settings

Chrome for a while has not allowed the user to shrink the window width narrower than a certain width (I think it's 500px on most displays). We had thought that our mobile tests were getting down to narrower widths, but it turns out they are blocked.

You can get narrower if you select a device to simulate from the developer tools.

It looks like CDP supports mobile device simulation, this would be a pretty awesome thing to be able to do in Apparition. It would probably require being able to pass mobile in as a parameter and then have it pass through to here:
https://github.com/twalpole/apparition/blob/170a98529bb3d49ee1a4335b43c183ee2eb9de41/lib/capybara/apparition/page.rb

https://developers.google.com/web/tools/chrome-devtools/device-mode

Would you be open to a PR to do this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.