network_requests.spec.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /// <reference types="cypress" />
  2. context('Network Requests', () => {
  3. beforeEach(() => {
  4. cy.visit('https://example.cypress.io/commands/network-requests')
  5. })
  6. // Manage HTTP requests in your app
  7. it('cy.request() - make an XHR request', () => {
  8. // https://on.cypress.io/request
  9. cy.request('https://jsonplaceholder.cypress.io/comments')
  10. .should((response) => {
  11. expect(response.status).to.eq(200)
  12. // the server sometimes gets an extra comment posted from another machine
  13. // which gets returned as 1 extra object
  14. expect(response.body).to.have.property('length').and.be.oneOf([500, 501])
  15. expect(response).to.have.property('headers')
  16. expect(response).to.have.property('duration')
  17. })
  18. })
  19. it('cy.request() - verify response using BDD syntax', () => {
  20. cy.request('https://jsonplaceholder.cypress.io/comments')
  21. .then((response) => {
  22. // https://on.cypress.io/assertions
  23. expect(response).property('status').to.equal(200)
  24. expect(response).property('body').to.have.property('length').and.be.oneOf([500, 501])
  25. expect(response).to.include.keys('headers', 'duration')
  26. })
  27. })
  28. it('cy.request() with query parameters', () => {
  29. // will execute request
  30. // https://jsonplaceholder.cypress.io/comments?postId=1&id=3
  31. cy.request({
  32. url: 'https://jsonplaceholder.cypress.io/comments',
  33. qs: {
  34. postId: 1,
  35. id: 3,
  36. },
  37. })
  38. .its('body')
  39. .should('be.an', 'array')
  40. .and('have.length', 1)
  41. .its('0') // yields first element of the array
  42. .should('contain', {
  43. postId: 1,
  44. id: 3,
  45. })
  46. })
  47. it('cy.request() - pass result to the second request', () => {
  48. // first, let's find out the userId of the first user we have
  49. cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
  50. .its('body') // yields the response object
  51. .its('0') // yields the first element of the returned list
  52. // the above two commands its('body').its('0')
  53. // can be written as its('body.0')
  54. // if you do not care about TypeScript checks
  55. .then((user) => {
  56. expect(user).property('id').to.be.a('number')
  57. // make a new post on behalf of the user
  58. cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
  59. userId: user.id,
  60. title: 'Cypress Test Runner',
  61. body: 'Fast, easy and reliable testing for anything that runs in a browser.',
  62. })
  63. })
  64. // note that the value here is the returned value of the 2nd request
  65. // which is the new post object
  66. .then((response) => {
  67. expect(response).property('status').to.equal(201) // new entity created
  68. expect(response).property('body').to.contain({
  69. title: 'Cypress Test Runner',
  70. })
  71. // we don't know the exact post id - only that it will be > 100
  72. // since JSONPlaceholder has built-in 100 posts
  73. expect(response.body).property('id').to.be.a('number')
  74. .and.to.be.gt(100)
  75. // we don't know the user id here - since it was in above closure
  76. // so in this test just confirm that the property is there
  77. expect(response.body).property('userId').to.be.a('number')
  78. })
  79. })
  80. it('cy.request() - save response in the shared test context', () => {
  81. // https://on.cypress.io/variables-and-aliases
  82. cy.request('https://jsonplaceholder.cypress.io/users?_limit=1')
  83. .its('body').its('0') // yields the first element of the returned list
  84. .as('user') // saves the object in the test context
  85. .then(function () {
  86. // NOTE 👀
  87. // By the time this callback runs the "as('user')" command
  88. // has saved the user object in the test context.
  89. // To access the test context we need to use
  90. // the "function () { ... }" callback form,
  91. // otherwise "this" points at a wrong or undefined object!
  92. cy.request('POST', 'https://jsonplaceholder.cypress.io/posts', {
  93. userId: this.user.id,
  94. title: 'Cypress Test Runner',
  95. body: 'Fast, easy and reliable testing for anything that runs in a browser.',
  96. })
  97. .its('body').as('post') // save the new post from the response
  98. })
  99. .then(function () {
  100. // When this callback runs, both "cy.request" API commands have finished
  101. // and the test context has "user" and "post" objects set.
  102. // Let's verify them.
  103. expect(this.post, 'post has the right user id').property('userId').to.equal(this.user.id)
  104. })
  105. })
  106. it('cy.intercept() - route responses to matching requests', () => {
  107. // https://on.cypress.io/intercept
  108. let message = 'whoa, this comment does not exist'
  109. // Listen to GET to comments/1
  110. cy.intercept('GET', '**/comments/*').as('getComment')
  111. // we have code that gets a comment when
  112. // the button is clicked in scripts.js
  113. cy.get('.network-btn').click()
  114. // https://on.cypress.io/wait
  115. cy.wait('@getComment').its('response.statusCode').should('be.oneOf', [200, 304])
  116. // Listen to POST to comments
  117. cy.intercept('POST', '**/comments').as('postComment')
  118. // we have code that posts a comment when
  119. // the button is clicked in scripts.js
  120. cy.get('.network-post').click()
  121. cy.wait('@postComment').should(({ request, response }) => {
  122. expect(request.body).to.include('email')
  123. expect(request.headers).to.have.property('content-type')
  124. expect(response && response.body).to.have.property('name', 'Using POST in cy.intercept()')
  125. })
  126. // Stub a response to PUT comments/ ****
  127. cy.intercept({
  128. method: 'PUT',
  129. url: '**/comments/*',
  130. }, {
  131. statusCode: 404,
  132. body: { error: message },
  133. headers: { 'access-control-allow-origin': '*' },
  134. delayMs: 500,
  135. }).as('putComment')
  136. // we have code that puts a comment when
  137. // the button is clicked in scripts.js
  138. cy.get('.network-put').click()
  139. cy.wait('@putComment')
  140. // our 404 statusCode logic in scripts.js executed
  141. cy.get('.network-put-comment').should('contain', message)
  142. })
  143. })