Skip to content

Commit 9ab0ca3

Browse files
authored
add example with dynamic data fetched in the plugin (#681)
1 parent 645f4f5 commit 9ab0ca3

File tree

7 files changed

+284
-27
lines changed

7 files changed

+284
-27
lines changed

examples/fundamentals__dynamic-tests/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Sometimes you want to iterate through a list of items, and for each item create
55
- run same test against different viewport resolutions
66
- run same test against different sub-domains of your site
77
- generate tests based on the fetched data
8+
- get the dynamic data from the plugin file before the tests start
89

910
## Note
1011

@@ -13,6 +14,7 @@ Sometimes the data to generate tests might be dynamic and come from an external
1314
1. you can fetch data using a script that runs _before_ Cypress starts. Save the results as a JSON file and load data using `require`. This has an advantage that the data does not change while running the tests, making debugging simpler. See suite called "generated from fixture" for an example.
1415
2. you can fetch the dynamic data before the tests and save as a local variable or context property, then have multiple tests assert against dynamic data items.
1516
3. you can get the data to use to create dynamic tests using [`cy.task`](https://on.cypress.io/task)
17+
4. you can get the data during the plugin file start and place the result into `Cypress.env()` object to pass to the specs
1618

1719
## Examples
1820

@@ -24,3 +26,6 @@ In these repo you can find:
2426
- [cypress/integration/fixture-spec.js](cypress/integration/fixture-spec.js) uses `require` to load JSON fixture file and generates tests for each item from the fixture.
2527
- [cypress/integration/request-spec.js](cypress/integration/request-spec.js) fetches a list of users from an external API endpoint and creates a test for each user
2628
- [cypress/integration/task-spec.js](cypress/integration/task-spec.js) gets a list of items by calling [`cy.task`](https://on.cypress.io/task) and then generating a test for each item
29+
- [cypress/integration/plugin-spec.js](./cypress/integration/plugin-spec.js) gets the list of users on start up, see [cypress/plugins/index.js](./cypress/plugins/index.js) file. You can see the fetched list in the `Cypress.env()` object
30+
31+
![Cypress env object with fetched users](./images/users.png)
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/// <reference types="cypress" />
2+
3+
// If we do NOT know the expected number of items we can grab them
4+
// before the spec starts running using the plugin file.
5+
// The plugin file places the dynamic list into "Cypress.env()" object
6+
describe('Test for each user', { retries: 2 }, () => {
7+
// Cypress.env() object is set by the time the tests start
8+
const users = Cypress.env('users')
9+
10+
it('has valid users', () => {
11+
expect(users).to.be.an('array').and.not.be.empty
12+
})
13+
14+
users.forEach((user) => {
15+
it(`has info for user ${user.id}: ${user.email}`, () => {
16+
// confirm the user information
17+
const url = `https://jsonplaceholder.cypress.io/users/${user.id}`
18+
19+
// confirm the endpoint returns the "user" object
20+
cy.request(url).its('body').should((data) => {
21+
// confirm each property explicitly
22+
// if any property is missing we will get nice Command Log
23+
// history showing the matching properties
24+
Object.keys(user).forEach((key) => {
25+
expect(data).to.have.property(key, user[key])
26+
})
27+
})
28+
})
29+
})
30+
})

examples/fundamentals__dynamic-tests/cypress/integration/request-spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('dynamic users using request', { retries: 2 }, () => {
77

88
before(() => {
99
// receive the dynamic list of users
10-
cy.request('https://jsonplaceholder.cypress.io/users?limit=3')
10+
cy.request('https://jsonplaceholder.cypress.io/users?_limit=10')
1111
.its('body')
1212
.should('have.length', 10)
1313
.invoke('slice', 0, 3)

examples/fundamentals__dynamic-tests/cypress/plugins/index.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,35 @@
88
// https://on.cypress.io/plugins-guide
99
// ***********************************************************
1010

11+
/* eslint-disable no-console */
12+
const got = require('got')
13+
const _ = require('lodash')
14+
1115
// This function is called when a project is opened or re-opened (e.g. due to
1216
// the project's config changing)
1317

14-
module.exports = (on, config) => {
18+
module.exports = async (on, config) => {
1519
// `on` is used to hook into various events Cypress emits
1620
// `config` is the resolved Cypress config
21+
1722
on('task', {
1823
getData () {
1924
return ['a', 'b', 'c']
2025
},
2126
})
27+
28+
// you can fetch the dynamic list to use to generate the data
29+
// before any tests run (even before the browser opens)
30+
const { body } = await got('https://jsonplaceholder.cypress.io/users?_limit=5', {
31+
responseType: 'json',
32+
})
33+
34+
// pass the data through the Cypress config object
35+
// by storing it in the environment object.
36+
// we are only interested in a few properties in each user object
37+
config.env.users = _.map(body, (user) => _.pick(user, 'id', 'name', 'email'))
38+
console.table(config.env.users)
39+
40+
// IMPORTANT: return the updated config object
41+
return config
2242
}
Loading

0 commit comments

Comments
 (0)