{
  "doc": {
    "id": "app/references/assertions",
    "title": "Assertions in Cypress: A Guide",
    "description": "Assertions available in Cypress with Chai, Chai-jQuery, and Sinon-Chai assertions",
    "section": "app",
    "source_path": "/llm/markdown/app/references/assertions.md",
    "version": "48b03b5502f7aea1d0454750cce208f775403542",
    "updated_at": "2026-05-20T19:00:20.270Z",
    "headings": [
      {
        "id": "app/references/assertions#assertions",
        "text": "Assertions",
        "level": 1
      },
      {
        "id": "app/references/assertions#what-youll-learn",
        "text": "What you'll learn",
        "level": 5
      },
      {
        "id": "app/references/assertions#chai",
        "text": "Chai",
        "level": 2
      },
      {
        "id": "app/references/assertions#chai-jquery",
        "text": "Chai-jQuery",
        "level": 2
      },
      {
        "id": "app/references/assertions#sinon-chai",
        "text": "Sinon-Chai",
        "level": 2
      },
      {
        "id": "app/references/assertions#adding-new-assertions",
        "text": "Adding New Assertions",
        "level": 2
      },
      {
        "id": "app/references/assertions#common-assertions",
        "text": "Common Assertions",
        "level": 2
      },
      {
        "id": "app/references/assertions#length",
        "text": "Length",
        "level": 3
      },
      {
        "id": "app/references/assertions#class",
        "text": "Class",
        "level": 3
      },
      {
        "id": "app/references/assertions#value",
        "text": "Value",
        "level": 3
      },
      {
        "id": "app/references/assertions#text-content",
        "text": "Text Content",
        "level": 3
      },
      {
        "id": "app/references/assertions#visibility",
        "text": "Visibility",
        "level": 3
      },
      {
        "id": "app/references/assertions#existence",
        "text": "Existence",
        "level": 3
      },
      {
        "id": "app/references/assertions#state",
        "text": "State",
        "level": 3
      },
      {
        "id": "app/references/assertions#css",
        "text": "CSS",
        "level": 3
      },
      {
        "id": "app/references/assertions#disabled-property",
        "text": "Disabled property",
        "level": 3
      },
      {
        "id": "app/references/assertions#negative-assertions",
        "text": "Negative assertions",
        "level": 2
      },
      {
        "id": "app/references/assertions#false-passing-tests",
        "text": "False passing tests",
        "level": 3
      },
      {
        "id": "app/references/assertions#should-callback",
        "text": "Should callback",
        "level": 2
      },
      {
        "id": "app/references/assertions#multiple-assertions",
        "text": "Multiple assertions",
        "level": 2
      },
      {
        "id": "app/references/assertions#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "app/references/assertions#what-youll-learn",
      "doc_id": "app/references/assertions",
      "heading": "What you'll learn",
      "heading_level": 5,
      "content_markdown": "##### What you'll learn\n\n*   Assertions available in Cypress with Chai, Chai-jQuery, and Sinon-Chai assertions\n*   How to write assertions for common use cases\n*   How to chain assertions together\n\nCypress bundles the popular [Chai](/llm/markdown/app/references/assertions.md#Chai) assertion library, as well as helpful extensions for [Sinon](/llm/markdown/app/references/assertions.md#Sinon-Chai) and [jQuery](/llm/markdown/app/references/assertions.md#Chai-jQuery), bringing you dozens of powerful assertions for free.\n\nIf you're looking to understand **how** to use these assertions please read about assertions in our [Introduction to Cypress](/llm/markdown/app/core-concepts/introduction-to-cypress.md#Assertions) guide.\n",
      "section": "app",
      "anchors": [
        "what-youll-learn"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 99
    },
    {
      "id": "app/references/assertions#chai",
      "doc_id": "app/references/assertions",
      "heading": "Chai",
      "heading_level": 2,
      "content_markdown": "## Chai\n\n[https://github.com/chaijs/chai](https://github.com/chaijs/chai)\n\nThese chainers are available for BDD assertions (`expect`/`should`). Aliases listed can be used interchangeably with their original chainer. You can see the entire list of available BDD Chai assertions [here](http://chaijs.com/api/bdd/).\n\n| Chainer | Example |\n| --- | --- |\n| not | `.should('not.equal', 'Jane')`  \n`expect(name).to.not.equal('Jane')` |\n| deep | `.should('deep.equal', { name: 'Jane' })`  \n`expect(obj).to.deep.equal({ name: 'Jane' })` |\n| nested | `.should('have.nested.property', 'a.b[1]')`  \n`.should('nested.include', {'a.b[1]': 'y'})`  \n`expect({a: {b: 'x'}}).to.have.nested.property('a.b')`  \n`expect({a: {b: 'x'}}).to.nested.include({'a.b': 'x'})` |\n| ordered | `.should('have.ordered.members', [1, 2])`  \n`expect([1, 2]).to.have.ordered.members([1, 2])`  \n`expect([1, 2]).not.to.have.ordered.members([2, 1])` |\n| any | `.should('have.any.keys', 'age')`  \n`expect(arr).to.have.any.keys('age')` |\n| all | `.should('have.all.keys', 'name', 'age')`  \n`expect(arr).to.have.all.keys('name', 'age')` |\n| a(_type_)  \n**Aliases:** an | `.should('be.a', 'string')`  \n`expect('test').to.be.a('string')` |\n| include(_value_)  \n**Aliases:** contain, includes, contains | `.should('include', 2)`  \n`expect([1,2,3]).to.include(2)` |\n| ok | `.should('not.be.ok')`  \n`expect(undefined).to.not.be.ok` |\n| true | `.should('be.true')`  \n`expect(true).to.be.true` |\n| false | `.should('be.false')`  \n`expect(false).to.be.false` |\n| null | `.should('be.null')`  \n`expect(null).to.be.null` |\n| undefined | `.should('be.undefined')`  \n`expect(undefined).to.be.undefined` |\n| exist | `.should('exist')`  \n`expect(myVar).to.exist` |\n| empty | `.should('be.empty')`  \n`expect([]).to.be.empty` |\n| arguments  \n**Aliases:** Arguments | `.should('be.arguments')`  \n`expect(arguments).to.be.arguments` |\n| equal(_value_)  \n**Aliases:** equals, eq | `.should('equal', 42)`  \n`expect(42).to.equal(42)` |\n| deep.equal(_value_) | `.should('deep.equal', { name: 'Jane' })`  \n`expect({ name: 'Jane' }).to.deep.equal({ name: 'Jane' })` |\n| eql(_value_)  \n**Aliases:** eqls | `.should('eql', { name: 'Jane' })`  \n`expect({ name: 'Jane' }).to.eql({ name: 'Jane' })` |\n| greaterThan(_value_)  \n**Aliases:** gt, above | `.should('be.greaterThan', 5)`  \n`expect(10).to.be.greaterThan(5)` |\n| least(_value_)  \n**Aliases:** gte | `.should('be.at.least', 10)`  \n`expect(10).to.be.at.least(10)` |\n| lessThan(_value_)  \n**Aliases:** lt, below | `.should('be.lessThan', 10)`  \n`expect(5).to.be.lessThan(10)` |\n| most(_value_)  \n**Aliases:** lte | `.should('have.length.of.at.most', 4)`  \n`expect('test').to.have.length.of.at.most(4)` |\n| within(_start_, _finish_) | `.should('be.within', 5, 10)`  \n`expect(7).to.be.within(5, 10)` |\n| instanceOf(_constructor_)  \n**Aliases:** instanceof | `.should('be.instanceOf', Array)`  \n`expect([1, 2, 3]).to.be.instanceOf(Array)` |\n| property(_name_, _\\[value\\]_) | `.should('have.property', 'name')`  \n`expect(obj).to.have.property('name')` |\n| deep.property(_name_, _\\[value\\]_) | `.should('have.deep.property', 'tests[1]', 'e2e')`  \n`expect(deepObj).to.have.deep.property('tests[1]', 'e2e')` |\n| ownProperty(_name_)  \n**Aliases:** haveOwnProperty, own.property | `.should('have.ownProperty', 'length')`  \n`expect('test').to.have.ownProperty('length')` |\n| ownPropertyDescriptor(_name_)  \n**Aliases:** haveOwnPropertyDescriptor | `.should('have.ownPropertyDescriptor', 'a')`  \n`expect({a: 1}).to.have.ownPropertyDescriptor('a')` |\n| lengthOf(_value_) | `.should('have.lengthOf', 4)`  \n`expect('test').to.have.lengthOf(4)` |\n| match(_RegExp_)  \n**Aliases:** matches | `.should('to.match', /^test/)`  \n`expect('testing').to.match(/^test/)` |\n| string(_string_) | `.should('have.string', 'test')`  \n`expect('testing').to.have.string('test')` |\n| keys(_key1_, _\\[key2\\]_, _\\[...\\]_)  \n**Aliases:** key | `.should('have.keys', 'pass', 'fail')`  \n`expect({ pass: 1, fail: 2 }).to.have.keys('pass', 'fail')` |\n| throw(_constructor_)  \n**Aliases:** throws, Throw | `.should('throw', Error)`  \n`expect(fn).to.throw(Error)` |\n| respondTo(_method_)  \n**Aliases:** respondsTo | `.should('respondTo', 'getName')`  \n`expect(obj).to.respondTo('getName')` |\n| itself | `.should('itself.respondTo', 'getName')`  \n`expect(Foo).itself.to.respondTo('bar')` |\n| satisfy(_method_)  \n**Aliases:** satisfies | `.should('satisfy', (num) => num > 0)`  \n`expect(1).to.satisfy((num) => num > 0)` |\n| closeTo(_expected_, _delta_)  \n**Aliases:** approximately | `.should('be.closeTo', 1, 0.5)`  \n`expect(1.5).to.be.closeTo(1, 0.5)` |\n| members(_set_) | `.should('include.members', [3, 2])`  \n`expect([1, 2, 3]).to.include.members([3, 2])` |\n| oneOf(_values_) | `.should('be.oneOf', [1, 2, 3])`  \n`expect(2).to.be.oneOf([1,2,3])` |\n| change(_function_)  \n**Aliases:** changes | `.should('change', obj, 'val')`  \n`expect(fn).to.change(obj, 'val')` |\n| increase(_function_)  \n**Aliases:** increases | `.should('increase', obj, 'val')`  \n`expect(fn).to.increase(obj, 'val')` |\n| decrease(_function_)  \n**Aliases:** decreases | `.should('decrease', obj, 'val')`  \n`expect(fn).to.decrease(obj, 'val')` |\n\nThese getters are also available for BDD assertions. They don't actually do anything, but they enable you to write clear, English sentences.\n\n| Chainable getters |\n| --- |\n| `to`, `be`, `been`, `is`, `that`, `which`, `and`, `has`, `have`, `with`, `at`, `of`, `same` |\n",
      "section": "app",
      "anchors": [
        "chai"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 683
    },
    {
      "id": "app/references/assertions#chai-jquery",
      "doc_id": "app/references/assertions",
      "heading": "Chai-jQuery",
      "heading_level": 2,
      "content_markdown": "## Chai-jQuery\n\n[https://github.com/chaijs/chai-jquery](https://github.com/chaijs/chai-jquery)\n\nThese chainers are available when asserting about a DOM object.\n\nYou will commonly use these chainers after using DOM commands like: [`cy.get()`](/llm/markdown/api/commands/get.md), [`cy.contains()`](/llm/markdown/api/commands/contains.md), etc.\n\n| Chainers | Assertion |\n| --- | --- |\n| attr(_name_, _\\[value\\]_) | `.should('have.attr', 'bar')`  \n`expect($el).to.have.attr('foo', 'bar')` |\n| prop(_name_, _\\[value\\]_) | `.should('have.prop', 'disabled', false)`  \n`expect($el).to.have.prop('disabled', false)` |\n| css(_name_, _\\[value\\]_) | `.should('have.css', 'background-color', 'rgb(0, 0, 0)')`  \n`expect($el).to.have.css('background-color', 'rgb(0, 0, 0)')` |\n| data(_name_, _\\[value\\]_) | `.should('have.data', 'foo', 'bar')`  \n`expect($el).to.have.data('foo', 'bar')` |\n| class(_className_) | `.should('have.class', 'foo')`  \n`expect($el).to.have.class('foo')` |\n| id(_id_) | `.should('have.id', 'foo')`  \n`expect($el).to.have.id('foo')` |\n| html(_html_) | `.should('have.html', 'I love testing')`  \n`expect($el).to.have.html('with Cypress')` |\n| text(_text_) | `.should('have.text', 'I love testing')`  \n`expect($el).to.have.text('with Cypress')` |\n| value(_value_) | `.should('have.value', 'test@dev.com')`  \n`expect($el).to.have.value('test@dev.com')` |\n| visible | `.should('be.visible')`  \n`expect($el).to.be.visible` |\n| hidden | `.should('be.hidden')`  \n`expect($el).to.be.hidden` |\n| selected | `.should('be.selected')`  \n`expect($option).not.to.be.selected` |\n| checked | `.should('be.checked')`  \n`expect($input).not.to.be.checked` |\n| focus\\[ed\\] | `.should('have.focus')`  \n`expect($input).not.to.be.focused`  \n`expect($input).to.have.focus` |\n| enabled | `.should('be.enabled')`  \n`expect($input).to.be.enabled` |\n| disabled | `.should('be.disabled')`  \n`expect($input).to.be.disabled` |\n| empty | `.should('be.empty')`  \n`expect($el).not.to.be.empty` |\n| exist | `.should('exist')`  \n`expect($nonexistent).not.to.exist` |\n| match(_selector_) | `.should('match', ':empty')`  \n`expect($emptyEl).to.match(':empty')` |\n| contain(_text_) | `.should('contain', 'text')`  \n`expect($el).to.contain('text')` |\n| descendants(_selector_) | `.should('have.descendants', 'div')`  \n`expect($el).to.have.descendants('div')` |\n",
      "section": "app",
      "anchors": [
        "chai-jquery"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 263
    },
    {
      "id": "app/references/assertions#sinon-chai",
      "doc_id": "app/references/assertions",
      "heading": "Sinon-Chai",
      "heading_level": 2,
      "content_markdown": "## Sinon-Chai\n\n[https://github.com/domenic/sinon-chai](https://github.com/domenic/sinon-chai)\n\nThese chainers are used on assertions with [`cy.stub()`](/llm/markdown/api/commands/stub.md) and [`cy.spy()`](/llm/markdown/api/commands/spy.md).\n\n| Sinon.JS property/method | Assertion |\n| --- | --- |\n| called | `.should('have.been.called')`  \n`expect(spy).to.be.called` |\n| callCount | `.should('have.callCount', 3)`  \n`expect(spy).to.have.callCount(n)` |\n| calledOnce | `.should('have.been.calledOnce')`  \n`expect(spy).to.be.calledOnce` |\n| calledTwice | `.should('have.been.calledTwice')`  \n`expect(spy).to.be.calledTwice` |\n| calledThrice | `.should('have.been.calledThrice')`  \n`expect(spy).to.be.calledThrice` |\n| calledBefore | `.should('have.been.calledBefore', spy2)`  \n`expect(spy1).to.be.calledBefore(spy2)` |\n| calledAfter | `.should('have.been.calledAfter', spy2)`  \n`expect(spy1).to.be.calledAfter(spy2)` |\n| calledWithNew | `.should('have.been.calledWithNew')`  \n`expect(spy).to.be.calledWithNew` |\n| alwaysCalledWithNew | `.should('have.always.been.calledWithNew')`  \n`expect(spy).to.always.be.calledWithNew` |\n| calledOn | `.should('have.been.calledOn', context)`  \n`expect(spy).to.be.calledOn(context)` |\n| alwaysCalledOn | `.should('have.always.been.calledOn', context)`  \n`expect(spy).to.always.be.calledOn(context)` |\n| calledWith | `.should('have.been.calledWith', ...args)`  \n`expect(spy).to.be.calledWith(...args)` |\n| alwaysCalledWith | `.should('have.always.been.calledWith', ...args)`  \n`expect(spy).to.always.be.calledWith(...args)` |\n| calledOnceWith | `.should('have.been.calledOnceWith', ...args)`  \n`expect(spy).to.be.calledOnceWith(...args)` |\n| calledWithExactly | `.should('have.been.calledWithExactly', ...args)`  \n`expect(spy).to.be.calledWithExactly(...args)` |\n| alwaysCalledWithExactly | `.should('have.always.been.calledWithExactly', ...args)`  \n`expect(spy).to.always.be.calledWithExactly(...args)` |\n| calledOnceWithExactly | `.should('have.been.calledOnceWithExactly', ...args)`  \n`expect(spy).to.be.calledOnceWithExactly(...args)` |\n| calledWithMatch | `.should('have.been.calledWithMatch',...args)`  \n`expect(spy).to.be.calledWithMatch(...args)` |\n| alwaysCalledWithMatch | `.should('have.always.been.calledWithMatch',...args)`  \n`expect(spy).to.always.be.calledWithMatch(...args)` |\n| returned | `.should('have.returned', 'foo')`  \n`expect(spy).to.have.returned(returnVal)` |\n| alwaysReturned | `.should('have.always.returned', 'foo')`  \n`expect(spy).to.have.always.returned(returnVal)` |\n| threw | `.should('have.thrown', TypeError)`  \n`expect(spy).to.have.thrown(errorObjOrErrorTypeStringOrNothing)` |\n| alwaysThrew | `.should('have.always.thrown', 'TypeError')`  \n`expect(spy).to.have.always.thrown(errorObjOrErrorTypeStringOrNothing)` |\n",
      "section": "app",
      "anchors": [
        "sinon-chai"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 236
    },
    {
      "id": "app/references/assertions#adding-new-assertions",
      "doc_id": "app/references/assertions",
      "heading": "Adding New Assertions",
      "heading_level": 2,
      "content_markdown": "## Adding New Assertions\n\nBecause we are using `chai`, that means you can extend it however you'd like. Cypress will \"just work\" with new assertions added to `chai`. You can:\n\n*   Write your own `chai` assertions as [documented here](https://chaijs.com/guide/helpers/).\n*   npm install any existing `chai` library and import into your test file or [support file](/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Support-file).\n\n[Check out our example recipe extending chai with new assertions.](/llm/markdown/app/references/recipes.md#Fundamentals)\n",
      "section": "app",
      "anchors": [
        "adding-new-assertions"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 87
    },
    {
      "id": "app/references/assertions#common-assertions",
      "doc_id": "app/references/assertions",
      "heading": "Common Assertions",
      "heading_level": 2,
      "content_markdown": "## Common Assertions\n\nHere is a list of common element assertions. Notice how we use these assertions (listed above) with [`.should()`](/llm/markdown/api/commands/should.md). You may also want to read about how Cypress [retries](/llm/markdown/app/core-concepts/retry-ability.md) assertions.\n\n### Length\n\n```\n// retry until we find 3 matching <li.selected>cy.get('li.selected').should('have.length', 3)\n```\n\n### Class\n\n```\n// retry until this input does not have class disabledcy.get('form').find('input').should('not.have.class', 'disabled')\n```\n\n### Value\n\n```\n// retry until this textarea has the correct valuecy.get('textarea').should('have.value', 'foo bar baz')\n```\n\n### Text Content\n\n```\n// assert the element's text content is exactly the given textcy.get('[data-testid=\"user-name\"]').should('have.text', 'Joe Smith')// assert the element's text includes the given substringcy.get('[data-testid=\"address\"]').should('include.text', 'Atlanta')// retry until this span does not contain 'click me'cy.get('a').parent('span.help').should('not.contain', 'click me')// the element's text should start with \"Hello\"cy.get('[data-testid=\"greeting\"]')  .invoke('text')  .should('match', /^Hello/)// use cy.contains to find an element with its text// matching the given regular expressioncy.contains('[data-testid=\"greeting\"]', /^Hello/)\n```\n\n**Tip:** read about assertions against text with non-breaking space entities in [How do I get an element's text contents?](/llm/markdown/app/faq.md#How-do-I-get-an-elements-text-contents)\n\n### Visibility\n\n```\n// retry until the element with// data-testid \"form-submit\" is visiblecy.get('[data-testid=\"form-submit\"]').should('be.visible')// retry until the list item with// text \"write tests\" is visiblecy.contains('[data-testid=\"todo\"] li', 'write tests').should('be.visible')\n```\n\n**Note:** if there are multiple elements, the assertions `be.visible` and `not.be.visible` act differently:\n\n```\n// retry until SOME elements are visiblecy.get('li').should('be.visible')// retry until EVERY element is invisiblecy.get('li.hidden').should('not.be.visible')\n```\n\nWatch the short video [\"Multiple elements and should('be.visible') assertion\"](https://www.youtube.com/watch?v=LxkrhUEE2Qk) that shows how to correctly check the visibility of elements.\n\n**Visibility Semantics**\n\nFor detailed information about how Cypress determines element visibility, including the default behavior and the experimental fast visibility algorithm, see [Visibility](/llm/markdown/app/core-concepts/interacting-with-elements.md#Visibility).\n\n### Existence\n\n```\n// retry until loading spinner no longer existscy.get('[data-testid=\"loading\"]').should('not.exist')\n```\n\n### State\n\n```\n// retry until our radio is checkedcy.get(':radio').should('be.checked')\n```\n\n### CSS\n\n```\n// retry until element has matching csscy.get('[data-testid=\"completed\"]').should(  'have.css',  'text-decoration',  'line-through')\n```\n\n```\n// retry while accordion css has the// \"display: none\" propertycy.get('[data-testid=\"accordion\"]').should('not.have.css', 'display', 'none')\n```\n\n### Disabled property\n\n```\n<input type=\"text\" data-testid=\"example-input\" disabled />\n```\n\n```\ncy.get('[data-testid=\"example-input\"]')  .should('be.disabled')  // let's enable this element from the test  .invoke('prop', 'disabled', false)cy.get('[data-testid=\"example-input\"]')  // we can use \"enabled\" assertion  .should('be.enabled')  // or negate the \"disabled\" assertion  .and('not.be.disabled')\n```\n",
      "section": "app",
      "anchors": [
        "common-assertions"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 461
    },
    {
      "id": "app/references/assertions#text-content",
      "doc_id": "app/references/assertions",
      "heading": "Text Content",
      "heading_level": 3,
      "content_markdown": "### Text Content\n\n```\n// assert the element's text content is exactly the given textcy.get('[data-testid=\"user-name\"]').should('have.text', 'Joe Smith')// assert the element's text includes the given substringcy.get('[data-testid=\"address\"]').should('include.text', 'Atlanta')// retry until this span does not contain 'click me'cy.get('a').parent('span.help').should('not.contain', 'click me')// the element's text should start with \"Hello\"cy.get('[data-testid=\"greeting\"]')  .invoke('text')  .should('match', /^Hello/)// use cy.contains to find an element with its text// matching the given regular expressioncy.contains('[data-testid=\"greeting\"]', /^Hello/)\n```\n\n**Tip:** read about assertions against text with non-breaking space entities in [How do I get an element's text contents?](/llm/markdown/app/faq.md#How-do-I-get-an-elements-text-contents)\n",
      "section": "app",
      "anchors": [
        "text-content"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 109
    },
    {
      "id": "app/references/assertions#visibility",
      "doc_id": "app/references/assertions",
      "heading": "Visibility",
      "heading_level": 3,
      "content_markdown": "### Visibility\n\n```\n// retry until the element with// data-testid \"form-submit\" is visiblecy.get('[data-testid=\"form-submit\"]').should('be.visible')// retry until the list item with// text \"write tests\" is visiblecy.contains('[data-testid=\"todo\"] li', 'write tests').should('be.visible')\n```\n\n**Note:** if there are multiple elements, the assertions `be.visible` and `not.be.visible` act differently:\n\n```\n// retry until SOME elements are visiblecy.get('li').should('be.visible')// retry until EVERY element is invisiblecy.get('li.hidden').should('not.be.visible')\n```\n\nWatch the short video [\"Multiple elements and should('be.visible') assertion\"](https://www.youtube.com/watch?v=LxkrhUEE2Qk) that shows how to correctly check the visibility of elements.\n\n**Visibility Semantics**\n\nFor detailed information about how Cypress determines element visibility, including the default behavior and the experimental fast visibility algorithm, see [Visibility](/llm/markdown/app/core-concepts/interacting-with-elements.md#Visibility).\n",
      "section": "app",
      "anchors": [
        "visibility"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 131
    },
    {
      "id": "app/references/assertions#disabled-property",
      "doc_id": "app/references/assertions",
      "heading": "Disabled property",
      "heading_level": 3,
      "content_markdown": "### Disabled property\n\n```\n<input type=\"text\" data-testid=\"example-input\" disabled />\n```\n\n```\ncy.get('[data-testid=\"example-input\"]')  .should('be.disabled')  // let's enable this element from the test  .invoke('prop', 'disabled', false)cy.get('[data-testid=\"example-input\"]')  // we can use \"enabled\" assertion  .should('be.enabled')  // or negate the \"disabled\" assertion  .and('not.be.disabled')\n```\n",
      "section": "app",
      "anchors": [
        "disabled-property"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 52
    },
    {
      "id": "app/references/assertions#negative-assertions",
      "doc_id": "app/references/assertions",
      "heading": "Negative assertions",
      "heading_level": 2,
      "content_markdown": "## Negative assertions\n\nThere are positive and negative assertions. Examples of positive assertions are:\n\n```\ncy.get('[data-testid=\"todo-item\"]')  .should('have.length', 2)  .and('have.class', 'completed')\n```\n\nThe negative assertions have the \"not\" chainer prefixed to the assertion. Examples of negative assertions are:\n\n```\ncy.contains('first todo').should('not.have.class', 'completed')cy.get('[data-testid=\"loading\"]').should('not.be.visible')\n```\n\n### False passing tests\n\nNegative assertions may pass for reasons you weren't expecting. Let's say we want to test that a Todo list app adds a new Todo item after typing the Todo and pressing enter.\n\n**Positive assertions**\n\nWhen adding an element to the list and using a **positive assertion**, the test asserts a specific number of Todo items in our application.\n\nThe test below may still falsely pass if the application behaves unexpectedly, like adding a blank Todo, instead of adding the new Todo with the text \"Write tests\".\n\n```\ncy.get('[data-testid=\"todos\"]').should('have.length', 2)cy.get('[data-testid=\"new-todo\"]').type('Write tests{enter}')// using a positive assertion to check the// exact number of itemscy.get('[data-testid=\"todos\"]').should('have.length', 3)\n```\n\n**Negative assertions**\n\nBut when using a **negative assertion** in the test below, the test can falsely pass when the application behaves in multiple unexpected ways:\n\n*   The app deletes the entire list of Todo items instead of inserting the 3rd Todo\n*   The app deletes a Todo instead of adding a new Todo\n*   The app adds a blank Todo\n\n```\ncy.get('[data-testid=\"todos\"]').should('have.length', 2)cy.get('[data-testid=\"new-todo\"]').type('Write tests{enter}')// using negative assertion to check it's// not a number of itemscy.get('[data-testid=\"todos\"]').should('not.have.length', 2)\n```\n",
      "section": "app",
      "anchors": [
        "negative-assertions"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 301
    },
    {
      "id": "app/references/assertions#false-passing-tests",
      "doc_id": "app/references/assertions",
      "heading": "False passing tests",
      "heading_level": 3,
      "content_markdown": "### False passing tests\n\nNegative assertions may pass for reasons you weren't expecting. Let's say we want to test that a Todo list app adds a new Todo item after typing the Todo and pressing enter.\n\n**Positive assertions**\n\nWhen adding an element to the list and using a **positive assertion**, the test asserts a specific number of Todo items in our application.\n\nThe test below may still falsely pass if the application behaves unexpectedly, like adding a blank Todo, instead of adding the new Todo with the text \"Write tests\".\n\n```\ncy.get('[data-testid=\"todos\"]').should('have.length', 2)cy.get('[data-testid=\"new-todo\"]').type('Write tests{enter}')// using a positive assertion to check the// exact number of itemscy.get('[data-testid=\"todos\"]').should('have.length', 3)\n```\n\n**Negative assertions**\n\nBut when using a **negative assertion** in the test below, the test can falsely pass when the application behaves in multiple unexpected ways:\n\n*   The app deletes the entire list of Todo items instead of inserting the 3rd Todo\n*   The app deletes a Todo instead of adding a new Todo\n*   The app adds a blank Todo\n\n```\ncy.get('[data-testid=\"todos\"]').should('have.length', 2)cy.get('[data-testid=\"new-todo\"]').type('Write tests{enter}')// using negative assertion to check it's// not a number of itemscy.get('[data-testid=\"todos\"]').should('not.have.length', 2)\n```\n",
      "section": "app",
      "anchors": [
        "false-passing-tests"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 245
    },
    {
      "id": "app/references/assertions#should-callback",
      "doc_id": "app/references/assertions",
      "heading": "Should callback",
      "heading_level": 2,
      "content_markdown": "## Should callback\n\nIf built-in assertions are not enough, you can write your own assertion function and pass it as a callback to the `.should()` command. Cypress will automatically [retry](/llm/markdown/app/core-concepts/retry-ability.md) the callback function until it passes or the command times out. See the [`.should()`](/llm/markdown/api/commands/should.md#Function) documentation.\n\n```\n<div class=\"main-abc123 heading-xyz987\">Introduction</div>\n```\n\n```\ncy.get('div').should(($div) => {  expect($div).to.have.length(1)  const className = $div[0].className  // className will be a string like \"main-abc123 heading-xyz987\"  expect(className).to.match(/heading-/)})\n```\n",
      "section": "app",
      "anchors": [
        "should-callback"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 93
    },
    {
      "id": "app/references/assertions#multiple-assertions",
      "doc_id": "app/references/assertions",
      "heading": "Multiple assertions",
      "heading_level": 2,
      "content_markdown": "## Multiple assertions\n\nYou can attach multiple assertions to the same command.\n\n```\n<a  data-testid=\"assertions-link\"  class=\"active\"  href=\"https://on.cypress.io\"  target=\"_blank\">  Cypress Docs</a>\n```\n\n```\ncy.get('[data-testid=\"assertions-link\"]')  .should('have.class', 'active')  .and('have.attr', 'href')  .and('include', 'cypress.io')\n```\n\nNote that all chained assertions will use the same reference to the original subject. For example, if you wanted to test a loading element that first appears and then disappears, the following WILL NOT WORK because the same element cannot be visible and invisible at the same time:\n\n```\n// ⛔️ DOES NOT WORKcy.get('[data-testid=\"loading\"]').should('be.visible').and('not.be.visible')\n```\n\nInstead you should split the assertions and re-query the element:\n\n```\n// ✅ THE CORRECT WAYcy.get('[data-testid=\"loading\"]').should('be.visible')cy.get('[data-testid=\"loading\"]').should('not.be.visible')\n```\n",
      "section": "app",
      "anchors": [
        "multiple-assertions"
      ],
      "path": "/llm/json/chunked/app/references/assertions.json",
      "token_estimate": 136
    }
  ]
}