{"__v":1,"_id":"56954a97fe18811700c9c027","category":{"__v":16,"_id":"56954a95fe18811700c9bfdf","pages":["56954a97fe18811700c9c01d","56954a97fe18811700c9c01e","56954a97fe18811700c9c01f","56954a97fe18811700c9c020","56954a97fe18811700c9c021","56954a97fe18811700c9c022","56954a97fe18811700c9c023","56954a97fe18811700c9c024","56954a97fe18811700c9c025","56954a97fe18811700c9c026","56954a97fe18811700c9c027","56954a97fe18811700c9c028","56954a97fe18811700c9c029","5696cda524490c3700170a05","5697efe61c4dc8230054268e","5697efe72cf4060d004eaa75","56993ff47465970d00650b8f","56a7a155dfdabc0d000ae910","56a7a155b5d0920d0051cd81","56a7a1a6cf6d771700baeee3","56a7a1a63d33bc2100793d5d","56a7a23097e8b00d0096d209","56a7a230ea3e3417000df4b1","56a7a25acf6d771700baeee6","56a7a25a03f28c0d00a545bf","56a7a2b83d33bc2100793d60","56a7a2b8b5d0920d0051cd82","56b27fe42db51f0d0044e566"],"project":"568fde81b700ce0d002f4b43","version":"56954a94fe18811700c9bfda","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-01-09T16:40:53.584Z","from_sync":false,"order":4,"slug":"guides","title":"Guides"},"parentDoc":null,"project":"568fde81b700ce0d002f4b43","user":"568fffce769f210d0013258f","version":{"__v":6,"_id":"56954a94fe18811700c9bfda","project":"568fde81b700ce0d002f4b43","createdAt":"2016-01-12T18:48:52.007Z","releaseDate":"2016-01-12T18:48:52.007Z","categories":["56954a95fe18811700c9bfdb","56954a95fe18811700c9bfdc","56954a95fe18811700c9bfdd","56954a95fe18811700c9bfde","56954a95fe18811700c9bfdf","56954a95fe18811700c9bfe0","56954a95fe18811700c9bfe1","56954a95fe18811700c9bfe2","56954a95fe18811700c9bfe3","56954a95fe18811700c9bfe4","5695649fdcaf0d1700cb8721","5696c1168560a60d00e2c1d6","56a7a32e79395317007c1ad6","5898fc3eec49fb0f004c2663","589cc675ea37da23004e05e1"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"foo","version_clean":"0.0.0","version":"0.0"},"updates":["56a9a07b2bb3910d000ee969"],"next":{"pages":[],"description":""},"createdAt":"2016-01-09T16:42:27.783Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":8,"body":"# Contents\n\n- :fa-angle-right: [Async Challenges](#section-async-challenges)\n- :fa-angle-right: [Introducing Aliasing](#section-introducing-aliasing)\n- :fa-angle-right: [Aliasing DOM Elements](#section-aliasing-dom-elements)\n- :fa-angle-right: [Aliasing Routes](#section-asliasing-routes)\n\n***\n\n# Async Challenges\n\nBecause all commands in Cypress are asynchronous, it makes referencing commands challenging. Aliasing is a DSL that solves referencing work done in previous commands.\n\n**Imagine the following synchronous example in jQuery:**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"var body = $(\\\"body\\\")\\n\\n// do more work here\\n\\n// later use this body reference\\nbody.find(\\\"button\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n> In Cypress, every command is asynchronous.\n\nIn jQuery we can assign regular values because work is performed synchronously. But in Cypress, every command is asynchronous, so there is no immediate return value. You'd have to do something like this to get access to previously resolved values:\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// A not good example of referencing in Cypress\\n\\nvar _this = this\\n\\ncy.get(\\\"body\\\").then(function($body){\\n  _this.body = $body\\n})\\n\\n// more work here\\n\\ncy.then(function(){\\n  cy.wrap(_this.body).find(\\\"button\\\")\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nOf course this is *not good*. It's clunky and difficult to figure out what is going on. Plus, with complex JavaScript applications, the element references may no longer be in the DOM by the time you're ready to use them.\n\n***\n\n# Introducing Aliasing\n\n**Aliasing** was designed to solve async referencing issues and DOM Element re-querying, routing requests and responses, server integration, and automated error handling. Aliasing also gives you a human readable word for a potentially complex series of events. Aliasing is prominently displayed in the Cypress Command Log making it even easier to understand relationships.\n\n![alias-commands](https://cloud.githubusercontent.com/assets/1271364/12363262/cf6fee26-bb95-11e5-8592-4f8cd3a6520e.jpg)\n\n**Aliasing is incredibly powerful but very simple to use:**\n\n* Create an alias with the [`cy.as`](https://on.cypress.io/api/as) command.\n* Reference an alias with the [`cy.get`](https://on.cypress.io/api/get) or [`cy.wait`](https://on.cypress.io/api/wait) command.\n\nEvery time you reference an alias, it should be prefixed with `:::at:::`. You can think of this character as \"a\" for alias or you can think of an alias as a pointer (like how variables point to memory).\n\n# Aliasing DOM Elements\n\nOne use case for aliasing is for referencing a DOM Element.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// alias all of the tr's found in the table as 'rows'\\ncy.get(\\\"table\\\").find(\\\"tr\\\").as(\\\"rows\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nInternally Cypress has made a reference to the `<tr>` collection returned as the alias \"rows\". To reference these same \"rows\" later, you can use the [`cy.get`](https://on.cypress.io/api/get) command.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// Cypress returns the reference to the <tr>'s\\n// which allows us to continue to chain commands\\n// finding the 1st row.\\ncy.get(\\\"@rows\\\").first().click()\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nBecause we've used the `@` character in [`cy.get`](https://on.cypress.io/api/get), instead of querying the DOM for elements, [`cy.get`](https://on.cypress.io/api/get) looks for an existing alias called `rows` and returns the reference (if it finds it).\n\n***\n\n## When alias references no longer exist in the DOM\n\nCypress automatically decides when it should reference existing elements or re-query for new elements.\n\nIn many single-page JavaScript applications, the DOM re-renders parts of the application constantly. If you alias DOM elements that have been removed from the DOM by the time you call [`cy.get`](https://on.cypress.io/api/get) with the alias, Cypress automatically re-querys the DOM to find these elements again.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<ul id=\\\"todos\\\">\\n  <li>\\n    Walk the dog\\n    <button class=\\\"edit\\\">edit</button>\\n  </li>\\n  <li>\\n    Feed the cat\\n    <button class=\\\"edit\\\">edit</button>\\n  </li>\\n</ul>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\nLet's imagine when we click the `.edit` button that our `<li>` is re-rendered in the DOM. Instead of displaying the edit button, it instead displays an `<input />` text field allowing you to edit the todo. The previous `<li>` has been *completely* removed from the DOM, and a new `<li>` is rendered in its place.\n\n**Cypress calculates stale alias references.**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  .get(\\\"#todos li\\\").first().as(\\\"firstTodo\\\")\\n  .get(\\\"@firstTodo\\\").find(\\\".edit\\\").click()\\n  .get(\\\"@firstTodo\\\").should(\\\"have.class\\\", \\\"editing\\\")\\n    .find(\\\"input\\\").type(\\\"Clean the kitchen\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nWhen we reference [email protected]`, Cypress checks to see if all elements its referencing are still in the DOM. If they are, it returns those existing elements. If they aren't, Cypress replays the commands leading up to the alias definition.\n\nIn our case it would re-issue the commands: `cy.get(\"#todos li\").first()`. Everything just works because the new `<li>` is found.\n\n[block:callout]\n{\n  \"type\": \"warning\",\n  \"body\": \"*Usually* replaying previous commands will return what you expect, but not always. Cypress' calculations are complicated and we may improve this algorithm at a later time. It is recommended to not alias DOM elements very far down a chain of commands - **alias elements as soon as possible with as few commands as possible**. When in doubt, you can *always* issue a regular `cy.get` to query for the elements again.\"\n}\n[/block]\n\n***\n\n# Aliasing Routes\n\nAnother use case for aliasing is with routes. Using aliases with [`cy.route`](https://on.cypress.io/api/route) makes dealing with AJAX requests much easier.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  .server()\\n  // alias this route as 'postUser'\\n  .route(\\\"POST\\\", /users/, {id: 123}).as(\\\"postUser\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nOnce you've given a route an alias, you can use it later to indicate what you expect to have happen in your application. Imagine your application's code is as follows:\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"$(\\\"form\\\").submit(function(){\\n  var data = $(this).serializeData()\\n\\n  // simple example of an async\\n  // request that only goes out\\n  // after an indeterminate period of time\\n  setTimeout(function(){\\n    $.post(\\\"/users\\\", {data: data})\\n  }, 1000)\\n})\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\nYou can tell Cypress to wait until it sees a request that matches your aliased route using the [`cy.wait`](https://on.cypress.io/api/wait) command.\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  .get(\\\"form\\\").submit()\\n  .wait(\\\"@postUser\\\")\\n  .get(\\\".success\\\").contains(\\\"User successfully created!\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n**Telling Cypress to wait for an AJAX request that matches an aliased route has enormous advantages.**\n\n1. Waiting for an explicit route reference is less flaky. Instead of waiting for an arbitrary period of time, waiting for a specific aliased route is much more predictable.\n2. Cypress will resolve if there's already been a request that matches the alias.\n3. The actual XHR request object will be yielded to you as the next subject.\n4. Errors are more obvious.","excerpt":"Reference work done in previous commands.","slug":"using-aliases","type":"basic","title":"Using Aliases"}

Using Aliases

Reference work done in previous commands.

# Contents - :fa-angle-right: [Async Challenges](#section-async-challenges) - :fa-angle-right: [Introducing Aliasing](#section-introducing-aliasing) - :fa-angle-right: [Aliasing DOM Elements](#section-aliasing-dom-elements) - :fa-angle-right: [Aliasing Routes](#section-asliasing-routes) *** # Async Challenges Because all commands in Cypress are asynchronous, it makes referencing commands challenging. Aliasing is a DSL that solves referencing work done in previous commands. **Imagine the following synchronous example in jQuery:** [block:code] { "codes": [ { "code": "var body = $(\"body\")\n\n// do more work here\n\n// later use this body reference\nbody.find(\"button\")\n", "language": "javascript" } ] } [/block] > In Cypress, every command is asynchronous. In jQuery we can assign regular values because work is performed synchronously. But in Cypress, every command is asynchronous, so there is no immediate return value. You'd have to do something like this to get access to previously resolved values: [block:code] { "codes": [ { "code": "// A not good example of referencing in Cypress\n\nvar _this = this\n\ncy.get(\"body\").then(function($body){\n _this.body = $body\n})\n\n// more work here\n\ncy.then(function(){\n cy.wrap(_this.body).find(\"button\")\n})\n", "language": "javascript" } ] } [/block] Of course this is *not good*. It's clunky and difficult to figure out what is going on. Plus, with complex JavaScript applications, the element references may no longer be in the DOM by the time you're ready to use them. *** # Introducing Aliasing **Aliasing** was designed to solve async referencing issues and DOM Element re-querying, routing requests and responses, server integration, and automated error handling. Aliasing also gives you a human readable word for a potentially complex series of events. Aliasing is prominently displayed in the Cypress Command Log making it even easier to understand relationships. ![alias-commands](https://cloud.githubusercontent.com/assets/1271364/12363262/cf6fee26-bb95-11e5-8592-4f8cd3a6520e.jpg) **Aliasing is incredibly powerful but very simple to use:** * Create an alias with the [`cy.as`](https://on.cypress.io/api/as) command. * Reference an alias with the [`cy.get`](https://on.cypress.io/api/get) or [`cy.wait`](https://on.cypress.io/api/wait) command. Every time you reference an alias, it should be prefixed with `@`. You can think of this character as "a" for alias or you can think of an alias as a pointer (like how variables point to memory). # Aliasing DOM Elements One use case for aliasing is for referencing a DOM Element. [block:code] { "codes": [ { "code": "// alias all of the tr's found in the table as 'rows'\ncy.get(\"table\").find(\"tr\").as(\"rows\")\n", "language": "javascript" } ] } [/block] Internally Cypress has made a reference to the `<tr>` collection returned as the alias "rows". To reference these same "rows" later, you can use the [`cy.get`](https://on.cypress.io/api/get) command. [block:code] { "codes": [ { "code": "// Cypress returns the reference to the <tr>'s\n// which allows us to continue to chain commands\n// finding the 1st row.\ncy.get(\"@rows\").first().click()\n", "language": "javascript" } ] } [/block] Because we've used the `@` character in [`cy.get`](https://on.cypress.io/api/get), instead of querying the DOM for elements, [`cy.get`](https://on.cypress.io/api/get) looks for an existing alias called `rows` and returns the reference (if it finds it). *** ## When alias references no longer exist in the DOM Cypress automatically decides when it should reference existing elements or re-query for new elements. In many single-page JavaScript applications, the DOM re-renders parts of the application constantly. If you alias DOM elements that have been removed from the DOM by the time you call [`cy.get`](https://on.cypress.io/api/get) with the alias, Cypress automatically re-querys the DOM to find these elements again. [block:code] { "codes": [ { "code": "<ul id=\"todos\">\n <li>\n Walk the dog\n <button class=\"edit\">edit</button>\n </li>\n <li>\n Feed the cat\n <button class=\"edit\">edit</button>\n </li>\n</ul>\n", "language": "html" } ] } [/block] Let's imagine when we click the `.edit` button that our `<li>` is re-rendered in the DOM. Instead of displaying the edit button, it instead displays an `<input />` text field allowing you to edit the todo. The previous `<li>` has been *completely* removed from the DOM, and a new `<li>` is rendered in its place. **Cypress calculates stale alias references.** [block:code] { "codes": [ { "code": "cy\n .get(\"#todos li\").first().as(\"firstTodo\")\n .get(\"@firstTodo\").find(\".edit\").click()\n .get(\"@firstTodo\").should(\"have.class\", \"editing\")\n .find(\"input\").type(\"Clean the kitchen\")\n", "language": "javascript" } ] } [/block] When we reference [email protected]`, Cypress checks to see if all elements its referencing are still in the DOM. If they are, it returns those existing elements. If they aren't, Cypress replays the commands leading up to the alias definition. In our case it would re-issue the commands: `cy.get("#todos li").first()`. Everything just works because the new `<li>` is found. [block:callout] { "type": "warning", "body": "*Usually* replaying previous commands will return what you expect, but not always. Cypress' calculations are complicated and we may improve this algorithm at a later time. It is recommended to not alias DOM elements very far down a chain of commands - **alias elements as soon as possible with as few commands as possible**. When in doubt, you can *always* issue a regular `cy.get` to query for the elements again." } [/block] *** # Aliasing Routes Another use case for aliasing is with routes. Using aliases with [`cy.route`](https://on.cypress.io/api/route) makes dealing with AJAX requests much easier. [block:code] { "codes": [ { "code": "cy\n .server()\n // alias this route as 'postUser'\n .route(\"POST\", /users/, {id: 123}).as(\"postUser\")\n", "language": "javascript" } ] } [/block] Once you've given a route an alias, you can use it later to indicate what you expect to have happen in your application. Imagine your application's code is as follows: [block:code] { "codes": [ { "code": "$(\"form\").submit(function(){\n var data = $(this).serializeData()\n\n // simple example of an async\n // request that only goes out\n // after an indeterminate period of time\n setTimeout(function(){\n $.post(\"/users\", {data: data})\n }, 1000)\n})\n", "language": "javascript" } ] } [/block] You can tell Cypress to wait until it sees a request that matches your aliased route using the [`cy.wait`](https://on.cypress.io/api/wait) command. [block:code] { "codes": [ { "code": "cy\n .get(\"form\").submit()\n .wait(\"@postUser\")\n .get(\".success\").contains(\"User successfully created!\")\n", "language": "javascript" } ] } [/block] **Telling Cypress to wait for an AJAX request that matches an aliased route has enormous advantages.** 1. Waiting for an explicit route reference is less flaky. Instead of waiting for an arbitrary period of time, waiting for a specific aliased route is much more predictable. 2. Cypress will resolve if there's already been a request that matches the alias. 3. The actual XHR request object will be yielded to you as the next subject. 4. Errors are more obvious.