{"_id":"56902ba918c3920d00be8b55","parentDoc":null,"user":"568fffce769f210d0013258f","category":{"_id":"569002f19ebef90d0087289d","pages":["56900352769f210d00132595","5690047121fcf0190071d943","569004924719c119002ce654","569004ceb700ce0d002f4b94","569023e518c3920d00be8b37","569023f748df220d004ca215","5690240af7eb9a0d00f4465d","5690241b48df220d004ca217","5690243e48df220d004ca219","56902453741e9c0d00af2fb5","56902463efcc380d0043a5a1","5690247b18c3920d00be8b39","56902492f7eb9a0d00f4465f","569024a16c49d70d00f18075","569024b2efcc380d0043a5a3","569024cc48df220d004ca21b","569024ea18c3920d00be8b3b","5690258618c3920d00be8b3f","5690259bf7eb9a0d00f44662","569025b06c49d70d00f18077","569029b418c3920d00be8b43","569029d4f7eb9a0d00f44667","569029e8e056c80d00fdec58","569029fb48df220d004ca221","56902a1c18c3920d00be8b46","56902a45f7eb9a0d00f44669","56902a6be056c80d00fdec5a","56902a78f7eb9a0d00f4466b","56902a8848df220d004ca224","56902aa018c3920d00be8b4b","56902ace6c49d70d00f18085","56902ae0741e9c0d00af2fc6","56902aee48df220d004ca226","56902af8f7eb9a0d00f44674","56902b26efcc380d0043a5b1","56902b8148df220d004ca22a","56902ba918c3920d00be8b55","56902bb96c49d70d00f1808b","56902bc818c3920d00be8b57","56902bd518c3920d00be8b59","56902be218c3920d00be8b5b","56902bf66c49d70d00f1808e","56902c05e056c80d00fdec5d","56902c196c49d70d00f18090","56902c2648df220d004ca22d","56902c34f7eb9a0d00f44678","56902c5518c3920d00be8b5d","56902c62741e9c0d00af2fcc","56902cde48df220d004ca230","56902cea741e9c0d00af2fcf","56902d0ae056c80d00fdec60","56902d20efcc380d0043a5b4","56902d3448df220d004ca232","5696c3fbf9203821005fe2fb","5696c3fb9e2d000d00947ab0","5696c3fbf9203821005fe2fa","5697efee8d2a770d00d2fd17","569802611c4dc823005426c7","56a65c82b3ffe00d00156eaf","56f01f88332da41700f24b74"],"project":"568fde81b700ce0d002f4b43","version":"568fde82b700ce0d002f4b46","__v":60,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-01-08T18:41:53.562Z","from_sync":false,"order":1,"slug":"commands","title":"Commands"},"project":"568fde81b700ce0d002f4b43","version":{"_id":"568fde82b700ce0d002f4b46","__v":23,"project":"568fde81b700ce0d002f4b43","createdAt":"2016-01-08T16:06:26.373Z","releaseDate":"2016-01-08T16:06:26.373Z","categories":["568fde82b700ce0d002f4b47","568ff0e504440a1700e4cbbd","569002f19ebef90d0087289d","569004f4769f210d00132599","5690056d9ebef90d008728a0","569005d394c5030d0028813a","5690067804440a1700e4cbe2","569137eb3c4f510d00ec9b92","56913815e56a790d008dbfe3","569138ba3c4f510d00ec9b93","5691392f3c4f510d00ec9b94","56913bbe72f2810d007e4cb0","56933b8d6ebadc0d005b71d2","56933b8d6ebadc0d005b71d3","569564facaa32519009c41e6","5696a319b6d61f0d00acfb40","5696a319a857080d0082e8e8","5697efe43503e40d0061f4d1","5697efe48d2a770d00d2fd16","569e9597ffccd10d00a05c59","56a7a1523d33bc2100793d5c","56a7a32ecf6d771700baeee8","56b8b0f7ddeb231700e69825"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":false,"codename":"bar","version_clean":"1.0.0","version":"1.0"},"__v":0,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-01-08T21:35:37.116Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":50,"body":"Use `cy.request` to make HTTP requests. Great for talking to an external endpoint before, during, or after your tests for seeding, querying records, or API testing.\n\n| | |\n|--- | --- |\n| **Returns** | the `response` as an object literal. |\n| **Timeout** | `cy.request` will wait for the response for the duration of the [responseTimeout](https://on.cypress.io/guides/configuration#section-timeouts) or the [`timeout`](#section-options) passed in the options object of the command. |\n\n***\n\n# [cy.request( *url* )](#section-url-usage)\n\nMakes a `GET` request using the specified url.\n\n***\n\n# [cy.request( *url*, *body* )](#section-url-and-body-usage)\n\nMake a `GET` request to the provided url with the provided body.\n\n***\n\n# [cy.request( *method*, *url* )](#section-method-and-url-usage)\n\nMake a request using the provided method to the specified url.\n\n***\n\n# [cy.request( *method*, *url*, *body* )](#section-method-and-url-and-body-usage)\n\nAdditionally pass in the request `body` as a `String` or `Object Literal`. Cypress will set the `Accepts` request header and serialize the response body by its `Content-Type`.\n\n***\n\n# Options\n\nPass in an options object to change the default behavior of `cy.request`.\n\n**[cy.request( *options* )](#options-usage)**\n\nOption | Default | Notes\n--- | --- | ---\n`auth` | `null` | Any auth to send. Accepts an object literal.\n`body` | `null` | The Request Body to send along with the request.\n`failOnStatusCode` | `true` | Whether to fail on response codes other than `2xx` and `3xx`.\n`followRedirect` | `true` | Whether to automatically follow redirects.\n`form` | `false` | Whether to convert the `body` values to urlencoded content and automatically set the `x-www-form-urlencoded` header.\n`gzip` | `true` | Whether to accept the `gzip` encoding.\n`headers` | `null` | Any additional headers to send. Accepts an object literal.\n`log` | `true` | Whether to log the request in the Command Log\n`method` | `GET` | The HTTP method to use when making the request.\n`qs` | `null` | The query parameters to be appended to the `url` option when making the request.\n`timeout` | [`responseTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) | Total time to wait for a response (in ms)\n`url` | `null` | The URL to make the request.\n\nYou can also set options for the `cy.request`'s `baseUrl` and `responseTimeout` globally in [configuration](https://on.cypress.io/guides/configuration).\n\n***\n\n# URL Usage\n\n## Make a `GET` request\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// make a request to seed the database prior to running each test\\nbeforeEach(function(){\\n  cy.request(\\\"http://localhost:8080/db/seed\\\")\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n## Issue a simple HTTP request\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  // dont visit this page and load the resources\\n  // instead let's just issue a simple HTTP request\\n  // so we can make an assertion about its body\\n  .request(\\\"/admin\\\")\\n  .its(\\\"body\\\")\\n  .should(\\\"include\\\", \\\"<h2>admin.html</h2>\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Send the new subject to an HTTP's response on request\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// the response object is an object literal\\n// containing status, body, headers, and duration\\ncy.request(\\\"http://dev.local/users\\\").then(function(response){\\n  // subject is now the response object\\n  // {\\n  //   status: 200,\\n  //   headers: {...},\\n  //   body: [{id: 1, name: \\\"Jane\\\"}, {id: 2, name: \\\"LeeAnn\\\"}],\\n  //   duration: 28\\n  // }\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Method and URL Usage\n\n## Send a `DELETE` request\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// Delete a user\\ncy.request(\\\"DELETE\\\", \\\"http://localhost:8888/users/827\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Method and URL and Body Usage\n\n## Send a `POST` request with a JSON body\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// the Accepts Request Header is automatically set based\\n// on the type of body you supply\\ncy\\n  .request(\\\"POST\\\", \\\"http://localhost:8888/users/admin\\\", {name: \\\"Jane\\\"})\\n  .then(function(response){\\n    // response.body would automatically be serialized into JSON\\n    expect(response.body).to.have.property(\\\"name\\\", \\\"Jane\\\") // true\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Options Usage\n\n## Request the dashboard while disabling auto redirect\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// to test the redirection behavior on login without a session\\n// cy.request can be used to check the status code and redirectedToUrl property.\\n//\\n// the 'redirectedToUrl' property is a special Cypress property under the hood\\n// that normalizes the url the browser would normally follow during a redirect\\n\\ncy.request({\\n  url: '/dashboard',\\n  followRedirect: false // turn off following redirects automatically\\n})\\n.then((resp) => {\\n  // should have status code 302\\n  expect(resp.status).to.eq(302)\\n\\n  // when we turn off following redirects, Cypress will also send us\\n  // a 'redirectedToUrl' property with the fully qualified URL that we were redirected to.\\n  expect(resp.redirectedToUrl).to.eq(\\\"http://localhost:8082/unauthorized\\\")\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## HTML form submissions using form option\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// oftentimes once we have a proper e2e test around logging in\\n// there is NO more reason to actually use our UI to log in users\\n// doing so wastes a huge amount of time, as our entire page has to load\\n// all associated resources, we have to wait to fill the\\n// form and for the form submission and redirection process\\n//\\n// with cy.request we can bypass all of this because it automatically gets\\n// and sets cookies under the hood which acts exactly as if these requests\\n// came from the browser\\n\\ncy\\n  .request({\\n    method: 'POST',\\n    url: '/login_with_form', // baseUrl will be prepended to this url\\n    form: true, // indicates the body should be form urlencoded and sets Content-Type: application/x-www-form-urlencoded headers\\n    body: {\\n      username: 'jane.lane',\\n      password: 'password123'\\n    }\\n  })\\n\\n  // just to prove we have a session\\n  cy.getCookie(\\\"cypress-session-cookie\\\").should('exist')\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"[Check out our example recipe using cy.request for HTML form submissions](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_html_web_form_spec.js)\",\n  \"title\": \"Using cy.request for HTML Forms\"\n}\n[/block]\n\n***\n\n# Notes\n\n## Why don't I see the XHR in the Network Tab of the Chrome Dev Tools?\n\nCypress does not actually make an XHR request out of the browser. Under the hood we are making the HTTP request from the desktop application (in node). Therefore you will not see the request inside of the Chrome Dev Tools.\n\nNote that we automatically set both Cookies + User Agent headers correctly as if the request was really coming from the browser.\n\n***\n\n## CORS is bypassed\n\nNormally when the browser detects a cross-origin HTTP request, it will send an `OPTIONS` preflight check to ensure the server allows cross-origin requests. `cy.request` bypasses CORS entirely.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// we can make requests to any external server, no problem.\\ncy\\n  .request(\\\"https://www.google.com/webhp?#q=cypress.io+cors\\\")\\n    .its(\\\"body\\\")\\n    .should(\\\"include\\\", \\\"Testing, the way it should be\\\") // true\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Cookies are automatically sent and received\n\nBefore sending the HTTP request, we will automatically attach cookies that would have otherwise been attached had the request come from the browser. Additionally, if a response has a `Set-Cookie` header, these are automatically set back on the browser cookies.\n\nIn other words, `cy.request` transparently performs all of the underlying functions as if it came from the browser.\n\n***\n\n## Rules for resolving a relative request url\n\nIf you provide a non fully qualified domain name (FQDN), Cypress will make its best guess as to which host you want the request to go to.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  // after you visit somewhere, Cypress will assume this is the host\\n  .visit(\\\"http://localhost:8080/app\\\")\\n  .request(\\\"users/1.json\\\") // <-- url is http://localhost:8080/users/1.json\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nIf you make the `cy.request` prior to visiting a page, Cypress will use the host configured as the `baseUrl` property inside of `cypress.json`.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// cypress.json\\n{\\n  baseUrl: \\\"http://localhost:1234\\\"\\n}\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// inside of your tests\\ncy.request(\\\"seed/admin\\\") //<-- url is http://localhost:1234/seed/admin\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nIf Cypress cannot determine the host it will throw an explicit error.\n\n***\n\n# Related\n\n- [Recipe: Logging In - HTML Web Form](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_html_web_form_spec.js)\n- [Recipe: Logging In - XHR Web Form](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_xhr_web_form_spec.js)\n- [Recipe: Logging In - CSRF Tokens](https://github.com/cypress-io/cypress-example-recipes#logging-in---csrf-tokens)\n- [Recipe: Logging In - Single Sign on](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_single_sign_on_spec.js)\n- [visit](https://on.cypress.io/api/visit)","excerpt":"Make HTTP request","slug":"request","type":"basic","title":"request"}

request

Make HTTP request

Use `cy.request` to make HTTP requests. Great for talking to an external endpoint before, during, or after your tests for seeding, querying records, or API testing. | | | |--- | --- | | **Returns** | the `response` as an object literal. | | **Timeout** | `cy.request` will wait for the response for the duration of the [responseTimeout](https://on.cypress.io/guides/configuration#section-timeouts) or the [`timeout`](#section-options) passed in the options object of the command. | *** # [cy.request( *url* )](#section-url-usage) Makes a `GET` request using the specified url. *** # [cy.request( *url*, *body* )](#section-url-and-body-usage) Make a `GET` request to the provided url with the provided body. *** # [cy.request( *method*, *url* )](#section-method-and-url-usage) Make a request using the provided method to the specified url. *** # [cy.request( *method*, *url*, *body* )](#section-method-and-url-and-body-usage) Additionally pass in the request `body` as a `String` or `Object Literal`. Cypress will set the `Accepts` request header and serialize the response body by its `Content-Type`. *** # Options Pass in an options object to change the default behavior of `cy.request`. **[cy.request( *options* )](#options-usage)** Option | Default | Notes --- | --- | --- `auth` | `null` | Any auth to send. Accepts an object literal. `body` | `null` | The Request Body to send along with the request. `failOnStatusCode` | `true` | Whether to fail on response codes other than `2xx` and `3xx`. `followRedirect` | `true` | Whether to automatically follow redirects. `form` | `false` | Whether to convert the `body` values to urlencoded content and automatically set the `x-www-form-urlencoded` header. `gzip` | `true` | Whether to accept the `gzip` encoding. `headers` | `null` | Any additional headers to send. Accepts an object literal. `log` | `true` | Whether to log the request in the Command Log `method` | `GET` | The HTTP method to use when making the request. `qs` | `null` | The query parameters to be appended to the `url` option when making the request. `timeout` | [`responseTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) | Total time to wait for a response (in ms) `url` | `null` | The URL to make the request. You can also set options for the `cy.request`'s `baseUrl` and `responseTimeout` globally in [configuration](https://on.cypress.io/guides/configuration). *** # URL Usage ## Make a `GET` request [block:code] { "codes": [ { "code": "// make a request to seed the database prior to running each test\nbeforeEach(function(){\n cy.request(\"http://localhost:8080/db/seed\")\n})\n", "language": "javascript" } ] } [/block] ## Issue a simple HTTP request [block:code] { "codes": [ { "code": "cy\n // dont visit this page and load the resources\n // instead let's just issue a simple HTTP request\n // so we can make an assertion about its body\n .request(\"/admin\")\n .its(\"body\")\n .should(\"include\", \"<h2>admin.html</h2>\")\n", "language": "javascript" } ] } [/block] *** ## Send the new subject to an HTTP's response on request [block:code] { "codes": [ { "code": "// the response object is an object literal\n// containing status, body, headers, and duration\ncy.request(\"http://dev.local/users\").then(function(response){\n // subject is now the response object\n // {\n // status: 200,\n // headers: {...},\n // body: [{id: 1, name: \"Jane\"}, {id: 2, name: \"LeeAnn\"}],\n // duration: 28\n // }\n})\n", "language": "javascript" } ] } [/block] *** # Method and URL Usage ## Send a `DELETE` request [block:code] { "codes": [ { "code": "// Delete a user\ncy.request(\"DELETE\", \"http://localhost:8888/users/827\")\n", "language": "javascript" } ] } [/block] *** # Method and URL and Body Usage ## Send a `POST` request with a JSON body [block:code] { "codes": [ { "code": "// the Accepts Request Header is automatically set based\n// on the type of body you supply\ncy\n .request(\"POST\", \"http://localhost:8888/users/admin\", {name: \"Jane\"})\n .then(function(response){\n // response.body would automatically be serialized into JSON\n expect(response.body).to.have.property(\"name\", \"Jane\") // true\n})\n", "language": "javascript" } ] } [/block] *** # Options Usage ## Request the dashboard while disabling auto redirect [block:code] { "codes": [ { "code": "// to test the redirection behavior on login without a session\n// cy.request can be used to check the status code and redirectedToUrl property.\n//\n// the 'redirectedToUrl' property is a special Cypress property under the hood\n// that normalizes the url the browser would normally follow during a redirect\n\ncy.request({\n url: '/dashboard',\n followRedirect: false // turn off following redirects automatically\n})\n.then((resp) => {\n // should have status code 302\n expect(resp.status).to.eq(302)\n\n // when we turn off following redirects, Cypress will also send us\n // a 'redirectedToUrl' property with the fully qualified URL that we were redirected to.\n expect(resp.redirectedToUrl).to.eq(\"http://localhost:8082/unauthorized\")\n})\n", "language": "javascript" } ] } [/block] *** ## HTML form submissions using form option [block:code] { "codes": [ { "code": "// oftentimes once we have a proper e2e test around logging in\n// there is NO more reason to actually use our UI to log in users\n// doing so wastes a huge amount of time, as our entire page has to load\n// all associated resources, we have to wait to fill the\n// form and for the form submission and redirection process\n//\n// with cy.request we can bypass all of this because it automatically gets\n// and sets cookies under the hood which acts exactly as if these requests\n// came from the browser\n\ncy\n .request({\n method: 'POST',\n url: '/login_with_form', // baseUrl will be prepended to this url\n form: true, // indicates the body should be form urlencoded and sets Content-Type: application/x-www-form-urlencoded headers\n body: {\n username: 'jane.lane',\n password: 'password123'\n }\n })\n\n // just to prove we have a session\n cy.getCookie(\"cypress-session-cookie\").should('exist')\n", "language": "javascript" } ] } [/block] [block:callout] { "type": "info", "body": "[Check out our example recipe using cy.request for HTML form submissions](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_html_web_form_spec.js)", "title": "Using cy.request for HTML Forms" } [/block] *** # Notes ## Why don't I see the XHR in the Network Tab of the Chrome Dev Tools? Cypress does not actually make an XHR request out of the browser. Under the hood we are making the HTTP request from the desktop application (in node). Therefore you will not see the request inside of the Chrome Dev Tools. Note that we automatically set both Cookies + User Agent headers correctly as if the request was really coming from the browser. *** ## CORS is bypassed Normally when the browser detects a cross-origin HTTP request, it will send an `OPTIONS` preflight check to ensure the server allows cross-origin requests. `cy.request` bypasses CORS entirely. [block:code] { "codes": [ { "code": "// we can make requests to any external server, no problem.\ncy\n .request(\"https://www.google.com/webhp?#q=cypress.io+cors\")\n .its(\"body\")\n .should(\"include\", \"Testing, the way it should be\") // true\n", "language": "javascript" } ] } [/block] *** ## Cookies are automatically sent and received Before sending the HTTP request, we will automatically attach cookies that would have otherwise been attached had the request come from the browser. Additionally, if a response has a `Set-Cookie` header, these are automatically set back on the browser cookies. In other words, `cy.request` transparently performs all of the underlying functions as if it came from the browser. *** ## Rules for resolving a relative request url If you provide a non fully qualified domain name (FQDN), Cypress will make its best guess as to which host you want the request to go to. [block:code] { "codes": [ { "code": "cy\n // after you visit somewhere, Cypress will assume this is the host\n .visit(\"http://localhost:8080/app\")\n .request(\"users/1.json\") // <-- url is http://localhost:8080/users/1.json\n", "language": "javascript" } ] } [/block] If you make the `cy.request` prior to visiting a page, Cypress will use the host configured as the `baseUrl` property inside of `cypress.json`. [block:code] { "codes": [ { "code": "// cypress.json\n{\n baseUrl: \"http://localhost:1234\"\n}\n", "language": "javascript" } ] } [/block] [block:code] { "codes": [ { "code": "// inside of your tests\ncy.request(\"seed/admin\") //<-- url is http://localhost:1234/seed/admin\n", "language": "javascript" } ] } [/block] If Cypress cannot determine the host it will throw an explicit error. *** # Related - [Recipe: Logging In - HTML Web Form](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_html_web_form_spec.js) - [Recipe: Logging In - XHR Web Form](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_xhr_web_form_spec.js) - [Recipe: Logging In - CSRF Tokens](https://github.com/cypress-io/cypress-example-recipes#logging-in---csrf-tokens) - [Recipe: Logging In - Single Sign on](https://github.com/cypress-io/cypress-example-recipes/blob/master/cypress/integration/logging_in_single_sign_on_spec.js) - [visit](https://on.cypress.io/api/visit)