Testing Pusher with Capybara Poltergeist - capybara

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.

Related

Does Capybara Webkit recognize JavaScript's Array.includes() method?

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

How do poltergeist/PhantomJS and capybara-webkit differ?

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.

jQuery document.ready not called during rails integration test

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).'

Is it possible to facebook connect using Capybara Webkit

Is it possible to facebook connect using Capybara-webkit driver?
All the examples I see on the Web are using the "within_window" method (like this one: https://gist.github.com/1187574) which is currently not supported by Capybara-webkit.
Thank you.
I also found only "within_window" examples, but after some more research I found a quite recent pull request on the capybara-webkit repo that solves that issue and adds support for within_window to the capybara-webkit gem
Probably the best way to go is to fetch the gem from Github instead of rubygems.
gem "capybara-webkit", git: "https://github.com/thoughtbot/capybara-webkit.git"
Let me know if it works. I haven't really tested out.

Integrate test process with Rspec and Cucumber in a plugin using Desert

I'm developing some rails plugins with desert, and I would like to use tests with RSpec and Cucumber in the development. RSpec is integrated by default in Desert plugins, but it gives me some bugs.
Finally I have created a minimal application which use my plugin, and I try to test it like a normal application without plugin. But I dislike that solution, the plugin lost its modularity, and RSpec still returns me some bugs (he can't find the models/views/controllers located in the plugin...).
So am I the only one who try to test a Desert plugin (or even in a classic plugin) ? May anyone know those matters and get a solution ?
I was working with 'Desert' plug-ins in a legacy Rails 2.2.2 app and the following helped me http://pivotallabs.com/users/joe/blog/articles/985-testing-desert-plugins-in-isolation
You should not use desert plugin, it's an 'old thing'.

Resources