Executing JavaScript from a Cucumber/Capybara test - ruby

It appears that Selenium has a feature called JavascriptExecutor which makes it possible to execute JavaScript directly on the page. However it appears that there is no such thing available to my Cucumber/Capybara tests. How can I execute arbitrary JavaScript from my Cucumber tests?

Capybara has two methods to execute javascript #execute_script and #evaluate_script.
Both can be found at: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Selenium/Driver
However, do note that the readme has this statement about the above methods:
For simple expressions, you can return the result of the script. Note
that this may break with more complicated expressions:
See http://rubydoc.info/github/jnicklas/capybara/master/file/README.md.

Related

How to test Capybara?

I have a script that use Capybara to publish links in Google+. I would like to have tests to cover this functionality. Usually Capybara is using as a tool for writing Integration tests. In may case i need to test Capybara itself.
I see 3 possible ways:
stub capybara's method (but in this case i test nothing but just stubbed methods)
test capybara agains saved HTML/JS page (that will help me understand that i did not break anything during refactoring)
do not test at all (no comments here)
Have you ever faced such a problem?
If you register different drivers for your app and your test code, possibly manage the sessions manually depending on how you're using it in your app, and make sure you're careful with Capybaras setting's you should be able to go with option 2. You have to be careful with Capybaras settings because most of them are global so changing them for your tests will also change them for your app.

Custom code for #javascript tags in Capybara Webkit

I have some test set up code that I need to run before any Capybara tests that are running JavaScript with the #javascript tag. I don't want the code to run the rest of the time since this test set up is expensive in terms of system resources and cognitive load.
I've searched the documentation extensively and was unable to find any examples of running arbitrary ruby before tests based in tagging. Can anyone help me out?
Edit: after thinking about this some more, I only need the code to run once before any tests are run, so this is probably a simpler problem then I first described.
Since you're asking about an #javascript tag I'm assuming you're talking about Cucumber driven tests, if you're not then please clarify.
To run code before a test you use Before
Before('#javascript') do
# any code here will get run before each test tagged with #javascript
end
To make it only run that code once you'd need to use a global variable
Before('#javascript') do
$already_run ||= false
return $already_run if $already_run
# code here will get run once before the first test tagged #javascript
$already_run = true
end

Test cases for an application which has both php and javascript

There is an application which uses both php and javascript. If I want to write test cases for this application. Shall I have to write both (phpunit test cases for php code and jasmine test cases for javascript code)? .
I have downloaded phpunit from the link https://phar.phpunit.de/phpunit.phar
I am just not clear how to start the test cases.Please help .
From the link https://softwareengineering.stackexchange.com/questions/28306/can-i-test-effectively-javascript-functions-with-a-php-unit-testing-framework , they say I have to write javascript test cases for javascript code and php test cases for php code. But my javascript code is in between php code. How can I write and execute the test cases?
The first important concept is: to be tested, your code must be run, and for that you have to use the environment needed for each case:
for php: usually the php command line executable
for Javascript: a real browser, a headless browser like PhantomJS, or node.js
Once you have this clear, it's easy to understand how to setup the tests. Use PHPUnit for testing your php files and classes, and your Javascript framework of choice for testing Javascript code.
Regarding Javascript code being mixed with php code:
Strictly, the Javascript code will finally be sent to the browser, even if it is being written by php. So it should be testable running it in a Javascript environment.
But in reality, this probably is an indication of a poorly structured app, in which Javascript code is not separated from the backend code, and probably does not use objects and separation of concerns. This will make the code quite hard to test.
IMO the hardest part of testing is being able to write testable code, not writing the actual tests. If your code does not uses objects, some kind of dependency injection, templates for writing the HTML and the Javascript code is not fully separated from the backend code, I'd say you'll have a bad time trying to test it. My advice is that you rewrite some part of your app using best practices and try to test it. Using a framework usually helps because frameworks enforce the separation of concerns and usually have unit testing integrated.

One set of tests for few projects with different parameters

i'm using Protractor and Jasmine and would like to organize my E2E test in the best way.
Example:
There is a set of the tests for check registration function (registration with right credentials, register as existed user, etc.).
I need to run those tests in three different projects. Tests are same, but credentials are different. For one project it could be 3 fields in the registration form, in another one - 6.
Now everything is organized in a very complicated way:
each single test is made not as "it" but as a function
there is a function which contains all tests (functions which test)
there is a file with Describe function in each
in that file there is one "it" which call the function which contains all tests
there is test suite for each project
I believe that there is a practice how to organize everything in a right way, that each test was in own "it". So will be happy to see some links or advice.
Thank you in advance!
Since it's a broad question, i will redirect you to few links. You should probably be looking at page-object model of Protractor. It will help you simplify and set a standard to organise your tests in a way that is readable and easy to use. Here's the link to it as described by Protractor team.
page-object model
However if you want to know why do we need to use such a framework, there are many shortcomings to it, which can be solved by using such framework. A detailed explanation is here
shortcomings of protractor and how to overcome them
EDIT: Based on your comments i feel that you are trying make a unified file/function that can cater to all the suites that will be using it. In order to handle such things try adding a generalised function (to fill form fields in your case), export that function and then require it into your test suites. Here's a sample link to it -
Exports and require
Hope this helps.

How to run cucumber scenario with and without javascript avoiding code duplication

I was wondering if there is any way to run cucumber scenario with and without javascript without duplicating code.
I develop website that utilizes html5 navigation. However it should work find if browser doesn't support html5 features.
I would like to write cucumber test that would test navigation.
I know I can test basic html navigation with simple cucumber scenario. And I can test html5 navigation with same scenario but with #javascript tag.
I would really love to avoid this code duplication.
I was experimenting with around hooks, hoping that I could simple call block, then call same block with
Capybara.using_driver(Capybara.javascript_driver) { block.call }
However this doesn't work.
Anyone have any idea how to implement this?
P.S.
I'm quite new to Ruby, and just started working with cucumber.
It looks like you need two different scenarios. I'd use the Background feature to avoid step definitions but it's a matter of taste.
Based on the solution by Jon M of using the environment variable, you need to set the current_driver before each scenario runs (which seems better than changing the default_driver).
Before do
if ENV['USE_JS_DRIVER']
Capybara.current_driver = Capybara.javascript_driver
end
end
And then running
cucumber .
USE_JS_DRIVER=1 cucumber .
If you don't want to create separate features to deal with both types of browser, then one solution is to use an environment variable to tell cucumber which type of browser driver to use, and invoke cucumber twice.
You'd need to query the environment variable to set the correct driver, probably in env.rb:
if ENV['USE_JS_DRIVER']
Capybara.current_driver = Capybara.javascript_driver
end
And then you could run either/both of:
cucumber .
USE_JS_DRIVER=1 cucumber .
You'd have to find some useful way of merging the results from both cucumber runs, but depending on your needs this could be a simpler solution than duplicating your scenarios.

Resources