Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cypress (and FE in general) documentation improvement #1901

Merged
merged 5 commits into from
Jul 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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({
},
],
},
})
}