mirror of
https://bitbucket.org/wisemapping/wisemapping-frontend.git
synced 2024-11-14 03:07:57 +01:00
Merged in feat/cypress (pull request #1)
Adding cypress integration into the webapp * Merge branch 'master' into feat/cypress * moving the config files to ts * updating from master * adding pipeline config * updating the cypress base image to use the same node version * moving node to 14.15.4 * unifying all the tasks into one step * using cypress base image for the whole pipeline for now * removing cypress examples * adding readme for tests Approved-by: Ezequiel Bergamaschi
This commit is contained in:
parent
b7c5ff3940
commit
d4094c4b27
@ -4,16 +4,23 @@
|
|||||||
# The workflow allows running tests and code linting on the default branch.
|
# The workflow allows running tests and code linting on the default branch.
|
||||||
|
|
||||||
# Node LTS
|
# Node LTS
|
||||||
image: node:14.15.5
|
image: cypress/base:14.15.4
|
||||||
|
|
||||||
pipelines:
|
pipelines:
|
||||||
default:
|
default:
|
||||||
- parallel:
|
- parallel:
|
||||||
- step:
|
- step:
|
||||||
name: Build and Test
|
name: Build and test
|
||||||
caches:
|
caches:
|
||||||
- node
|
- node
|
||||||
|
- npm
|
||||||
|
- cypress
|
||||||
script:
|
script:
|
||||||
- yarn install
|
- yarn install
|
||||||
- yarn build
|
- yarn build
|
||||||
- yarn lint
|
- yarn lint
|
||||||
|
- yarn test
|
||||||
|
definitions:
|
||||||
|
caches:
|
||||||
|
npm: $HOME/.npm
|
||||||
|
cypress: $HOME/.cache/Cypress
|
@ -5,7 +5,7 @@
|
|||||||
"build": "lerna run build",
|
"build": "lerna run build",
|
||||||
"clean": "lerna clean && rm -rf node_modules",
|
"clean": "lerna clean && rm -rf node_modules",
|
||||||
"lint": "lerna run lint",
|
"lint": "lerna run lint",
|
||||||
"test": "lerna run test"
|
"test": "lerna run test --stream"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -22,7 +22,7 @@
|
|||||||
"Ezequiel Bergamaschi"
|
"Ezequiel Bergamaschi"
|
||||||
],
|
],
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "=14.15.5"
|
"node": "=14.15.4"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
3
packages/webapp/.gitignore
vendored
Normal file
3
packages/webapp/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cypress/screenshots
|
||||||
|
cypress/videos
|
||||||
|
cypress/downloads
|
4
packages/webapp/cypress.json
Normal file
4
packages/webapp/cypress.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"video": false,
|
||||||
|
"videoUploadOnPasses": false
|
||||||
|
}
|
26
packages/webapp/cypress/README.md
Normal file
26
packages/webapp/cypress/README.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Running tests with cypress.
|
||||||
|
|
||||||
|
For details on why we picked Cypress, check the following [PR](https://bitbucket.org/wisemapping/wisemapping-react/pull-requests/1)
|
||||||
|
|
||||||
|
Check the [Cypress docs](https://docs.cypress.io/guides/overview/why-cypress.html) for more information
|
||||||
|
|
||||||
|
## How to run it
|
||||||
|
|
||||||
|
- To run the test cases headless run: `yarn test`
|
||||||
|
- To debug the tests you can use cypress interactive UI by running `yarn cypress open` (You will need to have the UI running in a separate terminal `yarn start`)
|
||||||
|
|
||||||
|
|
||||||
|
## How to write a new test case
|
||||||
|
|
||||||
|
Any new test cases should be added under the `cypress/integration` folder. Aim to group similar test cases in one file.
|
||||||
|
|
||||||
|
If any stub/mock is needed, those should be added to `cypress/fixtures` folder. Cypress has a [built in way](https://docs.cypress.io/api/commands/fixture.html#Usage) of using those.
|
||||||
|
|
||||||
|
We use `data-testid` as a practice to define selectors in the code and we leverage the [Cypress Testing Library plugin](https://testing-library.com/docs/cypress-testing-library/intro/) to find the elements in the tests.
|
||||||
|
- We leverage a `data-testid` or selecting by text (`findAllByText`, `findByText`) to make sure the test cases are decoupled from the implementation.
|
||||||
|
|
||||||
|
We leverage the [Page Object Pattern](https://martinfowler.com/bliki/PageObject.html) to abstract away selectors and actions and simplify changes required to future refactors. Take a look to any example under the `cypress/pageObject` folder to see how that pattern is implemented.
|
||||||
|
|
||||||
|
Finally any common functionality such as for example `login` should be abstracted into a command. CY Commands can be added into the `cypress/support` folder. Feel free to group similar commands into files (You only need to make sure those get imported into the `cypress/support/index.ts` file)
|
||||||
|
|
||||||
|
Happy testing!!!
|
16
packages/webapp/cypress/integration/maps.test.ts
Normal file
16
packages/webapp/cypress/integration/maps.test.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import MapsPage from "../pageObject/MapsPage";
|
||||||
|
|
||||||
|
context("Maps Page", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.visit("http://localhost:3000/c/maps");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should load the maps page", () => {
|
||||||
|
MapsPage.isLoaded();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should open the create dialog", () => {
|
||||||
|
MapsPage.create();
|
||||||
|
MapsPage.isCreateDialogVisible();
|
||||||
|
});
|
||||||
|
});
|
14
packages/webapp/cypress/pageObject/MapsPage.ts
Normal file
14
packages/webapp/cypress/pageObject/MapsPage.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export default class MapsPage {
|
||||||
|
static isLoaded() {
|
||||||
|
return cy.findByTestId("create");
|
||||||
|
}
|
||||||
|
|
||||||
|
static create() {
|
||||||
|
return cy.findByTestId("create").click();
|
||||||
|
}
|
||||||
|
|
||||||
|
static isCreateDialogVisible() {
|
||||||
|
//TODO move to findByText when the double create dialog issue is solved
|
||||||
|
return cy.findAllByText("Create a new mindmap");
|
||||||
|
}
|
||||||
|
}
|
7
packages/webapp/cypress/plugins/index.ts
Normal file
7
packages/webapp/cypress/plugins/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* @type {Cypress.PluginConfig}
|
||||||
|
*/
|
||||||
|
module.exports = (on, config) => {
|
||||||
|
// `on` is used to hook into various events Cypress emits
|
||||||
|
// `config` is the resolved Cypress config
|
||||||
|
}
|
1
packages/webapp/cypress/support/commands.ts
Normal file
1
packages/webapp/cypress/support/commands.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import '@testing-library/cypress/add-commands'
|
1
packages/webapp/cypress/support/index.ts
Normal file
1
packages/webapp/cypress/support/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
import './commands'
|
@ -7,6 +7,8 @@
|
|||||||
"build": "webpack --config webpack.prod.js",
|
"build": "webpack --config webpack.prod.js",
|
||||||
"build-dev": "webpack --config webpack.dev.js",
|
"build-dev": "webpack --config webpack.dev.js",
|
||||||
"lint": "eslint src",
|
"lint": "eslint src",
|
||||||
|
"cy:run": "cypress run",
|
||||||
|
"test": "start-server-and-test start http-get://localhost:3000 cy:run",
|
||||||
"extract": "formatjs extract",
|
"extract": "formatjs extract",
|
||||||
"compile": "formatjs compile"
|
"compile": "formatjs compile"
|
||||||
},
|
},
|
||||||
@ -16,6 +18,8 @@
|
|||||||
"private": false,
|
"private": false,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@formatjs/cli": "^2.13.15",
|
"@formatjs/cli": "^2.13.15",
|
||||||
|
"@testing-library/cypress": "^7.0.3",
|
||||||
|
"@types/testing-library__cypress": "^5.0.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
"@typescript-eslint/eslint-plugin": "^4.8.1",
|
||||||
"@typescript-eslint/parser": "^4.8.1",
|
"@typescript-eslint/parser": "^4.8.1",
|
||||||
"brotli-webpack-plugin": "^1.1.0",
|
"brotli-webpack-plugin": "^1.1.0",
|
||||||
@ -23,6 +27,7 @@
|
|||||||
"compression-webpack-plugin": "^7.1.2",
|
"compression-webpack-plugin": "^7.1.2",
|
||||||
"copy-webpack-plugin": "^7.0.0",
|
"copy-webpack-plugin": "^7.0.0",
|
||||||
"css-loader": "^5.0.1",
|
"css-loader": "^5.0.1",
|
||||||
|
"cypress": "^6.5.0",
|
||||||
"eslint": "^7.14.0",
|
"eslint": "^7.14.0",
|
||||||
"eslint-plugin-react": "^7.21.5",
|
"eslint-plugin-react": "^7.21.5",
|
||||||
"eslint-plugin-react-hooks": "^4.2.0",
|
"eslint-plugin-react-hooks": "^4.2.0",
|
||||||
@ -56,6 +61,7 @@
|
|||||||
"react-redux": "^7.2.2",
|
"react-redux": "^7.2.2",
|
||||||
"react-router": "^5.1.8",
|
"react-router": "^5.1.8",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
|
"start-server-and-test": "^1.12.0",
|
||||||
"styled-components": "^5.1.7"
|
"styled-components": "^5.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,6 +145,7 @@ const MapsPage = (): ReactElement => {
|
|||||||
<Toolbar>
|
<Toolbar>
|
||||||
<Tooltip arrow={true} title={intl.formatMessage({ id: 'maps.create-tooltip', defaultMessage: 'Create a New Map' })}>
|
<Tooltip arrow={true} title={intl.formatMessage({ id: 'maps.create-tooltip', defaultMessage: 'Create a New Map' })}>
|
||||||
<Button color="primary"
|
<Button color="primary"
|
||||||
|
data-testid="create"
|
||||||
size="medium"
|
size="medium"
|
||||||
variant="contained"
|
variant="contained"
|
||||||
type="button"
|
type="button"
|
||||||
|
Loading…
Reference in New Issue
Block a user