In my Rails app front-end I use JavaScript's Array.includes method as follows
if (['a', 'b', 'c'].includes('b')) {
// do stuff
It works fine in a live Chrome browser, but my RSpec test is failing. I believe Capybara Webkit doesn't seem to support it?
I can confirm this by pausing the spec with binding.pry and running
> page.evaluate_script("['a', 'b', 'c'].includes('b')")
=> nil
It returns nil when it should return true.
Just out of curiosity I tried this same thing on another Rails app, and miraculously it worked on that app
> page.evaluate_script("['a', 'b', 'c'].includes('b')")
=> true
So I'm scratching my head as to why it would work on one app but not another?
App #1 (Failure)
Capybara 2.18.0
Capybara Webkit 1.15.0
App #2 (Success)
Capybara 2.13.0
Capybara Webkit 1.14.0
In fact the first app where it failed seems to have a more recent version of Capybara/Webkit..
Thanks!
capybara-webkit gets it's JS support based on the version of QtWebkit it is built against. The last released stable version of QtWebkit supported ES5 (and most of ES 5.1) and is basically equivalent to a 6-7 year old version of Safari.
Since Array.prototype.includes() wasn't included in the JS standard until ES2015 it is not supported natively by capybara-webkit. You can however add support for includes via a polyfill and I'm guessing that's what you have in your App #2.
In order for capybara-webkit to be useful with modern apps you need to make sure all JS used in your app is transpiled to ES5 and polyfilled (using babel, etc). If your apps requirements don't include old/obsolete browsers a better solution for headless testing is to use headless Chrome or Firefox via capybaras selenium driver since those combinations support modern JS and CSS.
According to the docs, execute_script will perform and javascript much better, I have replaced evaluate with execute in my e2e tests
Related
Our team create functional tests using Rspec and UI tests using Selenium Webdriver with Ruby.
UI tests get executed as Rake tasks. While running one of the test, browser session was not opening, throwing "Error 500" with message as:
"Selenium::WebDriver::Error::SessionNotCreatedError (session not created: This version of ChromeDriver only supports Chrome version 79):"
I already updated both chrome and chrome driver version; still I was encountering the same error.
By going back and forth, I came across the solutions to similar issue but with different techstack and infra, which were not applicable to the issue I came up with.
So finally I found that there was a gem called "chromedriver-helper", which ([link] https://rubygems.org/gems/chromedriver-helper/versions/1.0.0) got deprecated and it was advised to get rid of this gem, while using another one called "webdrivers".
[link] https://everydayrails.com/2019/04/09/chromedriver-helper-webdrivers.html
[link] https://github.com/flavorjones/chromedriver-helper
So I removed the deprecated gem while added the new one which was suggested and removed following the folder under home directory:
$HOME/.chromedriver-helper. After these two changes, my team is now able to run the UI tests smoothly
What are the differences between PhantomJS and capybara-webkit?
What are the advantages of capybara-webkit over PhantomJS?
Which of the two is the most efficient tool?
Others ...
poltergeist is the capybara driver for PhantomJS, a headless browser which is built on WebKit. capybara-webkit is a capybara driver which uses WebKit directly.
poltergeist/PhantomJS has some big advantages over capybara-webkit:
In my experience poltergeist/PhantomJS always times out when it should, whereas capybara-webkit sometimes hangs.
Its error messages are much clearer. For example, it will actually tell you if it can't click an element that is on the page because there's another element in front of it.
It can be told to re-raise Javascript errors as test errors (by instantiating the driver with js_errors: true).
PhantomJS is much easier to install than standalone WebKit. PhantomJS provides a nearly dependency-free executable that you can download, while standalone WebKit has many OS library dependencies which you may have to upgrade or otherwise fiddle with.
TL;DR
Poltergeist/PhantomJS is easier to set up
Poltergeist/PhantomJS has less dependencies
Capybara-webkit is more stable and reliable and it’s better for CI
Long:
I have been using Poltergeist + PhantomJS for more than one year. My largest project has a lot of Ajax calls, file uploads, image manipulations, JS templates and pure CSS3 animations.
From time to time, Poltergeist and PhantomJS generated random errors.
Some of them were my mistakes. Testing Ajax is tricky. A common error was that at the end of the successful test the database_cleaner gem truncated the database, however, one Ajax call was still running and generated exception in the controller due the empty database. This isn’t always easy to fix unless you want to use sleep(). (I do not).
However, many errors with Poltergeist were not my mistakes. I have a test which does the same thing 30 times (for a good reason) and once in a while 1 of the 30 times it didn’t work. Poltergeist did not click on the button at all. It was a visible, not animated, normal button. I could fix it (by clicking on it again), however, that’s an ugly hack and feels wrong.
Sometimes the script that worked in all browsers generated random javascript errors with Poltergeist/PhantomJS. About 1 or 2 of 100 times.
With two different Ajax uploader plugin I have experienced that PhantomJS 1.9 and 2.0 behaves differently. 2.0 is more stable and consistent but it’s far from being perfect.
This was a huge pain with Jenkins. About every third run was a failure because 1 or 2 of the 400 features (js browser tests) generated random errors.
Two weeks ago I tried Capybara-webkit. It took me a couple of hours to migrate since they treat invisible elements differently. Capybara-webkit is more correct or strict in this. I noticed the same about overlapping elements.
Testing Ajax uploading and image manipulation requires custom scripts that I had to modify for Capybara-webkit.
I’m using Mac OS X for development, FreeBSD for production and Linux for Jenkins. Capybara-webkit was more complicated to set up than Poltergeist because it requires a screen and it has many dependencies. Only PhantomJS is truly headless and standalone. I could run PhantomJS on production servers if I wanted. I would not do that with capybara-webkit because of the dependencies.
Now I have 100% stable Jenkins CI. All the random javascript errors are the memories of the past. Capybara-webkit always clicks on the button I want it to click on. Javascript always works fine. Currently I have about 20-25 stable builds in a straight line.
For projects with a lot of Ajax, I recommend capybara-webkit.
My advice is based on the current, up to date versions in Aug, 2015.
capybara-webkit and PhantomJS both use Webkit under the hood to render web pages headlessly, i.e., without the need for a browser. They're different tools, however:
capybara-webkit serves as an adapter for Capybara, a Ruby gem that lets you write and perform high-level UI testing for a Rails or Rack app.
PhantomJS is a lower level tool that simply lets you run scripts against a web page. It can also be used to write UI tests as well (see Casper, for instance, or any of the other testing tools that build upon PhantomJS).
PhantomJS does not support HTML5 features like Audio/Video which really sucks.
We are currently upgrading our Rails 3.2 (Ruby 2, Mongoid 3.1.5) App to Capybara Webkit 1.0.0 from 0.13.1. After the gem upgrade we fixed all new failing specs to comply with Capybara 2's new features and (default) settings. That went quite well. BUT: Our whole test suite is now significantly slower than before (~21 minutes compared to ~12 minutes).
Some tests take about 20 seconds. After lots of debugging we figgured out that the issue is not in those slow tests themselves (they run in 2 seconds as single test or in a selected group) but in the cumulation of several tests. We do run (and test) ajax calls in most of these feature tests. So the guess is that the webkit server gets blocked after some tests. But we didn't have that problem with the old capybara version.
I now, every test suite is quite individual so I don't ask for specifics. I'm happy with any idea which can lead to a solution.
Has anyone experienced (and solved ;-) similar problems? Maybe any ideas I didn't have yet?
Clue: Check for the number of files the webkit server opens and webkit processes during the test run
lsof |grep webkit
I've been trying to test a pusher app with Poltergeist. So far I've only had success with capybara-webkit. I've created a minimal example app which demonstrates this in a spec. The spec passes with capybara-webkit but fails with Poltergeist.
Am I missing something or is this type of Pusher (WebSocket) testing not possible with Poltergeist at the moment ?
Thanks in advance.
Update your Pusher javascript library to 2.1.5 (or higher) and it should work (assuming you are also using PhantomJS 1.9 or higher).
Poltergeist automates PhantomJS. PhantomJS does support WebSockets, however it's an older version (until PhantomJS 2.0 comes out, see https://github.com/ariya/phantomjs/issues/11018). The Pusher javascript library also supports various versions of WebSockets so in theory they should work together.
In practice I had trouble getting it to work when using version 2.1.3 of the Pusher JS library (and from the date of this question I imagine you were using an even older version). As of 2.1.5 my poltergeist tests are successfully testing Pusher functionality.
I have an integration test that fails for a page that depends heavily on javacript. The same page runs just fine from the browser.
Simplifying the test to a bare minimum I found out that just testing for the presence of a selector that is added by javascript after the page load, would fail.
After precompiling the test assets and using save_and_open_page I found that the handler for the jQuery ready event is not running during the integration test.
I didn't find any references to this problem, so I guess I'm doing something wrong.
Can anyone help me figuring this out?
I'm using using rails 3.2.11, RSpec 2.13.0, Capybara 2.0.3 and capybara-webkit 0.14.2
By default Rails uses webdriver which doesn't handle JS. If you want JS support you'd need to use one of the JS-aware drivers, like Selenium (which runs full featured browser), capybara-webkit or poltergeist (which are headless webkit browsers). There are many others but these three are most popular.
I solved this problem for me by examining my AJAX request. The problem was that I was requesting a 'http://..." instead of '/' of my page. This meant that it raised a CORS ('ajax request from outside the domain') even though the request looked like it was coming from inside the domain.
My original symptom was 'javascript-inserted HTML elements are not on the page when testing using Capybara with Poltergeist or Selenium (but are on the page when running the application).'