diff --git a/.gitignore b/.gitignore index bc5e543..cdde554 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,8 @@ node_modules/ /.awcache /.cache-loader package-lock.json + +# ignore local cypress artifacts +/cypress/videos/ +/cypress/screenshots/ + diff --git a/cypress.json b/cypress.json new file mode 100644 index 0000000..c704cda --- /dev/null +++ b/cypress.json @@ -0,0 +1,10 @@ +{ + "experimentalStudio": true, + "viewportWidth": 1920, + "viewportHeight": 1080, + "defaultCommandTimeout": 100000, + "responseTimeout": 100000, + "env": { + "host": "http://localhost:8080" + } +} \ No newline at end of file diff --git a/cypress/fixtures/example.json b/cypress/fixtures/example.json new file mode 100644 index 0000000..02e4254 --- /dev/null +++ b/cypress/fixtures/example.json @@ -0,0 +1,5 @@ +{ + "name": "Using fixtures to represent data", + "email": "hello@cypress.io", + "body": "Fixtures are a great way to mock data for responses to routes" +} diff --git a/cypress/integration/index.js b/cypress/integration/index.js new file mode 100644 index 0000000..26464e7 --- /dev/null +++ b/cypress/integration/index.js @@ -0,0 +1 @@ +import 'tdp_publicdb/cypress/integration/'; \ No newline at end of file diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js new file mode 100644 index 0000000..59b2bab --- /dev/null +++ b/cypress/plugins/index.js @@ -0,0 +1,22 @@ +/// +// *********************************************************** +// This example plugins/index.js can be used to load plugins +// +// You can change the location of this file or turn off loading +// the plugins file with the 'pluginsFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/plugins-guide +// *********************************************************** + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) + +/** + * @type {Cypress.PluginConfig} + */ +// eslint-disable-next-line no-unused-vars +module.exports = (on, config) => { + // `on` is used to hook into various events Cypress emits + // `config` is the resolved Cypress config +} diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 0000000..7e0f4f7 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,37 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// + + +// -- This is a parent command -- +Cypress.Commands.add('login', () => { + + // Check if form is visible and the two inputs are not empty (so not to click too fast on the button) + cy.get('.form-signin').should('be.visible'); + cy.get('.form-signin #login_username').invoke('val').should('not.be.empty'); + cy.get('.form-signin #login_password').invoke('val').should('not.be.empty'); + // Add a small wait just for safety + cy.wait(1000); + cy.get('.form-signin button[type="submit"]').click(); + // Check that login disappears + cy.get('.form-signin button[type=submit]').should('not.be.visible'); +}); + +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) diff --git a/cypress/support/index.js b/cypress/support/index.js new file mode 100644 index 0000000..69f8009 --- /dev/null +++ b/cypress/support/index.js @@ -0,0 +1,48 @@ +// *********************************************************** +// This example support/index.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' +import 'tdp_core/cypress/support/commands'; +import 'ordino/cypress/support/commands'; + +// Alternatively you can use CommonJS syntax: +// require('./commands') + + +// Here we define the selector priority for cypress. +// We use Cypress.SelectorPlayground.defaults within itself, in order to define two different selector priorities, +// depending on whether the element has the data-testid attribute. +// This is a little hacky, but works and is the most stable solution. +// Why this works can be founde here: https://github.com/cypress-io/cypress/blob/b6c4ba144cd6ae3d210789bbb69b9aacc6a92094/packages/driver/src/cypress/selector_playground.ts +// If in the future changes happen in cypress, that interfere with this approach, this solution must be changed. + +Cypress.SelectorPlayground.defaults({ + // With onElement we can check whether the element has the data-testid attribute + onElement: (el) => { + if (el.attr('data-testid')) { + // If it has the data-testid attribute then it should only use it in the selector priority. + // This ensures that we get nice outputs in the cypress studio as we intended (hierarchy of data-testid elements). + Cypress.SelectorPlayground.defaults({ + selectorPriority: ['data-testid'], + }) + } else { + // If it does not have it (eg. line up) we use all the available selector types to ensure that a unique selector is returned. + Cypress.SelectorPlayground.defaults({ + selectorPriority: ['data-testid', 'data-cy', 'data-test', 'class', 'tag', 'attributes', 'nth-child', 'id'], + }) + } + }, +}) \ No newline at end of file diff --git a/package.json b/package.json index 5bc44b0..ed0988b 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,9 @@ "release:minor": "npm version minor && npm publish && git push --follow-tags", "release:patch": "npm version patch && npm publish && git push --follow-tags", "predist": "npm run build && npm run docs", - "dist": "mkdir lib && cd dist && tar cvzf ../lib/ordino_public.tar.gz *" + "dist": "mkdir lib && cd dist && tar cvzf ../lib/ordino_public.tar.gz *", + "cy:open": "cypress open", + "cy:run": "cypress run" }, "files": [ "src", @@ -66,6 +68,7 @@ "@types/react-router-dom": "^5.1.7", "@typescript-eslint/eslint-plugin": "^5.9.0", "@typescript-eslint/parser": "^5.9.0", + "cypress": "^9.5.2", "eslint": "^8.7.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-airbnb-typescript": "^16.1.0", @@ -78,6 +81,7 @@ "eslint-plugin-react-hooks": "^4.3.0", "identity-obj-proxy": "~3.0.0", "jest-raw-loader": "~1.0.1", + "local-cypress": "^1.2.5", "prettier": "^2.5.1", "rimraf": "~3.0.2", "shx": "~0.3.3",