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

Dynamic test from CSV using Webpack loader #834

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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))
},
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/// <reference types="cypress" />

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'])
})
})
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user id,first name,last name
101,Joe,Smith
102,Mary,Jane
103,Adam,Peterson
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<body>
<h1>Users table</h1>
<table>
<tbody>
<tr>
<th>ID</th>
<th>First name</th>
<th>Last name</th>
</tr>
<tr>
<td data-cy="userId">101</td>
<td data-cy="firstName">Joe</td>
<td data-cy="lastName">Smith</td>
</tr>
<tr>
<td data-cy="userId">102</td>
<td data-cy="firstName">Mary</td>
<td data-cy="lastName">Jane</td>
</tr>
<tr>
<td data-cy="userId">103</td>
<td data-cy="firstName">Adam</td>
<td data-cy="lastName">Peterson</td>
</tr>
</tbody>
</table>
</body>
Original file line number Diff line number Diff line change
@@ -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"
}
}