{
  "doc": {
    "id": "app/core-concepts/introduction-to-cypress",
    "title": "Introduction to Cypress",
    "description": "Learn the basics of Cypress, including querying elements, chaining commands, and interacting with elements.",
    "section": "app",
    "source_path": "/llm/markdown/app/core-concepts/introduction-to-cypress.md",
    "version": "1375fa62d5875962138c8c43f27d7e1235a504a5",
    "updated_at": "2026-04-29T19:28:48.012Z",
    "headings": [
      {
        "id": "app/core-concepts/introduction-to-cypress#introduction-to-cypress-app",
        "text": "Introduction to Cypress App",
        "level": 1
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#what-youll-learn",
        "text": " What you'll learn",
        "level": 5
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#cypress-can-be-simple-sometimes",
        "text": "Cypress Can Be Simple (Sometimes)",
        "level": 2
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#querying-elements",
        "text": "Querying Elements",
        "level": 2
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#cypress-is-like-jquery",
        "text": "Cypress is Like jQuery",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#cypress-is-not-like-jquery",
        "text": "Cypress is Not Like jQuery",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#1-the-element-is-found",
        "text": "1. The element is found",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#2-a-set-timeout-is-reached",
        "text": "2. A set timeout is reached",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#querying-by-text-content",
        "text": "Querying by Text Content",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#when-elements-are-missing",
        "text": "When Elements Are Missing",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#chains-of-commands",
        "text": "Chains of Commands",
        "level": 2
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#interacting-with-elements",
        "text": "Interacting With Elements",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#asserting-about-elements",
        "text": "Asserting About Elements",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#subject-management",
        "text": "Subject Management",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#all-commands-yield-a-value",
        "text": "All commands yield a value.",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#some-commands-require-a-previous-subject",
        "text": "Some commands require a previous subject.",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#examples",
        "text": "Examples:",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#using-then-to-act-on-a-subject",
        "text": "Using .then() To Act On A Subject",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#lets-look-at-an-example",
        "text": "Let's look at an example:",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#using-aliases-to-refer-to-previous-subjects",
        "text": "Using Aliases to Refer to Previous Subjects",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#commands-are-asynchronous",
        "text": "Commands Are Asynchronous",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#take-this-short-test-for-example",
        "text": "Take this short test, for example:",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#mixing-async-and-sync-code",
        "text": "Mixing Async and Sync code",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#avoid-loops",
        "text": "Avoid loops",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#commands-run-serially",
        "text": "Commands Run Serially",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#lets-take-another-look-at-an-example",
        "text": "Let's take another look at an example",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#the-cypress-command-queue",
        "text": "The Cypress Command Queue",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#you-cannot-race-or-run-multiple-commands-at-the-same-time",
        "text": "You cannot race or run multiple commands at the same time",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#you-cannot-add-a-catch-error-handler-to-a-failed-command",
        "text": "You cannot add a .catch error handler to a failed command",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#assertions",
        "text": "Assertions",
        "level": 2
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#asserting-in-english",
        "text": "Asserting in English",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#when-to-assert",
        "text": "When To Assert?",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#consider-this-example",
        "text": "Consider this example:",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#implicit-assertions",
        "text": "Implicit Assertions",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#for-instance",
        "text": "For instance:",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-1-existence-and-actionability",
        "text": "Example #1: Existence and Actionability",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-2-reversing-the-implicit-assertion",
        "text": "Example #2: Reversing the Implicit Assertion",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-3-other-implicit-assertions",
        "text": "Example #3: Other Implicit Assertions",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#list-of-assertions",
        "text": "List of Assertions",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#writing-assertions",
        "text": "Writing Assertions",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#command-assertions",
        "text": "Command Assertions",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#mocha-assertions",
        "text": "Mocha Assertions",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#timeouts",
        "text": "Timeouts",
        "level": 2
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#applying-timeouts",
        "text": "Applying Timeouts",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-1-implicit-assertion",
        "text": "Example #1: Implicit Assertion",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-2-additional-assertions",
        "text": "Example #2: Additional Assertions",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#example-3-modifying-timeouts",
        "text": "Example #3: Modifying Timeouts",
        "level": 4
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#default-values",
        "text": "Default Values",
        "level": 3
      },
      {
        "id": "app/core-concepts/introduction-to-cypress#next-steps",
        "text": "Next steps",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Introduction to Cypress App"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is the single most important guide for understanding how to test with\nCypress. Read it. Understand it. Ask questions about it so that we can improve\nit."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": " What you'll learn"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The rules Cypress follows so you can productively test your application"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to query elements in Cypress"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How Cypress uses command chains and the asynchronous nature of Cypress commands"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "How to interact with elements and assert about elements"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Cypress Can Be Simple (Sometimes)"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Simplicity is all about getting more done with less typing. Let's look at an\nexample:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "describe('Post Resource', () => {\n  it('Creating a New Post', () => {\n    -{cy.visit('/posts/new')::cy.mount(<PostBuilder />)}- // 1.\n\n    cy.get(\"input.post-title\") // 2.\n      .type(\"My First Post\"); // 3.\n\n    cy.get(\"input.post-body\") // 4.\n      .type(\"Hello, world!\"); // 5.\n\n    cy.contains(\"Submit\") // 6.\n      .click(); // 7.\n\n    cy.get(\"h1\") // 8.\n      .should(\"contain\", \"My First Post\");\n  });\n});"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Can you read this? If you did, it might sound something like this:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Visit page at `/posts/new` (or mount the `PostBuilder` component)."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find the `<input>` with class `post-title`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Type \"My First Post\" into it."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find the `<input>` with class `post-body`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Type \"Hello, world!\" into it."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find the element containing the text `Submit`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Click it."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find the `h1` tag, ensure it contains the text \"My First Post\"."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is a relatively straightforward test, but consider how much code has been\ncovered by it, both on the client and the server!"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For the remainder of this guide, we'll explore the basics of Cypress that make\nthis example work. We'll demystify the rules Cypress follows so you can\nproductively test your application to act as much like a user as possible, as\nwell as discuss how to take shortcuts when it's useful."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Querying Elements"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cypress is Like jQuery"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you've used "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://jquery.com/",
            "children": [
              {
                "type": "text",
                "value": "jQuery"
              }
            ]
          },
          {
            "type": "text",
            "value": " before, you may be used to querying\nfor elements like this:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "$('.my-selector')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, querying elements is the same:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('.my-selector')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In fact, Cypress\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/bundled-libraries.md#Other-Library-Utilities",
            "children": [
              {
                "type": "text",
                "value": "bundles jQuery"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nand exposes many of its DOM traversal methods to you so you can work with\ncomplex HTML structures with ease using APIs you're already familiar with."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// Each Cypress query is equivalent to its jQuery counterpart.\ncy.get('#main-content').find('.article').children('img[src^=\"/static\"]').first()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress leverages jQuery's powerful selector engine to help make tests familiar\nand readable for modern web developers."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Interested in the best practices for selecting elements?\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Selecting-Elements",
            "children": [
              {
                "type": "text",
                "value": "Read here"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Accessing the DOM elements returned from the query works differently, however:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// This is fine, jQuery returns the element synchronously.\nconst $jqElement = $('.element')\n\n// This will not work! Cypress does not return the element synchronously.\nconst $cyElement = cy.get('.element')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Let's look at why this is..."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cypress is Not Like jQuery"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Question: What happens when jQuery can't find any matching DOM elements from\nits selector?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Answer: Oops! It returns an empty jQuery collection. We've got a real\nobject to work with, but it doesn't contain the element we wanted. So we start\nadding conditional checks and retrying our queries manually."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// $() returns immediately with an empty collection.\nconst $myElement = $('.element').first()\n\n// Leads to ugly conditional checks\n// and worse - flaky tests!\nif ($myElement.length) {\n  doSomething($myElement)\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Question: What happens when Cypress can't find any matching DOM elements\nfrom its selector?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Answer: No big deal! Cypress automatically retries the query until either:"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "1. The element is found"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy\n  // cy.get() looks for '#element', repeating the query until...\n  .get('#element')\n\n  // ...it finds the element!\n  // You can now work with it by using .then\n  .then(($myElement) => {\n    doSomething($myElement)\n  })"
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "2. A set timeout is reached"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy\n  // cy.get() looks for '#element-does-not-exist', repeating the query until...\n  // ...it doesn't find the element before its timeout.\n  // Cypress halts and fails the test.\n  .get('#element-does-not-exist')\n\n  // ...this code is never run...\n  .then(($myElement) => {\n    doSomething($myElement)\n  })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This makes Cypress robust and immune to dozens of common problems that occur in\nother testing tools. Consider all the circumstances that could cause querying a\nDOM element to fail:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The DOM has not loaded yet."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Your framework hasn't finished bootstrapping."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "An XHR request hasn't responded."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "An animation hasn't completed."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "and on and on..."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Before, you'd be forced to write custom code to protect against any and all of\nthese issues: a nasty mashup of arbitrary waits, conditional retries, and null\nchecks littering your tests. Not in Cypress! With built-in retrying and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Timeouts",
            "children": [
              {
                "type": "text",
                "value": "customizable timeouts"
              }
            ]
          },
          {
            "type": "text",
            "value": ", Cypress\nsidesteps all of these flaky issues."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress wraps all DOM queries with robust retry-and-timeout logic that better\nsuits how real web apps work. We trade a minor change in how we find DOM\nelements for a major stability upgrade to all of our tests. Banishing flake for\ngood!"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress, when you want to interact with a DOM element directly, call\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "`.then()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " with a callback function that receives the\nelement as its first argument. When you want to skip the retry-and-timeout\nfunctionality entirely and perform traditional synchronous work, use\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/utilities/$.md",
            "children": [
              {
                "type": "text",
                "value": "`Cypress.$`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Querying by Text Content"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Another way to locate things -- a more human way -- is to look them up by their\ncontent, by what the user would see on the page. For this, there's the handy\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/contains.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.contains()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command, for example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// Find an element in the document containing the text 'New Post'\ncy.contains('New Post')\n\n// Find an element within '.main' containing the text 'New Post'\ncy.get('.main').contains('New Post')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is helpful when writing tests from the perspective of a user interacting\nwith your app. They only know that they want to click the button labeled\n\"Submit\". They have no idea that it has a `type` attribute of `submit`, or a CSS\nclass of `my-submit-button`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Internationalization"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your app is translated into multiple languages for i18n, make sure you\nconsider the implications of using user-facing text to find DOM elements!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "When Elements Are Missing"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As we showed above, Cypress anticipates the asynchronous nature of web\napplications and doesn't fail immediately the first time an element is not\nfound. Instead, Cypress gives your app a window of time to finish whatever it\nmay be doing!"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is known as a `timeout`, and most commands can be customized with specific\ntimeout periods\n("
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Timeouts",
            "children": [
              {
                "type": "text",
                "value": "the default timeout is 4 seconds"
              }
            ]
          },
          {
            "type": "text",
            "value": ").\nThese Commands will list a `timeout` option in their API documentation,\ndetailing how to set the number of milliseconds you want to continue to try\nfinding the element."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// Give this element 10 seconds to appear\ncy.get('.my-slow-selector', { timeout: 10000 })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can also set the timeout globally via the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#Timeouts",
            "children": [
              {
                "type": "text",
                "value": "configuration setting: `defaultCommandTimeout`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To match the behavior of web applications, Cypress is asynchronous and relies on\ntimeouts to know when to stop waiting on an app to get into the expected state.\nTimeouts can be configured globally, or on a per-command basis."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Timeouts and Performance"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "There is a performance tradeoff here: tests that have longer timeout periods\ntake longer to fail. Commands always proceed as soon as their expected\ncriteria is met, so working tests will be performed as fast as your application\nallows. A test that fails due to timeout will consume the entire timeout period,\nby design. This means that while you may want to increase your timeout period\nto suit specific parts of your app, you don't want to make it \"extra long,\njust in case\"."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Later in this guide we'll go into much more detail about\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "#Implicit-Assertions",
            "children": [
              {
                "type": "text",
                "value": "Implicit Assertions"
              }
            ]
          },
          {
            "type": "text",
            "value": " and "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Timeouts",
            "children": [
              {
                "type": "text",
                "value": "Timeouts"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Chains of Commands"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "It's very important to understand the mechanism Cypress uses to chain commands\ntogether. It manages a Promise chain on your behalf, with each command yielding\na 'subject' to the next command, until the chain ends or an error is\nencountered. The developer should not need to use Promises directly, but\nunderstanding how they work is helpful!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Interacting With Elements"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As we saw in the initial example, Cypress allows you to click on and type into\nelements on the page by using "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/click.md",
            "children": [
              {
                "type": "text",
                "value": "`.click()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/type.md",
            "children": [
              {
                "type": "text",
                "value": "`.type()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " action commands with a\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/get.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.get()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " or "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/contains.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.contains()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "\nquery command. This is a great example of chaining in action. Let's see it\nagain:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('textarea.post-body').type('This is an excellent post.')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We're chaining "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/type.md",
            "children": [
              {
                "type": "text",
                "value": "`.type()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " onto\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/get.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.get()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", telling it to type into the subject yielded\nfrom the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/get.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.get()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " query, which will be a DOM element."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Here are even more action commands Cypress provides to interact with your app:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/blur.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.blur()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Make a focused DOM element blur."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/focus.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.focus()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Focus on a DOM element."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/clear.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.clear()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Clear the value of an input or textarea."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/check.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.check()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Check checkbox(es) or radio(s)."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/uncheck.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.uncheck()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Uncheck checkbox(es)."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/select.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.select()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Select an `<option>` within a\n`<select>`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/dblclick.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.dblclick()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Double-click a DOM element."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/rightclick.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.rightclick()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " - Right-click a DOM element."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "These commands ensure\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/interacting-with-elements.md",
            "children": [
              {
                "type": "text",
                "value": "some guarantees"
              }
            ]
          },
          {
            "type": "text",
            "value": " about what\nthe state of the elements should be prior to performing their actions."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For example, when writing a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/click.md",
            "children": [
              {
                "type": "text",
                "value": "`.click()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command, Cypress\nensures that the element is able to be interacted with (like a real user would).\nIt will automatically wait until the element reaches an \"actionable\" state by:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Not being hidden"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Not being covered"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Not being disabled"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Not animating"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This also helps prevent flake when interacting with your application in tests.\nYou can usually override this behavior with a `force` option."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress provides a simple but powerful algorithm when\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/interacting-with-elements.md",
            "children": [
              {
                "type": "text",
                "value": " interacting with elements."
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Asserting About Elements"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Assertions let you do things like ensuring an element is visible or has a\nparticular attribute, CSS class, or state. Assertions are commands that enable\nyou to describe the desired state of your application. Cypress will\nautomatically wait until your elements reach this state, or fail the test if the\nassertions don't pass. Here's a quick look at assertions in action:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get(':checkbox').should('be.disabled')\n\ncy.get('form').should('have.class', 'form-horizontal')\n\ncy.get('input').should('not.have.value', 'US')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In each of these examples, it's important to note that Cypress will\nautomatically wait until these assertions pass. This prevents you from having\nto know or care about the precise moment your elements eventually do reach this\nstate."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We will learn more about "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Assertions",
            "children": [
              {
                "type": "text",
                "value": "assertions"
              }
            ]
          },
          {
            "type": "text",
            "value": " later in this guide."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Subject Management"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A new Cypress chain always starts with `cy.[command]`, where what is yielded by\nthe `command` establishes what other commands can be called next (chained)."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "All commands yield a value."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each command specifies what value it yields. For example,"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/clearcookies.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.clearCookies()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " yields `null`. You can chain\noff commands that yield `null`, as long as the next command doesn't expect to\nreceive a subject."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.contains()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " yields a DOM element, allowing\nfurther commands to be chained (assuming they expect a DOM subject) like\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " or even\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.contains()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " again."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " yields the same subject it was originally\ngiven."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Some commands require a previous subject."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " requires a DOM element from the previous\ncommand."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/its.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.its()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " requires a subject, but it can be of any type."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.contains()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " behaves differently depending on the\nprevious subject. If chained directly off of `cy`, or if the previous command\nyielded `null`, it will look at the entire document. But if the subject is a\nDOM element, it will only look inside that container."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/clearcookies.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.clearCookies()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " does not require a previous\nsubject - it can be chained off of anything, even\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/end.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.end()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Examples:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is actually much more intuitive than it sounds."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.clearCookies() // Yields null\n  .visit('/fixtures/dom.html') // Does not care about the previous subject.\n\ncy.get('.main-container') // Yields an array of matching DOM elements\n  .contains('Headlines') // Yields the first DOM element containing content\n  .click() // Yields same DOM element from previous command."
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress commands do not return their subjects, they yield them.\nRemember: Cypress commands are asynchronous and get queued for execution at a\nlater time. During execution, subjects are yielded from one command to the next,\nand a lot of helpful Cypress code runs between each command to ensure everything\nis in order."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Don't continue a chain after acting on the DOM"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "While it's possible in Cypress to act on the DOM and then continue chaining,\nthis is usually unsafe, and can lead to stale elements. See the\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "Retry-ability Guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " for more details."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "But the rule of thumb is simple: If you perform an action, like navigating the\npage, clicking a button or scrolling the viewport, end the chain of commands\nthere and start fresh from `cy`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To work around the need to reference elements, Cypress has a feature\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/variables-and-aliases.md",
            "children": [
              {
                "type": "text",
                "value": "known as aliasing"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Aliasing helps\nyou to store and save references for future use."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Using "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": ".then()"
              }
            ]
          },
          {
            "type": "text",
            "value": " To Act On A Subject"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Want to jump into the command flow and get your hands on the subject directly?\nNo problem, add a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": ".then()"
              }
            ]
          },
          {
            "type": "text",
            "value": " to your command chain. When the\nprevious command resolves, it will call your callback function with the yielded\nsubject as the first argument."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you wish to continue chaining commands after your\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "`.then()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", you'll need to specify the subject you want to\nyield to those commands, which you can achieve with a return value other than\n`null` or `undefined`. Cypress will yield that to the next command for you."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Let's look at an example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy\n  // Find the el with id 'some-link'\n  .get('#some-link')\n\n  .then(($myElement) => {\n    // ...massage the subject with some arbitrary code\n\n    // grab its href property\n    const href = $myElement.prop('href')\n\n    // strip out the 'hash' character and everything after it\n    return href.replace(/(#.*)/, '')\n  })\n  .then((href) => {\n    // href is now the new subject\n    // which we can work with now\n  })"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We have many more examples and use cases of "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "cy.then()"
              }
            ]
          },
          {
            "type": "text",
            "value": " in\nour "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/variables-and-aliases.md",
            "children": [
              {
                "type": "text",
                "value": "Core Concept Guide"
              }
            ]
          },
          {
            "type": "text",
            "value": " that\nteaches you how to properly deal with asynchronous code, when to use variables,\nand what aliasing is."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Using Aliases to Refer to Previous Subjects"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress has some added functionality for quickly referring back to past subjects\ncalled "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/variables-and-aliases.md",
            "children": [
              {
                "type": "text",
                "value": "Aliases"
              }
            ]
          },
          {
            "type": "text",
            "value": ". It looks\nsomething like this:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('.my-selector')\n  .as('myElement') // sets the alias\n  .click()\n\n/* many more actions */\n\ncy.get('@myElement') // re-queries the DOM as before\n  .click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This lets us reuse our queries for more readable tests, and it automatically\nhandles re-querying the DOM for us as it updates. This is particularly helpful\nwhen dealing with front end frameworks that do a lot of re-rendering!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Commands Are Asynchronous"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "It is very important to understand that Cypress commands don't do anything at\nthe moment they are invoked, but rather enqueue themselves to be run later. This\nis what we mean when we say Cypress commands are asynchronous."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Take this short test, for example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('hides the thing when it is clicked', () => {\n  -{cy.visit('/my/resource/path')::cy.mount(<MyComponent />)}- // Nothing happens yet\n\n  cy.get(\".hides-when-clicked\") // Still nothing happening\n    .should(\"be.visible\") // Still absolutely nothing\n    .click() // Nope, nothing\n\n  cy.get('.hides-when-clicked') // Still nothing happening\n    .should('not.be.visible') // Definitely nothing happening yet\n})\n\n// Ok, the test function has finished executing...\n// We've queued all of these commands and now\n// Cypress will begin running them in order!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress doesn't kick off the browser automation until the test function exits."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Mixing Async and Sync code"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Remembering that Cypress commands run asynchronously is important if you are\nattempting to mix Cypress commands with synchronous code. Synchronous code will\nexecute immediately - not waiting for the Cypress commands above it to execute."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Incorrect usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In the example below, the `el` evaluates immediately, before the `cy.visit()`\nhas executed, so will always evaluate to an empty array."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('does not work as we expect', () => {\n  cy.visit('/my/resource/path') // Nothing happens yet\n\n  cy.get('.awesome-selector') // Still nothing happening\n    .click() // Nope, nothing\n\n  // Cypress.$ is synchronous, so evaluates immediately\n  // there is no element to find yet because\n  // the cy.visit() was only queued to visit\n  // and did not actually visit the application\n  let el = Cypress.$('.new-el') // evaluates immediately as []\n\n  if (el.length) {\n    // evaluates immediately as 0\n    cy.get('.another-selector')\n  } else {\n    // this will always run\n    // because the 'el.length' is 0\n    // when the code executes\n    cy.get('.optional-selector')\n  }\n})\n\n// Ok, the test function has finished executing...\n// We've queued all of these commands and now\n// Cypress will begin running them in order!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Correct usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Below is one way the code above could be rewritten in order to ensure the\ncommands run as expected."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('does not work as we expect', () => {\n  cy.visit('/my/resource/path') // Nothing happens yet\n\n  cy.get('.awesome-selector') // Still nothing happening\n    .click() // Nope, nothing\n    .then(() => {\n      // placing this code inside the .then() ensures\n      // it runs after the cypress commands 'execute'\n      let el = Cypress.$('.new-el') // evaluates after .then()\n\n      if (el.length) {\n        cy.get('.another-selector')\n      } else {\n        cy.get('.optional-selector')\n      }\n    })\n})\n\n// Ok, the test function has finished executing...\n// We've queued all of these commands and now\n// Cypress will begin running them in order!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Incorrect usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In the example below, the check on the `username` value gets evaluated\nimmediately, before the `cy.visit()` has executed, so will always evaluate to\n`undefined`."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('test', () => {\n  let username = undefined // evaluates immediately as undefined\n\n  cy.visit('https://example.cypress.io') // Nothing happens yet\n  cy.get('.user-name') // Still, nothing happens yet\n    .then(($el) => {\n      // Nothing happens yet\n      // this line evaluates after the .then executes\n      username = $el.text()\n    })\n\n  // this evaluates before the .then() above\n  // so the username is still undefined\n  if (username) {\n    // evaluates immediately as undefined\n    cy.contains(username).click()\n  } else {\n    // this will always run\n    // because username will always\n    // evaluate to undefined\n    cy.contains('My Profile').click()\n  }\n})\n\n// Ok, the test function has finished executing...\n// We've queued all of these commands and now\n// Cypress will begin running them in order!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Correct usage"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Below is one way the code above could be rewritten in order to ensure the\ncommands run as expected."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('test', () => {\n  let username = undefined // evaluates immediately as undefined\n\n  cy.visit('https://example.cypress.io') // Nothing happens yet\n  cy.get('.user-name') // Still, nothing happens yet\n    .then(($el) => {\n      // Nothing happens yet\n      // this line evaluates after the .then() executes\n      username = $el.text()\n\n      // evaluates after the .then() executes\n      // it's the correct value gotten from the $el.text()\n      if (username) {\n        cy.contains(username).click()\n      } else {\n        cy.get('My Profile').click()\n      }\n    })\n})\n\n// Ok, the test function has finished executing...\n// We've queued all of these commands and now\n// Cypress will begin running them in order!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Each Cypress command (and chain of commands) returns immediately, having only\nbeen appended to a queue to be executed at a later time."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You purposefully cannot do anything useful with the return value from a\ncommand. Commands are enqueued and managed entirely behind the scenes."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We've designed our API this way because the DOM is a highly mutable object that\nconstantly goes stale. For Cypress to prevent flake, and know when to proceed,\nwe manage commands in a highly controlled deterministic way."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Why can't I use async / await?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're a modern JS programmer you might hear \"asynchronous\" and think: why\ncan't I just use `async/await` instead of learning some proprietary API?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress's APIs are built very differently from what you're likely used to: but\nthese design patterns are incredibly intentional. We'll go into more detail\nlater in this guide."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Avoid loops"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Using JavaScript loop commands like `while` can have unexpected effects. Let's\nsay our application shows a random number on load. We want the test to stop when it finds the number 7. If any other number is\ndisplayed the test reloads the page and checks again."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note: you can find this application and the correct test in our\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress-example-recipes#testing-the-dom",
            "children": [
              {
                "type": "text",
                "value": "Recipes"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Incorrect test"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The test written below WILL NOT work and most likely will crash your browser."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "let found7 = false\n\nwhile (!found7) {\n  // this schedules an infinite number\n  // of \"cy.get...\" commands, eventually crashing\n  // before any of them have a chance to run\n  // and set found7 to true\n  cy.get('#result')\n    .should('not.be.empty')\n    .invoke('text')\n    .then(parseInt)\n    .then((number) => {\n      if (number === 7) {\n        found7 = true\n        cy.log('lucky **7**')\n      } else {\n        cy.reload()\n      }\n    })\n}"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The above test keeps adding more `cy.get('#result')` commands to the test chain\nwithout executing any! The chain of commands keeps growing, but never executes -\nsince the test function never finishes running. The `while` loop never allows\nCypress to start executing even the very first `cy.get(...)` command."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Correct test"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We need to give the test a chance to run a few commands before deciding if it\nneeds to continue. Thus the correct test would use recursion."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "const checkAndReload = () => {\n  // get the element's text, convert into a number\n  cy.get('#result')\n    .should('not.be.empty')\n    .invoke('text')\n    .then(parseInt)\n    .then((number) => {\n      // if the expected number is found\n      // stop adding any more commands\n      if (number === 7) {\n        cy.log('lucky **7**')\n\n        return\n      }\n\n      // otherwise insert more Cypress commands\n      // by calling the function after reload\n      cy.wait(500, { log: false })\n      cy.reload()\n      checkAndReload()\n    })\n}\n\ncy.visit('public/index.html')\ncheckAndReload()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The test runs and correctly finishes."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Commands Run Serially"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After a test function is finished running, Cypress goes to work executing the\ncommands that were enqueued using the `cy.*` command chains."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Let's take another look at an example"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "it('hides the thing when it is clicked', () => {\n  -{cy.visit('/my/resource/path')::cy.mount(<MyComponent />)}- // 1.\n\n  cy.get('.hides-when-clicked') // 2\n    .should('be.visible') // 3\n    .click() // 4\n\n  cy.get('.hides-when-clicked') // 5\n    .should('not.be.visible') // 6\n});"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The test above would cause an execution in this order:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Visit the URL (or mount the component)."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find an element by its selector."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Assert that the element is visible."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Perform a click action on that element."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find an element by its selector."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Assert that the element is no longer visible."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "These actions will always happen serially (one after the other), never in\nparallel (at the same time). Why?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To illustrate this, let's revisit that list of actions and expose some of the\nhidden ✨ magic ✨ Cypress does for us at each step:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Visit the URL ✨ and wait for the page load event to fire after all\nexternal resources have loaded ✨ (or mount the component ✨ and wait for\nthe component to finish mounting ✨)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find an element by its selector ✨ and retry until it is found in the DOM\n✨"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Assert that the element is visible ✨ and retry until the assertion\npasses ✨"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Perform a click action on that element ✨ after we wait for the element to\nreach an actionable state ✨"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Find an element by its selector ✨ and retry until it is found in the DOM\n✨"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Assert that the element is no longer visible ✨ and retry until the\nassertion passes ✨"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As you can see, Cypress does a lot of extra work to ensure the state of the\napplication matches what our commands expect about it. Each command may resolve\nquickly (so fast you won't see them in a pending state) but others may take\nseconds, or even dozens of seconds to resolve."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "While most commands time out after a few seconds, other specialized commands\nthat expect particular things to take much longer like\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/visit.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.visit()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " will naturally wait longer before timing\nout."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "These commands have their own particular timeout values which are documented in\nthe "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress configuration"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Any waiting or retrying that is necessary to ensure a step was successful must\ncomplete before the next step begins. If they don't complete successfully before\nthe timeout is reached, the test will fail."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "The Cypress Command Queue"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "While the API may look similar to Promises, with its `then()` syntax, Cypress\ncommands and queries are not promises - they are serial commands passed into a\ncentral queue, to be executed asynchronously at a later date. These commands are\ndesigned to deliver deterministic, repeatable and consistent tests."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Almost all commands come with built-in\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "retry-ability"
              }
            ]
          },
          {
            "type": "text",
            "value": ". Without\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "retry-ability"
              }
            ]
          },
          {
            "type": "text",
            "value": ", assertions would\nrandomly fail. This would lead to flaky, inconsistent results."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "While Cypress does have a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "`.then()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command, Cypress\ncommands are not Promises and cannot be `await`ed. If you'd like to learn more\nabout handling asynchronous Cypress Commands please read our\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/variables-and-aliases.md",
            "children": [
              {
                "type": "text",
                "value": "Variables and Aliases Guide"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Commands also have some design choices that developers who are used to\npromise-based testing may find unexpected. They are intentional decisions on\nCypress' part, not technical limitations."
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You cannot race or run multiple commands at the same time (in parallel)."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "You cannot add a `.catch` error handler to a failed command."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The whole purpose of Cypress (and what makes it very different from other\ntesting tools) is to create consistent, non-flaky tests that perform identically\nfrom one run to the next. Making this happen isn't free - there are some\ntrade-offs we make that may initially seem unfamiliar to developers accustomed\nto working with Promises or other libraries."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Let's take a look at each trade-off in depth:"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "You cannot race or run multiple commands at the same time"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress guarantees that it will execute all of its commands and queries\ndeterministically and identically every time they are run."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A lot of Cypress commands mutate the state of the browser in some way."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/request.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.request()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " automatically gets + sets cookies to\nand from the remote server."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/clearcookies.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.clearCookies()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " clears all of the browser\ncookies."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " causes your application to react to click\nevents."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "None of the above commands are idempotent; they all cause side effects. Racing\ncommands is not possible because commands must be run in a controlled, serial\nmanner in order to create consistency. Because integration and e2e tests\nprimarily mimic the actions of a real user, Cypress models its command execution\nmodel after a real user working step by step."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "You cannot add a .catch error handler to a failed command"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In Cypress there is no built in error recovery from a failed command. A command\neventually passes, or if it fails, all remaining commands are not executed,\nand the test as a whole fails."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You might be wondering:"
          }
        ]
      },
      {
        "type": "blockquote",
        "children": [
          {
            "type": "paragraph",
            "children": [
              {
                "type": "text",
                "value": "How do I create conditional control flow, using if/else? So that if an element\ndoes (or doesn't) exist, I choose what to do?"
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress does not support this type of conditional control flow because it leads\nto non-deterministic tests - different runs may behave differently, which makes\nthem less consistent and useful for verifying your application's correctness. In\ngeneral, there are only a handful of very specific situations where you can or\nshould create control flow using Cypress commands."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With that said, as long as you are aware of the potential pitfalls with control\nflow, it is possible to do this in Cypress! You can read all about how to do\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/conditional-testing.md",
            "children": [
              {
                "type": "text",
                "value": "conditional testing"
              }
            ]
          },
          {
            "type": "text",
            "value": " here."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As we mentioned previously in this guide:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Assertions describe the desired state of your elements, your\nobjects, and your application."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "What makes Cypress unique from other testing tools is that assertions\nautomatically retry. Think of them as guards - assertions describe what\nyour application should look like, and Cypress will automatically block, wait,\nand retry until it reaches that state."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Asserting in English"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Let's look at how you'd describe an assertion in English:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After clicking on this `<button>`, I expect its class to be `active`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To express this in Cypress you'd write:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('button').click()\ncy.get('button').should('have.class', 'active')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This above test will pass even if the `.active` class is applied to the button\nasynchronously, after an indeterminate period of time or even if the button is\nremoved from the DOM entirely for a while (replaced with a waiting spinner, for\nexample)."
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "// even though we are adding the class\n// after two seconds...\n// this test will still pass!\n$('button').on('click', (e) => {\n  setTimeout(() => {\n    $(e.target).addClass('active')\n  }, 2000)\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Here's another example."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After making an HTTP request to my server, I expect the response body to equal\n`{name: 'Jane'}`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To express this with an assertion you'd write:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.request('/users/1').its('body').should('deep.eq', { name: 'Jane' })"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "When To Assert?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Despite the dozens of assertions Cypress makes available to you, sometimes the\nbest test may make no assertions at all! How can this be? Aren't assertions a\nbasic part of testing?"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Consider this example:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "-{cy.visit('/home')::cy.mount(<MyComponent />)}-\n\ncy.get('.main-menu').contains('New Project').click()\n\ncy.get('.title').type('My Awesome Project')\n\ncy.get('form').submit()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Without a single explicit assertion, there are dozens of ways this test can\nfail. Here's a few:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The initial "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/mount.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.mount()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " or\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/visit.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.visit()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " could respond with something other than\nsuccess."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Any of the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/get.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.get()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " queries could fail to find their\nelements in the DOM."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The element we want to "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " on could be covered\nby another element."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The input we want to "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/type.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.type()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " into could be disabled."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Form submission could result in a non-success status code."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "The in-page JS (the application under test) or the component could throw an\nerror."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "With Cypress, you don't have to write explicit assertions to have a useful test.\nWithout a single `expect()` or `.should()`, a few lines of Cypress can ensure\nthousands of lines of code are working properly across the client and server."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This is because many commands have built in Implicit Assertions which offer\nyou a high level of confidence that your application is working as expected."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Implicit Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Many commands have default, built-in assertions, or rather have requirements\nthat may cause it to fail without needing an explicit assertion you've added."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "For instance:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/visit.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.visit()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the page to send `text/html`\ncontent with a `200` status code."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/request.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.request()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the remote server to exist and\nprovide a response."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/contains.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.contains()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the element with content to\neventually exist in the DOM."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/get.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.get()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the element to eventually exist in the\nDOM."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/find.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.find()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " also expects the element to eventually exist\nin the DOM."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/type.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.type()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the element to eventually be in a\ntypeable state."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects the element to eventually be in an\nactionable state."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/its.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.its()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " expects to eventually find a property on the\ncurrent subject."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Certain commands may have a specific requirement that causes them to immediately\nfail without retrying, such as "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Others, such as DOM queries automatically\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "retry"
              }
            ]
          },
          {
            "type": "text",
            "value": " and wait for their corresponding\nelements to exist before failing."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Action commands automatically wait for their element to reach an\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/interacting-with-elements.md",
            "children": [
              {
                "type": "text",
                "value": "actionable state"
              }
            ]
          },
          {
            "type": "text",
            "value": " before\nfailing."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All DOM commands automatically wait for their elements to exist in the DOM."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You never need to write "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should('exist')`"
              }
            ]
          },
          {
            "type": "text",
            "value": " after\nquerying the DOM."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Most commands give you the flexibility to override or bypass the default ways\nthey can fail, typically by passing a `{force: true}` option."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #1: Existence and Actionability"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy\n  // there is an implicit assertion that this\n  // button must exist in the DOM before proceeding\n  .get('button')\n\n  // before issuing the click, this button must be \"actionable\"\n  // it cannot be disabled, covered, or hidden from view.\n  .click()"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress will automatically wait for elements to pass their implicit\nassertions. See "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Timeouts",
            "children": [
              {
                "type": "text",
                "value": "Timeouts"
              }
            ]
          },
          {
            "type": "text",
            "value": " below for more on how timeouts are\ndetermined."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #2: Reversing the Implicit Assertion"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Most of the time, when querying for elements, you expect them to eventually\nexist. But sometimes you wish to wait until they don't exist."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All you have to do is add that assertion and Cypress will skip implicitly\nwaiting for elements to exist."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('button.close').click()\n\n// now Cypress will wait until this\n// <button> is not in the DOM\ncy.get('button.close').should('not.exist')\n\n// and now make sure this #modal does not exist in the DOM\n// and automatically wait until it's gone!\ncy.get('#modal').should('not.exist')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Core Concept"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you want to disable the default existence assertion, you can add\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should('not.exist')`"
              }
            ]
          },
          {
            "type": "text",
            "value": " to any DOM command."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #3: Other Implicit Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Other commands have other implicit assertions not related to the DOM."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For instance, "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/its.md",
            "children": [
              {
                "type": "text",
                "value": "`.its()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " requires that the property you're\nasking about exists on the object."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// create an empty object\nconst obj = {}\n\n// set the 'foo' property after 1 second\nsetTimeout(() => {\n  obj.foo = 'bar'\n}, 1000)\n\n// .its() will wait until the 'foo' property is on the object\ncy.wrap(obj).its('foo')"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "List of Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress bundles "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/bundled-libraries.md#Chai",
            "children": [
              {
                "type": "text",
                "value": "Chai"
              }
            ]
          },
          {
            "type": "text",
            "value": ",\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/bundled-libraries.md#Chai-jQuery",
            "children": [
              {
                "type": "text",
                "value": "Chai-jQuery"
              }
            ]
          },
          {
            "type": "text",
            "value": ", and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/bundled-libraries.md#Sinon-Chai",
            "children": [
              {
                "type": "text",
                "value": "Sinon-Chai"
              }
            ]
          },
          {
            "type": "text",
            "value": " to provide\nbuilt-in assertions. You can see a comprehensive list of them in\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/assertions.md",
            "children": [
              {
                "type": "text",
                "value": "the list of assertions reference"
              }
            ]
          },
          {
            "type": "text",
            "value": ". You can also\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/recipes.md#Fundamentals",
            "children": [
              {
                "type": "text",
                "value": "write your own assertions as Chai plugins"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\nuse them in Cypress."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Writing Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "There are two ways to write assertions in Cypress:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "As Cypress Commands: Using "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/should.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.should()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " or\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/and.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.and()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "As Mocha Assertions: Using `expect`."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Command Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Using "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " or "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/and.md",
            "children": [
              {
                "type": "text",
                "value": "`.and()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "\ncommands is the preferred way of making assertions in Cypress. These are typical\nCypress commands, which means they apply to the currently yielded subject in the\ncommand chain."
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "// The subject here is the first <tr>.\n// This asserts that the <tr> has an .active class\ncy.get('tbody tr:first').should('have.class', 'active')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can chain multiple assertions together using "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/and.md",
            "children": [
              {
                "type": "text",
                "value": "`.and()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ",\nwhich is another name for "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " that makes things\nmore readable:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "cy.get('#header a')\n  .should('have.class', 'active')\n  .and('have.attr', 'href', '/users')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should('have.class')`"
              }
            ]
          },
          {
            "type": "text",
            "value": " does not change the\nsubject, "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/and.md",
            "children": [
              {
                "type": "text",
                "value": "`.and('have.attr')`"
              }
            ]
          },
          {
            "type": "text",
            "value": " is executed against the same\nelement. This is handy when you need to assert multiple things against a single\nsubject quickly."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Mocha Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Using `expect` allows you to assert on any JavaScript object, not just the\ncurrent subject. This is probably how you're used to seeing assertions written\nin unit tests:"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// the explicit subject here is the boolean: true\nexpect(true).to.be.true"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Did you know you can write Unit Tests in Cypress?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Check out our example recipes for "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/recipes.md",
            "children": [
              {
                "type": "text",
                "value": "unit testing"
              }
            ]
          },
          {
            "type": "text",
            "value": " and\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/recipes.md#Unit-Testing",
            "children": [
              {
                "type": "text",
                "value": "unit testing React components"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Mocha assertions are great when you want to:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Perform custom logic prior to making the assertion."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Make multiple assertions against the same subject."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " assertion allows us to pass a callback\nfunction that takes the yielded subject as its first argument. This works like\n"
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/then.md",
            "children": [
              {
                "type": "text",
                "value": "`.then()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", except Cypress automatically waits and\nretries for everything inside of the callback function to pass."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Complex Assertions"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The example below is a use case where we are asserting across multiple elements.\nUsing a "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " callback function is a great way to\nquery from a parent into multiple children elements and assert something\nabout their state."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Doing so enables you to block and guard Cypress by ensuring the state of\ndescendants matches what you expect without needing to query them individually\nwith regular Cypress DOM commands."
          }
        ]
      },
      {
        "type": "code",
        "lang": "javascript",
        "meta": null,
        "value": "cy.get('p').should(($p) => {\n  // massage our subject from a DOM element\n  // into an array of texts from all of the p's\n  let texts = $p.map((i, el) => {\n    return Cypress.$(el).text()\n  })\n\n  // jQuery map returns jQuery object\n  // and .get() converts this to an array\n  texts = texts.get()\n\n  // array should have length of 3\n  expect(texts).to.have.length(3)\n\n  // with this specific content\n  expect(texts).to.deep.eq([\n    'Some text from first p',\n    'More text from second p',\n    'And even more text from third p',\n  ])\n})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Make sure `.should()` is safe"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When using a callback function with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/should.md",
            "children": [
              {
                "type": "text",
                "value": "`.should()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ", be sure\nthat the entire function can be executed multiple times without side effects.\nCypress applies its "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/retry-ability.md",
            "children": [
              {
                "type": "text",
                "value": "retry logic"
              }
            ]
          },
          {
            "type": "text",
            "value": " to these\nfunctions: if there's a failure, it will repeatedly rerun the assertions until\nthe timeout is reached. That means your code should be retry-safe. The technical\nterm for this means your code must be idempotent."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Timeouts"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Almost all commands can time out in some way."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "All assertions, whether they're the default ones or whether they've been added\nby you all share the same timeout values."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Applying Timeouts"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can modify a commands's timeout. This timeout affects both its default\nassertions (if any) and any specific assertions you've added."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Remember because assertions are used to describe a condition of the previous\ncommands - the `timeout` modification goes on the previous commands not the\nassertions."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #1: Implicit Assertion"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// because .get() has an implicit assertion\n// that this element exists, it can time out and fail\ncy.get('.mobile-nav')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Under the hood Cypress:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": true,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Queries for the element `.mobile-nav`"
                  }
                ]
              },
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✨and waits up to 4 seconds for it to exist in the DOM✨"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #2: Additional Assertions"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// we've added 2 assertions to our test\ncy.get('.mobile-nav').should('be.visible').and('contain', 'Home')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Under the hood Cypress:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": true,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Queries for the element `.mobile-nav`"
                  }
                ]
              },
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✨and waits up to 4 seconds for it to exist in the DOM✨ ✨and be\nvisible✨ ✨and contain the text: Home✨"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The total amount of time Cypress will wait for all of the assertions to pass\nis for the duration of the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/get.md",
            "children": [
              {
                "type": "text",
                "value": "cy.get()"
              }
            ]
          },
          {
            "type": "text",
            "value": " `timeout` (which is 4\nseconds)."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Timeouts can be modified per command and this will affect all implicit\nassertions and any assertions chained after that command."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example #3: Modifying Timeouts"
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// we've modified the timeout which affects the implicit\n// assertions as well as all explicit ones.\ncy.get('.mobile-nav', { timeout: 10000 })\n  .should('be.visible')\n  .and('contain', 'Home')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Under the hood Cypress:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": true,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Gets the element `.mobile-nav`"
                  }
                ]
              },
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "✨and waits up to 10 seconds for it to exist in the DOM✨ ✨and be\nvisible✨ ✨and contain the text: Home✨"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Notice that this timeout has flowed down to all assertions and Cypress will now\nwait up to 10 seconds total for all of them to pass."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note that you never change the timeout inside the assertion. The `timeout`\nparameter always goes inside the command."
          }
        ]
      },
      {
        "type": "code",
        "lang": "js",
        "meta": null,
        "value": "// 🚨 DOES NOT WORK\ncy.get('.selector').should('be.visible', { timeout: 1000 })\n// ✅ THE CORRECT WAY\ncy.get('.selector', { timeout: 1000 }).should('be.visible')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Remember, you are retrying the command with attached assertions, not just the\nassertions!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Default Values"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress offers several different timeout values based on the type of command."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We've set their default timeout durations based on how long we expect certain\nactions to take."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For instance:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/visit.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.visit()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " loads a remote page and does not resolve\nuntil all of the external resources complete their loading phase. This may\ntake awhile, so its default timeout is set to `60000ms`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/exec.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.exec()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " runs a system command such as seeding a\ndatabase. We expect this to potentially take a long time, and its default\ntimeout is set to `60000ms`."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/wait.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`cy.wait()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " actually uses 2 different timeouts. When\nwaiting for a\n"
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/variables-and-aliases.md#Intercepts",
                    "children": [
                      {
                        "type": "text",
                        "value": "routing alias"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": ", we wait\nfor a matching request for `5000ms`, and then additionally for the server's\nresponse for `30000ms`. We expect your application to make a matching request\nquickly, but we expect the server's response to potentially take much longer."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "That leaves most other commands including all DOM queries to time out by default\nafter 4000ms."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Next steps"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/best-practices.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Best Practices"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " — put what you've learned into practice with Cypress conventions for selectors, state management, and test structure."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/tooling/ai-skills.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress AI Skills"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " — use your AI coding tool to write and review Cypress tests with these concepts built in."
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 8581
}