Skip to content

Commit

Permalink
Merge pull request #1901 from TouK/cypress-documentation
Browse files Browse the repository at this point in the history
Cypress (and FE in general) documentation improvement
  • Loading branch information
arkadius authored Jul 12, 2021
2 parents 60e9eae + 92135cb commit b7e9d81
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 32 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ _book/
out/
*.bsp
ui/client/cypress/fixtures/env.json
*.swp
123 changes: 108 additions & 15 deletions ui/client/README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,134 @@
# Prerequisites

## NodeJS and NPM

Make sure you have relatively new nodejs/npm version (see `.nvmrc` for details)

## Package dependencies

Fetch locked package dependencies using:
```
npm ci
```

# Run

You have a few options to provide backend for frontend needs. After each "run" command, frontend will be available at http://localhost:3000.
Below there are described possible options.

## Using backend started with docker

This option requires docker and connection to docker hub registry. It will use `touk/nussknacker` image in `staging-latest` version.
```
npm run start:backend-staging
```

## Using locally started backend

This option uses backend started at http://localhost:8080 . For more information how to start it, take a look at [Backend instruction](../README.md)
```
npm ci && npm start
open http://localhost:3000
npm start
```

## Using external environment

You can also run frontend connected to external environment like https://demo.nussknacker.io . To do that just invoke:
```
npm run start:backend-demo
```
For more options take a look at `package.json`

# Tests

## Unit (jest) tests

```npm test```
```
npm test
```

### Run tests from IntelliJ

`Jest` should work out of the box, just click green arrow.
`Jest` should work out of the box, just click play button.

## E2E (cypress) tests
_You should copy and fill `cypress.env.json.template` into `cypress.env.json` before start._

##### Image snapshots are **OS** and even resolution dependent!
Background: Cypress is a framework for end-to-end frontend tests. It verifies correctness of results using captured image snapshots.
It runs tests in browser connected to our frontend application at http://localhost:3000. It uses some variables available
in `cypress.env.json` like credentials.

> WARNING: Image snapshots are **OS** and even **resolution** dependent! Please add image snapshots captured on unified environment.
### Run cypress tests

There are a few ways to run cypress tests.

#### Using cypress devServer

Before this option you should run backend and frontend - take a look at "Run" chapter.

After execution of:
```
npm run test:e2e:dev
```
you will see cypress devServer. It is useful to see what is done in each test, but it has some drawbacks:
- "Run all specs" option doesn't work correctly
- Produced image snapshots are OS dependent, so you shouldn't use it for purpose of changing captured image snapshots!

#### Using devServer in CLI

This option is similar to option above, but run all tests in CLI and the same - you shouldn't use it for purpose of changing captured image snapshots!
```
npm run test:e2e
```

#### Using Intellij Idea

Thanks to [Cypress Plugin](https://plugins.jetbrains.com/plugin/13819-cypress-support) you can run tests by just clicking play button.

Just like in options above, you should run backend and frontend before and the same - you shouldn't use it for purpose of changing captured image snapshots!

#### Using unified linux environment

This is the correct option if you want to add/modify image snapshots and make sure that it was done in deterministic way.
It runs backend in docker container, frontend connected to this backend and after that it runs cypress tests also in docker container.
```
npm run test:e2e:docker
```

Compare, update (when needed) and commit **image snapshots** made with `BACKEND_DOMAIN` set to url of backend started with `npm run start-backend:docker`
#### Using unified linux environment on already started backend

#### Start server and test (CI) with already running BE
This option is similar to above, but it speeds up test loop. You should run once:
```
npm run start:backend-docker
```

and after that you can run multiple times:
```
npm run test:e2e:linux
```

#### Using unified linux environment with update image snapshots mode enabled

To run cypress test in mode that would update image snapshots, use the same commands as in two options above but with `:update` suffix:
```
npm run test:e2e:docker:update
```
or:
```
npm run test:e2e:linux:update
```

```npm test:e2e:ci```
### Fixing cypress tests

#### Start BE, start FE server and test inside linux image (snapshots for **CI**)
After some changes in frontend it might be needed to rewrite captured image snapshots. The easiest way is to:
1. Run cypress tests using "Run cypress tests using unified linux environment with update image snapshots mode enabled" method
2. Review changes in files e.g. using Intellij Idea changes diff
3. Commit changes or do fixes in scenarios.

```npm test:e2e:docker```
# Internationalization

#### CLI test with running devServer
```npm test:e2e```
We use `react-i18next` package for internalizations. This mechanism has priority of determinining value for given key (`i18next.t(key, default)`):
1. label from `translations/$lng/main.json` which is served at `/assets/locales/$lng/main.json` resource
2. `default` passed as an argument

#### GUI test with running devServer
```npm test:e2e:dev```
File `translations/$lng/main.json` is generated in `prebuild` phase based on defaults. During development (`start` scripts) is removed to avoid confusions.
4 changes: 4 additions & 0 deletions ui/client/cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@
const browserify = require("@cypress/browserify-preprocessor")

module.exports = (on, config) => {
if (process.env.CYPRESS_SNAPSHOT_UPDATE === 'true') {
config.env['cypress-plugin-snapshots'].updateSnapshots = true;
}
require("cypress-plugin-snapshots/plugin").initPlugin(on, config)

require("@cypress/code-coverage/task")(on, config)

const options = browserify.defaultOptions
Expand Down
18 changes: 11 additions & 7 deletions ui/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@
"lint": "eslint --ext .ts,.tsx,.js,.jsx",
"svgo": "svgo --config .svgo.yml",
"check": "npm run check-types && npm run lint -- . --rule 'i18next/no-literal-string: warn'",
"start": "BACKEND_DOMAIN=http://localhost:8080 webpack serve",
"start:backend-docker": "start-server-and-test start-backend:docker http-get://localhost:8080/static/main.html start",
"start:backend-staging": "BACKEND_DOMAIN=https://staging.nussknacker.io webpack serve",
"start:backend-demo": "BACKEND_DOMAIN=https://demo.nussknacker.io webpack serve",
"prestart-backend:docker": "docker pull touk/nussknacker:staging-latest",
"start-backend:docker": "docker run -i -p 8080:8080 -e CONFIG_FORCE_processTypes_streaming_engineConfig_type=stub -e NUSSKNACKER_CONFIG_FILE=/opt/nussknacker/conf/dev-application.conf -P touk/nussknacker:staging-latest",
"@comment translations json has higher priority than default labels in code, so we remove them before each start script, to make development faster": "",
"clean-translations": "rm ./translations/ -rf",
"start": "npm run clean-translations && BACKEND_DOMAIN=http://localhost:8080 webpack serve",
"start:backend-docker": "npm run clean-translations && start-server-and-test start-backend:docker http-get://localhost:8080/static/main.html start",
"start:backend-staging": "npm run clean-translations && BACKEND_DOMAIN=https://staging.nussknacker.io webpack serve",
"start:backend-demo": "npm run clean-translations && BACKEND_DOMAIN=https://demo.nussknacker.io webpack serve",
"start-backend:docker": "docker run -i -p 8080:8080 -e CONFIG_FORCE_processTypes_streaming_engineConfig_type=stub -e NUSSKNACKER_CONFIG_FILE=/opt/nussknacker/conf/dev-application.conf -P touk/nussknacker:staging-latest --pull always",
"pretest": "npm run check",
"test:unit": "jest",
"test:e2e": "cypress run",
"test:e2e:dev": "cypress open",
"test:e2e:linux": "docker run --add-host=host.docker.internal:host-gateway -it -v $PWD:/client -w /client cypress/included:6.8.0 --config baseUrl=http://host.docker.internal:3000",
"test:e2e:docker": "start-server-and-test start:backend-docker http-get://localhost:3000/static/main.html test:e2e:linux",
"test:e2e:dev": "cypress open",
"@comment script versions updating image snapshots": "",
"test:e2e:linux:update": "docker run --add-host=host.docker.internal:host-gateway -it -v $PWD:/client -w /client -e CYPRESS_SNAPSHOT_UPDATE=true cypress/included:6.8.0 --config baseUrl=http://host.docker.internal:3000",
"test:e2e:docker:update": "start-server-and-test start:backend-docker http-get://localhost:3000/static/main.html test:e2e:linux:update",
"coverage": "npx merge-cypress-jest-coverage",
"commit": "lint-staged"
},
Expand Down
27 changes: 17 additions & 10 deletions ui/client/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,6 @@ const GIT_HASH = childProcess.execSync("git log -1 --format=%H").toString()
const GIT_DATE = childProcess.execSync("git log -1 --format=%cd").toString()
const isProd = NODE_ENV === "production"

const smp = new SpeedMeasurePlugin({
disable: true,
outputFormat: "humanVerbose",
loaderTopFiles: 5,
})

const {ModuleFederationPlugin} = webpack.container
const {name} = require("./package.json")
const entry = {
Expand Down Expand Up @@ -53,7 +47,7 @@ const fileLoader = {
},
}

module.exports = smp.wrap({
module.exports = {
mode: NODE_ENV,
optimization: {
splitChunks: {
Expand Down Expand Up @@ -122,6 +116,20 @@ module.exports = smp.wrap({
},
},
},
watchOptions: {
ignored: [
'**/dist',
'**/target',
// ignore vim swap files
'**/*.sw[pon]',
// TODO: separate src/main, src/test and so on
'**/cypress*',
'**/.nyc_output',
'**/jest*',
'**/test*',
'**/*.md',
]
},
},
plugins: [
new MomentLocalesPlugin({
Expand Down Expand Up @@ -150,7 +158,7 @@ module.exports = smp.wrap({
new HtmlWebpackHarddiskPlugin(),
new CopyPlugin({
patterns: [
{from: "translations", to: "assets/locales"},
{from: "translations", to: "assets/locales", noErrorOnMissing: true},
{from: "assets/img/favicon.png", to: "assets/img/favicon.png"},
],
}),
Expand Down Expand Up @@ -181,7 +189,6 @@ module.exports = smp.wrap({
DATE: JSON.stringify(GIT_DATE),
},
}),
// each 10% log entry in separate line - fix for travis no output problem
new ForkTsCheckerWebpackPlugin(),
isProd ? null : new ReactRefreshWebpackPlugin(),
new webpack.ProgressPlugin(progressBar),
Expand Down Expand Up @@ -304,4 +311,4 @@ module.exports = smp.wrap({
},
],
},
})
}

0 comments on commit b7e9d81

Please sign in to comment.