Cypress Tests
ExpressionEngine is utilizing Cypress for integration tests.
The tests are organized to check the functionality of ExpressionEngine itself, but can also be extended for add-on testing.
In order to get access to Cypress testing, ExpressionEngine need to be installed from repository. You also need to have Node.js and NPM installed.
Setting up
Back up your existing database and
system/user/config.php
file. The database might be rewritten with the test dump and the config file changed during tests run.Ensure your
config.php
file has correctbase_path
,base_url
andsite_url
values set up. Example: $config[‘base_path’] = $_SERVER[‘DOCUMENT_ROOT’]; $config[‘base_url’] = ‘http://ee6pro.local/‘; $config[‘site_url’] = $config[‘base_url’];cd tests/cypress
The Cypress working directory istests/cypress
, so all terminal command should be run there.npm i
Cypress is being provided as NPM package, so run this command to install Cypress and all dependencies. If this is your first time using Cypress, the process might take a while to download and unpack the things.cp cypress.env.example.json cypress.env.json
You will need to set up environment file that will hold important information that allow Cypress to connect to ExpressionEngine, such as your site URL, database name etc. These values should match the settings in ExpressionEngine config file.npm run cypress:open
This command will open the Cypress UI that lists all tests that exist for ExpressionEngine intests/cypress/cypress/integration
folder and can be run individually. Clicking on the test file name will run the test using selected browser.npx cypress run --headed --no-exit -s cypress/integration/cp/login.ee6.js
This command will run particular test file as specified by-s
parameter. You can also specify a wildcard*
in place of the file name to run all tests in a folder. Note that as of the current Cypress version that EE is using the test files cannot be placed abovetests/cypress
directory in directories tree.
Cypress commands and tasks for EE
In addition to built-in Cypress commands, ExpressionEngine is providing several specific helper commands, that are defined in support/commands.js
cy.auth()
Log the the user into Control Panel.
cy.authVisit()
Visit certain page after ensuring the user is logged in into Control Panel.
cy.hasNoErrors()
Checks that page contents does not show any of common errors.
cy.createChannel()
Creates channel
cy.addMembers()
Creates test members
cy.addRole()
Creates new member role
cy.createEntries()
Creates some entries for testing
cy.eeConfig()
Get or set certain configuration value
cy.eeConfig({ item: 'save_tmpl_files', value: 'n' })
cy.eeConfig({ item: 'site_url' })
cy.task('db:clear')
Truncates the database
cy.task('db:seed')
Replaces the database using the default database dump provided with ExpressionEngine Cypress tests
cy.task('db:load', '../../support/spam/spam.sql')
Executes the SQL file provided
cy.task('db:query', 'SELECT status FROM exp_statuses')
Executes the SQL query provided
cy.task('cache:clear')
Clears all EE caches
cy.task('filesystem:delete', '../../images/about/')
Delete files from directory
cy.task('filesystem:create', Cypress.env("TEMP_DIR")+'/about')
Create directory
cy.task('filesystem:createFile', Cypress.env("TEMP_DIR")+'/test.html')
Create file
cy.task('filesystem:copy', { from: Cypress.env("TEMP_DIR")+'/about/*', to: '../../images/about' })
Copy files between directories
cy.task('filesystem:path', 'support/tmp')
Get full server path to file or directory
cy.task('filesystem:list', {target: upload_path, mask: '/*.png'})
List the files that match mask in target directory
cy.task('filesystem:read', '../../system/user/config/config.php')
Read the file
cy.task('filesystem:rename', {from: installer_folder, to: '../../system/ee/installer'})
Rename file or directory
Writing your own tests
The test files should have .ee6.js
extension and need to be placed in a folder inside tests/cypress/cypress/integration
directory.
The minimal test file might just consist of it
directive like in the example
it('test something', () => {
cy.log('performing the test...')
})
However if you have more than one test, it’s better to have them organized into groups
context('Test', () => {
it('test something', () => {
cy.log('performing the test...')
})
})
The typical test would try to emulate user performing certain actions and then check the result against what is expected.
It is recommended to keep the tests granular, so if one of the tests fails and the other ones pass you know exactly where to look. However for complex test cases sometimes the procedure needs to be written as one large test; in such case, it is good practice to perform intermediate checks during the test run.