scratch-www/test/integration-cypress
2018-11-09 09:17:04 -08:00
..
cypress/smoke-tests Use https for ScratchJR links 2018-11-09 09:17:04 -08:00
.eslintrc Setup Cypress linting 2018-03-22 15:01:51 -04:00
cypress.json Add initial cypress tests 2018-03-21 10:00:23 -04:00
package.json Add initial cypress tests 2018-03-21 10:00:23 -04:00
README.md Clarify README for the Cypress tests more. 2018-03-21 10:44:09 -04:00

Cypress tests

What is this?

Cypress is an end to end testing tool that we are using to do integration tests on Scratch.

It behaves in some ways like selenium but does not use selenium at all. It is simpler to implement, easier to read and includes features that make debugging easier.

Install cypress

To install in the command line you'll need npm installed. Navigate to this folder and run:

npm install

If you would like to install it in other projects run this:

npm install cypress --save-dev

Cypress also has a gui client. To get the gui you can download it from cypress.io.

Run tests

To run all of the tests in chrome from the command line, enter npm run test-all. To run headless enter npm run test-all-headless. This will run through all of the tests in the smoke-tests folder.

To run tests directly, without using npm, enter ./node_modules/.bin/cypress run.

Run a single test file

Append -s ./path/to/test/file (or -spec ./path/to/test/file) to the command to run just that one suite of tests. If using npm run you must add an add an additional -- before the arguments in order to pass them in:

npm run test-all -- -s ./cypress/smoke-tests/the-test-I-want-to-run

###Writing tests Tests are held in functions that take the following form:

it('name of test', function(){
  ...
  ...
  });

Commands that you run in tests almost always start with a cy object which contains functions for going to urls, finding objects on the page, etc. Any objects found are returned, so functions can be chained. For preference chaining should be structured like this:

cy
  .visit("");
cy
  .get('.logo a')
  .click();

get and visit

cy.visit() is the command used for loading web pages. It takes a url string as an argument.

cy.get() is used to find elements on a page. It uses jquery.

This is slightly different from how Selenium does it. For more on how to write tests see the documentation on cypress.io. It is pretty good for the most part.

Promises

Cypress has a built in promise manager and basically already turns every line of code into a promise for you so you can write code like it was synchronous.

Assertions

There are a few ways to put assertions into tests but mainly we use should() which can be put at the end of a chain and takes objects passed in from the chain as the first element to compare. should() can take two arguments, a comparison type and what to compare it to, or one argument that is a chainer similar to how it is done using Chai.

For more information check out the Cypress documentation on these topics.

Assertions aren't strictly necessary since a test will fail if any step in it fails. They are useful for making sure that you have gotten to the right page.

Suites

Tests can be organized in suites using describe:

describe('name of suite', function(){
  it('test 1', function(){
    ...
  });

  it('test 2', function(){
    ...
  })

});

Supported Browsers

Currently it defaults to running headless in Electron but it also supports Chrome.

Add --browser chrome to the command line when running the tests to run in chrome.

Firefox is not yet supported as of March 2018 but they are working on it.

Environment variables

To pass in environment variables, such as USERNAME and PASSWORD for a test user you add them before calling cypress run by adding CYPRESS_ before the variable name.

It will look like this: CYPRESS_USERNAME=made-up-name

Alternatively you can add to the command --env USERNAME=made-up-name, but this is not preferred. If following npm run you must add an aditional -- before adding arguments similar to how it is described in Run a single test (above).

configuration (cypress.json)

Cypress uses a configuration file ./cypress.json which contains environment variables and other information.

To access any variable you put in the configuration file from within your test code type Cypress.config('property_you_want').

There is a special case for accessing environment variables stored in the env : {} object: Cypress.env('environment_variable_you_want') This is also how you access any environment variables passed in from the command line.

more configuration (cypress.env.json)

You can add configuration or environment variables in the same way listed above to another json file called cypress.env.json. This file will overwrite whatever is in cypress.json. This file is untracked in git, so is useful for information that you don't want shared, such as username and password environment variables.

Base URL

Cypress hates it when you use a base url as an environment variable. If you try it gives strange results. The base URL is set in cypress.json as its own variable "baseUrl" : "https://scratch.ly".

This is automatically appended to visit() command arguments which are used to load webpages. It appends it, so you need to include a string as an argument so you would have to write it as visit("") or visit("/").

To overwrite the baseUrl variable from the command line you need to change it just like it is an environment variable (above): CYPRESS_baseUrl=https://scratch.mit.ed.

Alternatively you could change it like this after calling cypress : --config baseUrl=https://scratch.mit.edu

.only

If you would like to only run one test in a file you can change it(...) to it.only(...) and it will run just that one test.

Similarly you can run a suite of tests from a file by adding .only to a describe(...) function so it looks like this: describe.only(...). This will run all tests in that suite and no others.

ONLY USE ONE ONLY

If you use more than one .only anywhere in the file it will give you unpredictable results. This includes if you put one on a collection and one on an individual test.

.skip

If you would like to skip a test in a file you can cahnge the it(...) to it.skip(...) similarly to how you use only (above).

Skip can be used on individual tests and on suites:

describe.skip(...)

You can use any number of skips. If you skip a suite it till skip all of the tests inside.

Cookies

By default Cypress deletes all cookies between tests. This means that if you want to remain signed in you must manually keep the session data cookie by including this code in a beforeEach() function:

Cypress.Cookies.preserveOnce('scratchsessionsid')

The GUI

The gui, which can be downloaded at cypress.io, is useful especially if you want to look back through the state of tests after they have been run. If you run in chrome from the command line the browser closes at the end of the tests.

The gui captures the state of the DOM at each step of each test. You can mouse over a step and it will show you want was happening at that time. If you click on the step you can even inspect elements, which is useful for debugging.