From 2ce848d638654a170375a5b20aae9a8afe9238b9 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Thu, 25 Jul 2019 10:31:42 -0400 Subject: [PATCH] feat: add cy.request example that passes data to the second request (#275) * Add cy.request example that pass data around * copy new tests to the HTML --- app/commands/network-requests.html | 52 ++++++++++++++++++ .../examples/network_requests.spec.js | 54 +++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/app/commands/network-requests.html b/app/commands/network-requests.html index 0a511721e..02322d229 100644 --- a/app/commands/network-requests.html +++ b/app/commands/network-requests.html @@ -118,8 +118,60 @@

cy.request()

expect(response.body).to.have.length(500) expect(response).to.have.property('headers') expect(response).to.have.property('duration') + }) +

A request can pass the response data to the next request.

+
// first, let's find out the userId of the first user we have
+cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
+  .its('body.0') // yields the first element of the returned list
+  .then((user) => {
+    expect(user).property('id').to.be.a('number')
+    // make a new post on behalf of the user
+    cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
+      userId: user.id,
+      title: 'Cypress Test Runner',
+      body: 'Fast, easy and reliable testing for anything that runs in a browser.',
+    })
+  })
+  // note that the value here is the returned value of the 2nd request
+  // which is the new post object
+  .then((response) => {
+    expect(response).property('status').to.equal(201) // new entity created
+    expect(response).property('body').to.contain({
+      id: 101, // there are already 100 posts, so new entity gets id 101
+      title: 'Cypress Test Runner',
+    })
+    // we don't know the user id here - since it was in above closure
+    // so in this test just confirm that the property is there
+    expect(response.body).property('userId').to.be.a('number')
+  })
+ +

A good idea is to save the response data to be used later in the shared test context.

+
cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
+  .its('body.0') // yields the first element of the returned list
+  .as('user') // saves the object in the test context
+  .then(function () {
+    // NOTE 👀
+    //  By the time this callback runs the "as('user')" command
+    //  has saved the user object in the test context.
+    //  To access the test context we need to use
+    //  the "function () { ... }" callback form,
+    //  otherwise "this" points at a wrong or undefined object!
+    cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
+      userId: this.user.id,
+      title: 'Cypress Test Runner',
+      body: 'Fast, easy and reliable testing for anything that runs in a browser.',
+    })
+    .its('body').as('post') // save the new post from the response
+  })
+  .then(function () {
+    // When this callback runs, both "cy.request" API commands have finished
+    // and the test context has "user" and "post" objects set.
+    // Let's verify them.
+    expect(this.post, 'post has the right user id')
+      .property('userId').to.equal(this.user.id)
   })
+
diff --git a/cypress/integration/examples/network_requests.spec.js b/cypress/integration/examples/network_requests.spec.js index a2dda0dbe..a75797cfb 100644 --- a/cypress/integration/examples/network_requests.spec.js +++ b/cypress/integration/examples/network_requests.spec.js @@ -87,6 +87,60 @@ context('Network Requests', () => { }) }) + it('cy.request() - pass result to the second request', () => { + // first, let's find out the userId of the first user we have + cy.request('https://jsonplaceholder.cypress.io/users?_limit=1') + .its('body.0') // yields the first element of the returned list + .then((user) => { + expect(user).property('id').to.be.a('number') + // make a new post on behalf of the user + cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', { + userId: user.id, + title: 'Cypress Test Runner', + body: 'Fast, easy and reliable testing for anything that runs in a browser.', + }) + }) + // note that the value here is the returned value of the 2nd request + // which is the new post object + .then((response) => { + expect(response).property('status').to.equal(201) // new entity created + expect(response).property('body').to.contain({ + id: 101, // there are already 100 posts, so new entity gets id 101 + title: 'Cypress Test Runner', + }) + // we don't know the user id here - since it was in above closure + // so in this test just confirm that the property is there + expect(response.body).property('userId').to.be.a('number') + }) + }) + + it('cy.request() - save response in the shared test context', () => { + // https://on.cypress.io/variables-and-aliases + cy.request('https://jsonplaceholder.cypress.io/users?_limit=1') + .its('body.0') // yields the first element of the returned list + .as('user') // saves the object in the test context + .then(function () { + // NOTE 👀 + // By the time this callback runs the "as('user')" command + // has saved the user object in the test context. + // To access the test context we need to use + // the "function () { ... }" callback form, + // otherwise "this" points at a wrong or undefined object! + cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', { + userId: this.user.id, + title: 'Cypress Test Runner', + body: 'Fast, easy and reliable testing for anything that runs in a browser.', + }) + .its('body').as('post') // save the new post from the response + }) + .then(function () { + // When this callback runs, both "cy.request" API commands have finished + // and the test context has "user" and "post" objects set. + // Let's verify them. + expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id) + }) + }) + it('cy.route() - route responses to matching requests', () => { // https://on.cypress.io/route