Selenium tests for the PrestaShop Starter Theme.
This test suite should never be run on a production shop because some tests are destructive.
Dependencies:
- node.js
- npm
- java
- firefox
The usual:
cd tests/Selenium
npm install
- cross fingers
The less usual :
- install PrestaShop, preferably in English with URL rewriting enabled (though tests should ideally be language and settings agnostic)
- copy
tests/Selenium/settings.dist.js
totests/Selenium/settings.js
and customize according to your setup - once PrestaShop is installed, run
php prepare-shop.php
. WARNING: never do this on a production shop because it will edit existing products without asking for your permission.
cd tests/Selenium
npm run selenium
npm test
- cross fingers
Tests are contained in the specs
subfolder.
Until we can do more documentation, please have a look at the existing tests and at the WebDriver.io API.
If you need to add general purpose helper functions for your tests, they should go in commands/init.js
.
If you need fixtures for your tests, please use the ones from the default installation or provide a script that installs them.
Do not hard-code things such as product ids in your tests: instead abstract them behind a name and put them in the fixtures.js
file.
Our tests are run using the awesome mocha test runner, using the chai assertions framework with the should
syntax. By default we're also configuring chai
to use chai-as-promised to make assertions on promises easier - more on this later.
To create new tests, just add a file inside the specs
folder or add your tests to an existing spec file.
Related tests should live in the same spec file.
Tests are grouped inside describe
calls and defined using the it
function. This syntax encourages you to think about what you're doing from an end user point of view.
E.g. "describe
the home page, it
should contain a link with the logo" would be written in home-page.js
as:
describe('The home page', function () {
it('should contain a link with the logo', function () {
// your test here
});
});
So what should go into the body of the test?
In all the tests, you have access to a global browser
object, so let's use it:
/* global describe, it, browser */
describe('The home page', function () {
it('should contain a link with the logo', function () {
return browser
.url('/')
.element('a.logo img')
;
});
});
- Notice we're accessing the
/
URL, that's because the base URL is already defined insettings.js
so that tests do not depend on your shop's URL.webdriver.io
will automatically add the base URL. - The test works because if the
a.logo img
element is not found thenwebdriver.io
will throw an exception, which marks the test as failed formocha
.
webdriver.io
allows you to perform almost any action a browser would do using a fluent promise-based API.
You will need some familiarity with promises to make the most of the tool.
Here are a few examples to get you started.
In webdriver.io
all methods return promises, but if you don't care about the result of a call (e.g. if it is just an action) you can just chain methods and even though they are all asynchronous things will execute in order as you'd expect.
If some step fails, webdriver.io
will throw an exception and your test will fail, which is what we want.
For instance to click on an item and then wait for an element to appear:
browser
.click('#approve-terms')
.waitForVisible('#disapprove-terms')
Have a look at the methods in the Utility section of the webdriver doc, they're very helpful.
If you care about the result of intermediate steps in your promise chain, then you need to make the chaining explicit:
describe('The One Page Checkout', function () {
it('should not display payment modules until the checkboxes are checked', function () {
return browser
.elements('.payment_module')
.then(function (elements) {
elements.value.length.should.equal(0);
})
;
});
});
Here we care about what .elements
returns, so we use then
to tap into the promise chain and inspect the elements
.
If there are elements then the expression elements.value.length.should.equal(0)
will throw an exception.
Since we're inside the promise's success handler, the exception will make the promise rejected.
And because we're returning this promise the test will be marked as failed.
Without chai-as-promised
if you wanted to make an assertion on a promise you would have to write something like:
it('should display a disabled order confirmation button until the checkboxes are checked', function (done) {
return browser
.isEnabled('#payment-confirmation button')
.then(function (enabled) {
enabled.should.equal(false);
done();
})
.catch(function (err) {
done(err);
});
;
});
But thanks to chai-as-promised
you can make it much simpler:
it('should display a disabled order confirmation button until the checkboxes are checked', function () {
return browser
.isEnabled('#payment-confirmation button')
.should.eventually.equal(false)
;
});