diff --git a/README.md b/README.md index 95cfe46dc..ed367cc33 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Recipe | Description [Handling errors](./examples/fundamentals__errors) | Handling thrown errors and unhandled promise rejections [Dynamic tests](./examples/fundamentals__dynamic-tests) | Create tests dynamically from JSON data [Dynamic tests from CSV](./examples/fundamentals__dynamic-tests-from-csv) | Create tests dynamically from CSV file +[Dynamic tests from CSV using Webpack Preprocessor](./examples/fundamentals__dynamic-tests-from-csv-using-webpack) | Create tests dynamically from CSV file without having to specify them in cypress.config.js [Dynamic tests from API](./examples/fundamentals__dynamic-tests-from-api) | Create tests dynamically by calling an external API [Fixtures](./examples/fundamentals__fixtures) | Loading single or multiple fixtures [Adding Custom Commands](./examples/fundamentals__add-custom-command) | Write your own custom commands using JavaScript with correct types for IntelliSense to work diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md new file mode 100644 index 000000000..c645a3f77 --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/README.md @@ -0,0 +1,52 @@ +# Dynamic tests from CSV data using Webpack Preprocessor + +There are times when you need to generate tests using external sources such as CSV. We cannot load the CSV file directly from the spec file (unless we have a special CSV file bundler), and we cannot use the `cy.readFile` command - because by then it is too late to define new tests. However we can use `@cypress/webpack-preprocessor` and `csv-loader` thus giving us the ability to load the files and best part of you dont have to specify them in the your `cypress.config.js` each time a new CSV file is to be used. + +We can do this by adding those two new devDependencies in `package.json` and then load them in [setupNodeEvents](cypress.config.js) function. This config object will be available in each spec file. You then can get the list of records before the tests are created, see [csv-spec-using-WebpackLoader.cy.js](./cypress/e2e/csv-spec-using-WebpackLoader.cy.js) + +```js +//package.json +"devDependencies": { + "@cypress/webpack-preprocessor": "^5.17.1", + "csv-loader": "^3.0.5" + } + +// `setupNodeEvents` +const webpackPreprocessor = require('@cypress/webpack-preprocessor') +const { defineConfig } = require('cypress') +module.exports = defineConfig({ + e2e: { + supportFile: false, + setupNodeEvents (on, config) { + const webpackDefaults = webpackPreprocessor.defaultOptions + webpackDefaults.webpackOptions.module.rules.push({ + test: /\.csv$/, + loader: 'csv-loader', + options: { + dynamicTyping: true, + header: true, + skipEmptyLines: true, + }, + }) + on('file:preprocessor', webpackPreprocessor(webpackDefaults)) + }, + }, +}) + + +// cypress/e2e/csv-spec.cy.js +const csvUsers = require('../fixtures/users.csv') + +csvUsers.forEach((user) => { + it(`has the user ${user['first name']} ${user['last name']}`, () => { + cy.contains('td[data-cy=userId]', user['user id']) + .parent('tr') + .within(() => { + cy.contains('td[data-cy=firstName]', user['first name']) + cy.contains('td[data-cy=lastName]', user['last name']) + }) + }) + }) +``` + +![CSV spec](./images/csv-using-WebpackLoader.png) diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js new file mode 100644 index 000000000..1a2b84992 --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress.config.js @@ -0,0 +1,27 @@ +/* eslint-disable no-console */ +const webpackPreprocessor = require('@cypress/webpack-preprocessor') +const { defineConfig } = require('cypress') + +// This function is called when a project is opened or re-opened (e.g. due to +// the project's config changing) +module.exports = defineConfig({ + e2e: { + supportFile: false, + setupNodeEvents (on, config) { + // implement node event listeners here + const webpackDefaults = webpackPreprocessor.defaultOptions + + webpackDefaults.webpackOptions.module.rules.push({ + test: /\.csv$/, + loader: 'csv-loader', + options: { + dynamicTyping: true, + header: true, + skipEmptyLines: true, + }, + }) + + on('file:preprocessor', webpackPreprocessor(webpackDefaults)) + }, + }, +}) diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js new file mode 100644 index 000000000..cd3511a16 --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/e2e/csv-spec-using-WebpackLoader.cy.js @@ -0,0 +1,20 @@ +/// + +describe('Users from CSV', () => { + const csvUsers = require('../fixtures/users.csv') + + beforeEach(() => { + cy.visit('index.html') + }) + + csvUsers.forEach((user) => { + it(`has the user ${user['first name']} ${user['last name']}`, () => { + cy.contains('td[data-cy=userId]', user['user id']) + .parent('tr') + .within(() => { + cy.contains('td[data-cy=firstName]', user['first name']) + cy.contains('td[data-cy=lastName]', user['last name']) + }) + }) + }) +}) diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/fixtures/users.csv b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/fixtures/users.csv new file mode 100644 index 000000000..ef9559d75 --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/cypress/fixtures/users.csv @@ -0,0 +1,4 @@ +user id,first name,last name +101,Joe,Smith +102,Mary,Jane +103,Adam,Peterson diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/images/csv-using-WebpackLoader.png b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/images/csv-using-WebpackLoader.png new file mode 100644 index 000000000..46447401a Binary files /dev/null and b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/images/csv-using-WebpackLoader.png differ diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/index.html b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/index.html new file mode 100644 index 000000000..ba7a45f29 --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/index.html @@ -0,0 +1,27 @@ + +

Users table

+ + + + + + + + + + + + + + + + + + + + + + + +
IDFirst nameLast name
101JoeSmith
102MaryJane
103AdamPeterson
+ diff --git a/examples/fundamentals__dynamic-tests-from-csv-using-webpack/package.json b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/package.json new file mode 100644 index 000000000..2a911bc4f --- /dev/null +++ b/examples/fundamentals__dynamic-tests-from-csv-using-webpack/package.json @@ -0,0 +1,16 @@ +{ + "name": "dynamic-tests-from-csv", + "version": "1.0.0", + "description": "Create Cypress tests dynamically from CSV data", + "private": true, + "scripts": { + "cypress:open": "../../node_modules/.bin/cypress open", + "cypress:run": "../../node_modules/.bin/cypress run", + "test:ci": "npm run cypress:run", + "test:ci:record": "npm run cypress:run -- --record" + }, + "devDependencies": { + "@cypress/webpack-preprocessor": "^5.17.1", + "csv-loader": "^3.0.5" + } +}