{"__v":0,"_id":"5690247b18c3920d00be8b39","category":{"__v":60,"_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","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2016-01-08T18:41:53.562Z","from_sync":false,"order":1,"slug":"commands","title":"Commands"},"parentDoc":null,"project":"568fde81b700ce0d002f4b43","user":"568fffce769f210d0013258f","version":{"__v":23,"_id":"568fde82b700ce0d002f4b46","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"},"updates":[],"next":{"pages":[],"description":""},"createdAt":"2016-01-08T21:04:59.621Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":12,"body":"Get the DOM element containing the text. DOM elements can contain *more* than the desired text and still match. Additionally, Cypress will prefer some DOM elements over the deepest element found.\n\n**Preference order:**\n\n- `input[type='submit']`\n- `button`\n- `a`\n- `label`\n\n| | |\n|--- | --- |\n| **Returns** | the deepest DOM element containing the text  |\n| **Timeout** | `cy.contains` will retry for the duration of the [`defaultCommandTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) |\n\n***\n\n# [cy.contains( *text* )](#section-text-usage)\n\nGet the deepest DOM element containing the text.\n\n***\n\n# [cy.contains( *number* )](#section-number-usage)\n\nGet the deepest DOM element containing the number.\n\n***\n\n# [cy.contains( *regexp* )](#section-regular-expression-usage)\n\nGet the deepest DOM element containing the text matching the regular expression.\n\n***\n\n# [cy.contains( *selector*, *text* )](#section-selector-and-text-usage)\n\nSpecify a selector to filter DOM elements containing the text. Cypress will **ignore** it's default preference for the specified selector. Using a selector allows you to return more *shallow* elements in the tree which contain the specific text.\n\n***\n\n# Options\n\nPass in an options object to change the default behavior of `cy.contains`.\n\n**cy.contains( *text*, *options* )**\n**cy.contains( *selector*, *text*, *options* )**\n\nOption | Default | Notes\n--- | --- | ---\n`log` | `true` | whether to display command in command log\n`timeout` | [`defaultCommandTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) | Total time to retry finding an element\n\n***\n\n# Text Usage\n\n## Find the first element containing some text\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<ul>\\n  <li>apples</li>\\n  <li>oranges</li>\\n  <li>bananas</li>\\n</ul>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// returns <li>apples</li>\\ncy.contains(\\\"apples\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Find the input[type='submit'] by value\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<div id=\\\"main\\\">\\n  <form>\\n    <div>\\n      <label>name</label>\\n      <input name=\\\"name\\\" />\\n    </div>\\n    <div>\\n      <label>age</label>\\n      <input name=\\\"age\\\" />\\n    </div>\\n    <input type=\\\"submit\\\" value=\\\"submit the form!\\\" />\\n  </form>\\n</div>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// get the form element\\n// search inside its descendants for the content 'submit the form!'\\n// find the input[type='submit'] element\\n// click it\\ncy.get(\\\"form\\\").contains(\\\"submit the form!\\\").click()\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Favor of `button` over other deeper elements\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<form>\\n  <button>\\n    <i class=\\\"fa fa-search\\\"></i>\\n    <span>Search</span>\\n  </button>\\n</form>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// even though the <span> is the deepest element that contains: \\\"Search\\\"\\n// Cypress will automatically favor button elements higher in the chain\\n\\n// in this case the <button> is returned which is why we can now drill\\n// into its children\\ncy.contains(\\\"Search\\\").children(\\\"i\\\").should(\\\"have.class\\\", \\\"fa-search\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Favor of `a` over other deeper elements\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<nav>\\n  <a href=\\\"/dashboard\\\">\\n    <span>Dashboard</span>\\n  </a>\\n  <a href=\\\"/users\\\">\\n    <span>Users</span>\\n  </a>\\n  <a href=\\\"/signout\\\">\\n    <span>Sign Out</span>\\n  </a>\\n</nav>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// even though the <span> is the deepest element that contains: \\\"Sign Out\\\"\\n// Cypress will automatically favor anchor elements higher in the chain\\n\\n// in this case we can assert on the anchors properties\\ncy.get(\\\"nav\\\").contains(\\\"Sign Out\\\").should(\\\"have.attr\\\", \\\"href\\\", \\\"/signout\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Favor of `label` over other deeper elements\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<form>\\n  <label>\\n    <span>Name:</span>\\n    <input name=\\\"name\\\" />\\n  </label>\\n  <label>\\n    <span>Age:</span>\\n    <input name=\\\"age\\\" />\\n  </label>\\n</form>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// even though the <span> is the deepest element that contains: \\\"Age\\\"\\n// Cypress will favor label elements higher in the chain\\n\\n// additionally we can omit the colon as long as the element\\n// at least contains the text 'Age'\\n\\ncy.contains(\\\"Age\\\").find(\\\"input\\\").type(\\\"29\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n## Only the *first* matched element will be returned\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<ul id=\\\"header\\\">\\n  <li>Welcome, Jane Lane</li>\\n</ul>\\n<div id=\\\"main\\\">\\n  <span>These users have 10 connections with Jane Lane</span>\\n  <ul>\\n    <li>User 1</li>\\n    <li>User 2</li>\\n    <li>User 3</li>\\n  </ul>\\n</div>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// this will return the <li> in the #header since that is the first\\n// element that contains the text \\\"Jane Lane\\\"\\ncy.contains(\\\"Jane Lane\\\")\\n\\n// if you want to select the <span> inside of #main instead\\n// you need to scope the contains first\\n\\n//now the <span> is returned\\ncy.get(\\\"#main\\\").contains(\\\"Jane Lane\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Number Usage\n\n## Find the first element containing some number\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<button class=\\\"btn btn-primary\\\" type=\\\"button\\\">\\n  Messages <span class=\\\"badge\\\">4</span>\\n</button>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// even though the <span> is the deepest element that contains: 4\\n// Cypress will automatically favor button elements higher in the chain\\n\\n// in this case the <button> is returned\\ncy.contains(4)\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Regular Expression Usage\n\n## Find the first element with text matching the regular expression\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<ul>\\n  <li>apples</li>\\n  <li>oranges</li>\\n  <li>bananas</li>\\n</ul>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// <li>bananas</li> is returned\\ncy.contains(/^b\\\\w+/)\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n\n# Selector and Text Usage\n\n## Specify a selector to return a specific element\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"<html>\\n  <body>\\n    <ul>\\n      <li>apples</li>\\n      <li>oranges</li>\\n      <li>bananas</li>\\n    </ul>\\n  </body>\\n</html>\\n\",\n            \"language\": \"html\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// technically the <html>, <body>, <ul>, and first <li> all contain \\\"apples\\\"\\n\\n// normally Cypress would return the first <li> since that is the deepest\\n// element that contains: \\\"apples\\\"\\n\\n// to override this behavior, pass a 'ul' selector\\n// this returns the ul element since it also contains the text\\n\\n// returns <ul>...</ul>\\ncy.contains(\\\"ul\\\", \\\"apples\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Notes\n\n## Dual command can be either parent or child\n\n`cy.contains` is a dual command.  This means it can act as both a `parent` and a `child` command.  Read more about [issuing commands](https://on.cypress.io/guides/issuing-commands) if this is unfamiliar.\n\nBecause it is a dual command it can either *begin* a chain of commands or work off of an *existing* subject.\n\n**Start a chain of commands**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// search from the root scope (default: document)\\ncy.contains(\\\"some content\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n**Find content within an existing scope**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// search within an existing subject for the content\\n// contains is now scoped to the <aside> element and will\\n// only search its DOM descendants for the content\\ncy.get(\\\"#main\\\").find(\\\"aside\\\").contains(\\\"Add a user\\\")\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n**Be wary of chaining multiple contains**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// let's imagine a scenario where you click a user's delete button\\n// and a dialog appears asking you to confirm this deletion.\\n\\n// the following will not work:\\ncy\\n  .contains(\\\"Delete User\\\").click()\\n\\n  // because this is chained off of the existing button subject\\n  // Cypress will look inside of the existing button subject\\n  // for the new content\\n\\n  // in other words Cypress will look inside of the element\\n  // containing \\\"Delete User\\\" for the content: \\\"Yes I'm sure!\\\"\\n  .contains(\\\"Yes, I'm sure!\\\").click()\\n\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n**End previous chains to get back to the root scope**\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"cy\\n  // explicitly .end() the previous chain\\n  .contains(\\\"Delete User\\\").click().end()\\n\\n  // Cypress will now search the root scope\\n  // for this content (default: document)\\n  .contains(\\\"Yes, I'm sure!\\\").click()\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// alternatively just call cy again which\\n// automatically creates a new chain from the root scope\\ncy.contains(\\\"Delete User\\\").click()\\ncy.contains(\\\"Yes I'm sure!\\\").click()\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n[block:code]\n{\n    \"codes\": [\n        {\n            \"code\": \"// you can also do this\\ncy\\n  .contains(\\\"Delete User\\\").click()\\n\\n  // by using the parent command .get() we automatically\\n  // abort previous chains and change the scope to #dialog\\n  // which contains the content we're looking for\\n  .get(\\\"#dialog\\\").contains(\\\"Yes I'm sure!\\\").click()\\n\",\n            \"language\": \"javascript\"\n        }\n    ]\n}\n[/block]\n\n***\n\n# Command Log\n\n## Element contains text \"New User\"\n\n<img width=\"536\" alt=\"screen shot 2015-11-27 at 1 43 22 pm\" src=\"https://cloud.githubusercontent.com/assets/1271364/11446973/009ac32c-950d-11e5-9eaa-09f8b8ddf086.png\">\n\nWhen clicking on the `contains` command within the command log, the console outputs the following:\n\n<img width=\"477\" alt=\"screen shot 2015-11-27 at 1 43 50 pm\" src=\"https://cloud.githubusercontent.com/assets/1271364/11446977/04b31be4-950d-11e5-811e-4fd83d364d00.png\">\n\n***\n\n# Related\n\n- [get](https://on.cypress.io/api/get)\n- [within](https://on.cypress.io/api/within)\n- [root](https://on.cypress.io/api/root)","excerpt":"Get a DOM element that contains specific text","slug":"contains","type":"basic","title":"contains"}

contains

Get a DOM element that contains specific text

Get the DOM element containing the text. DOM elements can contain *more* than the desired text and still match. Additionally, Cypress will prefer some DOM elements over the deepest element found. **Preference order:** - `input[type='submit']` - `button` - `a` - `label` | | | |--- | --- | | **Returns** | the deepest DOM element containing the text | | **Timeout** | `cy.contains` will retry for the duration of the [`defaultCommandTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) | *** # [cy.contains( *text* )](#section-text-usage) Get the deepest DOM element containing the text. *** # [cy.contains( *number* )](#section-number-usage) Get the deepest DOM element containing the number. *** # [cy.contains( *regexp* )](#section-regular-expression-usage) Get the deepest DOM element containing the text matching the regular expression. *** # [cy.contains( *selector*, *text* )](#section-selector-and-text-usage) Specify a selector to filter DOM elements containing the text. Cypress will **ignore** it's default preference for the specified selector. Using a selector allows you to return more *shallow* elements in the tree which contain the specific text. *** # Options Pass in an options object to change the default behavior of `cy.contains`. **cy.contains( *text*, *options* )** **cy.contains( *selector*, *text*, *options* )** Option | Default | Notes --- | --- | --- `log` | `true` | whether to display command in command log `timeout` | [`defaultCommandTimeout`](https://on.cypress.io/guides/configuration#section-timeouts) | Total time to retry finding an element *** # Text Usage ## Find the first element containing some text [block:code] { "codes": [ { "code": "<ul>\n <li>apples</li>\n <li>oranges</li>\n <li>bananas</li>\n</ul>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// returns <li>apples</li>\ncy.contains(\"apples\")\n", "language": "javascript" } ] } [/block] *** ## Find the input[type='submit'] by value [block:code] { "codes": [ { "code": "<div id=\"main\">\n <form>\n <div>\n <label>name</label>\n <input name=\"name\" />\n </div>\n <div>\n <label>age</label>\n <input name=\"age\" />\n </div>\n <input type=\"submit\" value=\"submit the form!\" />\n </form>\n</div>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// get the form element\n// search inside its descendants for the content 'submit the form!'\n// find the input[type='submit'] element\n// click it\ncy.get(\"form\").contains(\"submit the form!\").click()\n", "language": "javascript" } ] } [/block] *** ## Favor of `button` over other deeper elements [block:code] { "codes": [ { "code": "<form>\n <button>\n <i class=\"fa fa-search\"></i>\n <span>Search</span>\n </button>\n</form>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// even though the <span> is the deepest element that contains: \"Search\"\n// Cypress will automatically favor button elements higher in the chain\n\n// in this case the <button> is returned which is why we can now drill\n// into its children\ncy.contains(\"Search\").children(\"i\").should(\"have.class\", \"fa-search\")\n", "language": "javascript" } ] } [/block] *** ## Favor of `a` over other deeper elements [block:code] { "codes": [ { "code": "<nav>\n <a href=\"/dashboard\">\n <span>Dashboard</span>\n </a>\n <a href=\"/users\">\n <span>Users</span>\n </a>\n <a href=\"/signout\">\n <span>Sign Out</span>\n </a>\n</nav>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// even though the <span> is the deepest element that contains: \"Sign Out\"\n// Cypress will automatically favor anchor elements higher in the chain\n\n// in this case we can assert on the anchors properties\ncy.get(\"nav\").contains(\"Sign Out\").should(\"have.attr\", \"href\", \"/signout\")\n", "language": "javascript" } ] } [/block] *** ## Favor of `label` over other deeper elements [block:code] { "codes": [ { "code": "<form>\n <label>\n <span>Name:</span>\n <input name=\"name\" />\n </label>\n <label>\n <span>Age:</span>\n <input name=\"age\" />\n </label>\n</form>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// even though the <span> is the deepest element that contains: \"Age\"\n// Cypress will favor label elements higher in the chain\n\n// additionally we can omit the colon as long as the element\n// at least contains the text 'Age'\n\ncy.contains(\"Age\").find(\"input\").type(\"29\")\n", "language": "javascript" } ] } [/block] *** ## Only the *first* matched element will be returned [block:code] { "codes": [ { "code": "<ul id=\"header\">\n <li>Welcome, Jane Lane</li>\n</ul>\n<div id=\"main\">\n <span>These users have 10 connections with Jane Lane</span>\n <ul>\n <li>User 1</li>\n <li>User 2</li>\n <li>User 3</li>\n </ul>\n</div>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// this will return the <li> in the #header since that is the first\n// element that contains the text \"Jane Lane\"\ncy.contains(\"Jane Lane\")\n\n// if you want to select the <span> inside of #main instead\n// you need to scope the contains first\n\n//now the <span> is returned\ncy.get(\"#main\").contains(\"Jane Lane\")\n", "language": "javascript" } ] } [/block] *** # Number Usage ## Find the first element containing some number [block:code] { "codes": [ { "code": "<button class=\"btn btn-primary\" type=\"button\">\n Messages <span class=\"badge\">4</span>\n</button>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// even though the <span> is the deepest element that contains: 4\n// Cypress will automatically favor button elements higher in the chain\n\n// in this case the <button> is returned\ncy.contains(4)\n", "language": "javascript" } ] } [/block] *** # Regular Expression Usage ## Find the first element with text matching the regular expression [block:code] { "codes": [ { "code": "<ul>\n <li>apples</li>\n <li>oranges</li>\n <li>bananas</li>\n</ul>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// <li>bananas</li> is returned\ncy.contains(/^b\\w+/)\n", "language": "javascript" } ] } [/block] *** # Selector and Text Usage ## Specify a selector to return a specific element [block:code] { "codes": [ { "code": "<html>\n <body>\n <ul>\n <li>apples</li>\n <li>oranges</li>\n <li>bananas</li>\n </ul>\n </body>\n</html>\n", "language": "html" } ] } [/block] [block:code] { "codes": [ { "code": "// technically the <html>, <body>, <ul>, and first <li> all contain \"apples\"\n\n// normally Cypress would return the first <li> since that is the deepest\n// element that contains: \"apples\"\n\n// to override this behavior, pass a 'ul' selector\n// this returns the ul element since it also contains the text\n\n// returns <ul>...</ul>\ncy.contains(\"ul\", \"apples\")\n", "language": "javascript" } ] } [/block] *** # Notes ## Dual command can be either parent or child `cy.contains` is a dual command. This means it can act as both a `parent` and a `child` command. Read more about [issuing commands](https://on.cypress.io/guides/issuing-commands) if this is unfamiliar. Because it is a dual command it can either *begin* a chain of commands or work off of an *existing* subject. **Start a chain of commands** [block:code] { "codes": [ { "code": "// search from the root scope (default: document)\ncy.contains(\"some content\")\n", "language": "javascript" } ] } [/block] **Find content within an existing scope** [block:code] { "codes": [ { "code": "// search within an existing subject for the content\n// contains is now scoped to the <aside> element and will\n// only search its DOM descendants for the content\ncy.get(\"#main\").find(\"aside\").contains(\"Add a user\")\n", "language": "javascript" } ] } [/block] **Be wary of chaining multiple contains** [block:code] { "codes": [ { "code": "// let's imagine a scenario where you click a user's delete button\n// and a dialog appears asking you to confirm this deletion.\n\n// the following will not work:\ncy\n .contains(\"Delete User\").click()\n\n // because this is chained off of the existing button subject\n // Cypress will look inside of the existing button subject\n // for the new content\n\n // in other words Cypress will look inside of the element\n // containing \"Delete User\" for the content: \"Yes I'm sure!\"\n .contains(\"Yes, I'm sure!\").click()\n\n", "language": "javascript" } ] } [/block] **End previous chains to get back to the root scope** [block:code] { "codes": [ { "code": "cy\n // explicitly .end() the previous chain\n .contains(\"Delete User\").click().end()\n\n // Cypress will now search the root scope\n // for this content (default: document)\n .contains(\"Yes, I'm sure!\").click()\n", "language": "javascript" } ] } [/block] [block:code] { "codes": [ { "code": "// alternatively just call cy again which\n// automatically creates a new chain from the root scope\ncy.contains(\"Delete User\").click()\ncy.contains(\"Yes I'm sure!\").click()\n", "language": "javascript" } ] } [/block] [block:code] { "codes": [ { "code": "// you can also do this\ncy\n .contains(\"Delete User\").click()\n\n // by using the parent command .get() we automatically\n // abort previous chains and change the scope to #dialog\n // which contains the content we're looking for\n .get(\"#dialog\").contains(\"Yes I'm sure!\").click()\n", "language": "javascript" } ] } [/block] *** # Command Log ## Element contains text "New User" <img width="536" alt="screen shot 2015-11-27 at 1 43 22 pm" src="https://cloud.githubusercontent.com/assets/1271364/11446973/009ac32c-950d-11e5-9eaa-09f8b8ddf086.png"> When clicking on the `contains` command within the command log, the console outputs the following: <img width="477" alt="screen shot 2015-11-27 at 1 43 50 pm" src="https://cloud.githubusercontent.com/assets/1271364/11446977/04b31be4-950d-11e5-811e-4fd83d364d00.png"> *** # Related - [get](https://on.cypress.io/api/get) - [within](https://on.cypress.io/api/within) - [root](https://on.cypress.io/api/root)