{
  "doc": {
    "id": "api/commands/its",
    "title": "cy.its()",
    "description": "Get a property's value on the previously yielded subject in Cypress.",
    "section": "api",
    "source_path": "/llm/markdown/api/commands/its.md",
    "version": "f97f06d85653c51afe39a9bd3cefda946807f150",
    "updated_at": "2026-10-05T21:01:45.863Z",
    "headings": [
      {
        "id": "api/commands/its#its",
        "text": "its",
        "level": 1
      },
      {
        "id": "api/commands/its#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "api/commands/its#usage",
        "text": "Usage",
        "level": 3
      },
      {
        "id": "api/commands/its#arguments",
        "text": "Arguments",
        "level": 3
      },
      {
        "id": "api/commands/its#yields",
        "text": "Yields",
        "level": 3
      },
      {
        "id": "api/commands/its#examples",
        "text": "Examples",
        "level": 2
      },
      {
        "id": "api/commands/its#objects",
        "text": "Objects",
        "level": 3
      },
      {
        "id": "api/commands/its#get-property",
        "text": "Get property",
        "level": 4
      },
      {
        "id": "api/commands/its#arrays",
        "text": "Arrays",
        "level": 3
      },
      {
        "id": "api/commands/its#get-index",
        "text": "Get index",
        "level": 4
      },
      {
        "id": "api/commands/its#dom-elements",
        "text": "DOM elements",
        "level": 3
      },
      {
        "id": "api/commands/its#get-the-length-property-of-a-dom-element",
        "text": "Get the length property of a DOM element",
        "level": 4
      },
      {
        "id": "api/commands/its#wait-for-a-list-to-finish-rendering-with-its-length",
        "text": "Wait for a list to finish rendering with .its('length')",
        "level": 4
      },
      {
        "id": "api/commands/its#get-a-property-of-the-dom-element-inside-the-jquery-object",
        "text": "Get a property of the DOM element inside the jQuery object",
        "level": 4
      },
      {
        "id": "api/commands/its#requests",
        "text": "Requests",
        "level": 3
      },
      {
        "id": "api/commands/its#get-the-user-object-of-the-responses-body",
        "text": "Get the user object of the response's body",
        "level": 4
      },
      {
        "id": "api/commands/its#intercepted-requests",
        "text": "Intercepted requests",
        "level": 3
      },
      {
        "id": "api/commands/its#assert-on-the-status-code-of-an-intercepted-response",
        "text": "Assert on the status code of an intercepted response",
        "level": 4
      },
      {
        "id": "api/commands/its#assert-on-the-body-of-an-intercepted-request",
        "text": "Assert on the body of an intercepted request",
        "level": 4
      },
      {
        "id": "api/commands/its#strings",
        "text": "Strings",
        "level": 3
      },
      {
        "id": "api/commands/its#get-length-of-title",
        "text": "Get length of title",
        "level": 4
      },
      {
        "id": "api/commands/its#functions",
        "text": "Functions",
        "level": 3
      },
      {
        "id": "api/commands/its#get-function-as-property",
        "text": "Get function as property",
        "level": 4
      },
      {
        "id": "api/commands/its#access-function-properties",
        "text": "Access function properties",
        "level": 4
      },
      {
        "id": "api/commands/its#use-its-to-test-window-fetch",
        "text": "Use .its() to test window.fetch",
        "level": 4
      },
      {
        "id": "api/commands/its#application-state",
        "text": "Application state",
        "level": 3
      },
      {
        "id": "api/commands/its#read-app-state-from-a-store-exposed-on-window",
        "text": "Read app state from a store exposed on window",
        "level": 4
      },
      {
        "id": "api/commands/its#nested-properties",
        "text": "Nested properties",
        "level": 3
      },
      {
        "id": "api/commands/its#existence",
        "text": "Existence",
        "level": 3
      },
      {
        "id": "api/commands/its#wait-for-some-property-to-exist-on-window",
        "text": "Wait for some property to exist on window",
        "level": 4
      },
      {
        "id": "api/commands/its#assert-that-a-property-does-not-exist-on-window",
        "text": "Assert that a property does not exist on window",
        "level": 4
      },
      {
        "id": "api/commands/its#assert-that-a-property-is-null-or-undefined",
        "text": "Assert that a property is null or undefined",
        "level": 4
      },
      {
        "id": "api/commands/its#wait-longer-for-a-property-with-the-timeout-option",
        "text": "Wait longer for a property with the timeout option",
        "level": 4
      },
      {
        "id": "api/commands/its#notes",
        "text": "Notes",
        "level": 2
      },
      {
        "id": "api/commands/its#choosing-between-its-invoke-and-then",
        "text": "Choosing between .its(), .invoke(), and .then()",
        "level": 3
      },
      {
        "id": "api/commands/its#rules",
        "text": "Rules",
        "level": 2
      },
      {
        "id": "api/commands/its#requirements",
        "text": "Requirements",
        "level": 3
      },
      {
        "id": "api/commands/its#assertions",
        "text": "Assertions",
        "level": 3
      },
      {
        "id": "api/commands/its#timeouts",
        "text": "Timeouts",
        "level": 3
      },
      {
        "id": "api/commands/its#command-log",
        "text": "Command Log",
        "level": 2
      },
      {
        "id": "api/commands/its#history",
        "text": "History",
        "level": 2
      },
      {
        "id": "api/commands/its#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "api/commands/its#syntax",
      "doc_id": "api/commands/its",
      "heading": "Syntax",
      "heading_level": 2,
      "content_markdown": "## Syntax\n\n```\n.its(propertyName)\n.its(propertyName, options)\n```\n\n### Usage\n\n**Correct Usage**\n\n```\ncy.wrap({ width: '50' }).its('width') // Get the 'width' property\ncy.window().its('sessionStorage') // Get the 'sessionStorage' property\n```\n\n**Incorrect Usage**\n\n```\ncy.its('window') // Errors, cannot be chained off 'cy'\ncy.clearCookies().its('length') // Errors, 'clearCookies' does not yield Object\n```\n\n### Arguments\n\n**propertyName _(String, Number)_**\n\nIndex, name of property, or path to a nested property to get. A path uses dot notation (`'body.user'`) and can reach into arrays with a numeric segment or bracket notation (`'items.1'` or `'items[1]'`).\n\n**options _(Object)_**\n\nPass in an options object to change the default behavior of `.its()`.\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `log` | `true` | Displays the command in the [Command log](/llm/markdown/app/core-concepts/open-mode.md#Command-Log) |\n| `timeout` | [`defaultCommandTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) | Time to wait for `.its()` to resolve before [timing out](#Timeouts) |\n\n### Yields\n\n*   `.its()` yields the value of the property.\n*   `.its()` is a query, and it is _safe_ to chain further commands.\n",
      "section": "api",
      "anchors": [
        "syntax"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 221
    },
    {
      "id": "api/commands/its#usage",
      "doc_id": "api/commands/its",
      "heading": "Usage",
      "heading_level": 3,
      "content_markdown": "### Usage\n\n**Correct Usage**\n\n```\ncy.wrap({ width: '50' }).its('width') // Get the 'width' property\ncy.window().its('sessionStorage') // Get the 'sessionStorage' property\n```\n\n**Incorrect Usage**\n\n```\ncy.its('window') // Errors, cannot be chained off 'cy'\ncy.clearCookies().its('length') // Errors, 'clearCookies' does not yield Object\n```\n",
      "section": "api",
      "anchors": [
        "usage"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 55
    },
    {
      "id": "api/commands/its#arguments",
      "doc_id": "api/commands/its",
      "heading": "Arguments",
      "heading_level": 3,
      "content_markdown": "### Arguments\n\n**propertyName _(String, Number)_**\n\nIndex, name of property, or path to a nested property to get. A path uses dot notation (`'body.user'`) and can reach into arrays with a numeric segment or bracket notation (`'items.1'` or `'items[1]'`).\n\n**options _(Object)_**\n\nPass in an options object to change the default behavior of `.its()`.\n\n| Option | Default | Description |\n| --- | --- | --- |\n| `log` | `true` | Displays the command in the [Command log](/llm/markdown/app/core-concepts/open-mode.md#Command-Log) |\n| `timeout` | [`defaultCommandTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) | Time to wait for `.its()` to resolve before [timing out](#Timeouts) |\n",
      "section": "api",
      "anchors": [
        "arguments"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 127
    },
    {
      "id": "api/commands/its#examples",
      "doc_id": "api/commands/its",
      "heading": "Examples",
      "heading_level": 2,
      "content_markdown": "## Examples\n\n### Objects\n\n#### Get property\n\n```\ncy.wrap({ age: 52 }).its('age').should('eq', 52) // true\n```\n\n### Arrays\n\n#### Get index\n\n```\ncy.wrap(['Wai Yan', 'Yu']).its(1).should('eq', 'Yu') // true\n```\n\n### DOM elements\n\n#### Get the `length` property of a DOM element\n\n```\ncy.get('ul li') // this yields us a jquery object\n  .its('length') // gets the 'length' property of that jQuery object\n  .should('be.gt', 2) // ensure the length is greater than 2\n```\n\n#### Wait for a list to finish rendering with `.its('length')`\n\n`.its()` is a query, so Cypress re-runs [`cy.get()`](/llm/markdown/api/commands/get.md) and `.its()` together until the assertion passes. If the app renders its list items over time, this waits until all three are on the page.\n\n```\ncy.get('#todo-list li').its('length').should('eq', 3)\n```\n\nIn the Command Log, `.its()` and its assertion stay pending while the list renders, then pass once the third item appears.\n\n#### Get a property of the DOM element inside the jQuery object\n\nCommands like [`cy.get()`](/llm/markdown/api/commands/get.md) yield a jQuery object. Start the path with an index to reach the DOM element inside it, then read the element's own properties, such as the browser's [validity state](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState).\n\n```\ncy.get('#email').type('not-an-email')\ncy.get('#email').its('0.validity.valid').should('be.false')\n```\n\n### Requests\n\n#### Get the `user` object of the response's `body`\n\n```\ncy.request('/users/1')\n  .its('body.user')\n  .then((user) => {\n    // do something with the user\n  })\n```\n\nAlternatively, get the `body` and destructure it:\n\n```\ncy.request('/users/1')\n  .its('body')\n  .then(({ user }) => {\n    // do something with the user\n  })\n```\n\n### Intercepted requests\n\n[`cy.wait()`](/llm/markdown/api/commands/wait.md) on a [`cy.intercept()`](/llm/markdown/api/commands/intercept.md) alias yields the interception, so `.its()` can reach into its `request` and `response`.\n\n#### Assert on the status code of an intercepted response\n\n```\ncy.intercept('GET', '/comments').as('getComments')\ncy.get('#fetch-comments').click()\ncy.wait('@getComments').its('response.statusCode').should('eq', 200)\n```\n\n#### Assert on the body of an intercepted request\n\n```\ncy.intercept('POST', '/comments').as('postComment')\ncy.get('#post-comment').click()\ncy.wait('@postComment')\n  .its('request.body')\n  .should('deep.include', { comment: 'hi' })\n```\n\n### Strings\n\n#### Get `length` of title\n\n```\ncy.title().its('length').should('eq', 24)\n```\n\n### Functions\n\n#### Get function as property\n\n```\nconst fn = () => {\n  return 42\n}\n\ncy.wrap({ getNum: fn }).its('getNum').should('be.a', 'function')\n```\n\n#### Access function properties\n\nYou can access functions to then drill into their own properties instead of invoking them.\n\napp.js\n\n```\n// a basic Factory constructor\nfunction Factory(arg) {\n  this.arg = arg\n}\n\nFactory.create = (arg) => {\n  return new Factory(arg)\n}\n\n// assign it to the window\nwindow.Factory = Factory\n```\n\nspec.cy.js\n\n```\ncy.window() // yields window object\n  .its('Factory') // yields Factory function\n  .invoke('create', 'arg') // now invoke properties on it\n```\n\n#### Use `.its()` to test `window.fetch`\n\n[Check out our example recipe on testing `window.fetch` using `.its()`](/llm/markdown/app/references/recipes.md#Stubbing-and-spying)\n\n### Application state\n\n#### Read app state from a store exposed on `window`\n\nWhen your app exposes its store on `window`, `.its()` and [`.invoke()`](/llm/markdown/api/commands/invoke.md) can read that state directly. The whole chain retries, so the assertion waits for the app to update its state.\n\napp.js\n\n```\n// expose the store only when the app runs inside Cypress\nif (window.Cypress) {\n  window.store = store\n}\n```\n\nspec.cy.js\n\n```\ncy.window()\n  .its('store')\n  .invoke('getState')\n  .its('cart.items')\n  .should('have.length', 2)\n```\n\n### Nested properties\n\nYou can drill into nested properties by using _dot notation_.\n\n```\nconst user = {\n  contacts: {\n    work: {\n      name: 'Kamil',\n    },\n  },\n}\n\ncy.wrap(user).its('contacts.work.name').should('eq', 'Kamil') // true\n```\n\nInclude an array index in the path with a numeric segment or bracket notation.\n\n```\nconst order = {\n  items: [{ name: 'Apple' }, { name: 'Banana' }],\n}\n\ncy.wrap(order).its('items[1].name').should('eq', 'Banana') // true\ncy.wrap(order).its('items.1.name').should('eq', 'Banana') // true\n```\n\n### Existence\n\n#### Wait for some property to exist on `window`\n\n```\ncy.window()\n  .its('globalProp')\n  .then((globalProp) => {\n    // do something now that window.globalProp exists\n  })\n```\n\n#### Assert that a property does not exist on `window`\n\n```\ncy.window().its('evilProp').should('not.exist')\n```\n\n#### Assert that a property is `null` or `undefined`\n\n`.its()` normally retries until a property has a value. Chain an assertion that expects `null` or `undefined`, and `.its()` leaves the decision to that assertion instead.\n\n```\ncy.wrap({ deletedAt: null }).its('deletedAt').should('be.null')\ncy.wrap({ name: 'Jane' }).its('nickname').should('be.undefined')\n```\n\n#### Wait longer for a property with the `timeout` option\n\nPass `timeout` when a property takes longer to appear than [`defaultCommandTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) allows, such as a flag an app sets after a slow startup.\n\n```\ncy.window().its('appReady', { timeout: 10000 }).should('be.true')\n```\n",
      "section": "api",
      "anchors": [
        "examples"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 915
    },
    {
      "id": "api/commands/its#dom-elements",
      "doc_id": "api/commands/its",
      "heading": "DOM elements",
      "heading_level": 3,
      "content_markdown": "### DOM elements\n\n#### Get the `length` property of a DOM element\n\n```\ncy.get('ul li') // this yields us a jquery object\n  .its('length') // gets the 'length' property of that jQuery object\n  .should('be.gt', 2) // ensure the length is greater than 2\n```\n\n#### Wait for a list to finish rendering with `.its('length')`\n\n`.its()` is a query, so Cypress re-runs [`cy.get()`](/llm/markdown/api/commands/get.md) and `.its()` together until the assertion passes. If the app renders its list items over time, this waits until all three are on the page.\n\n```\ncy.get('#todo-list li').its('length').should('eq', 3)\n```\n\nIn the Command Log, `.its()` and its assertion stay pending while the list renders, then pass once the third item appears.\n\n#### Get a property of the DOM element inside the jQuery object\n\nCommands like [`cy.get()`](/llm/markdown/api/commands/get.md) yield a jQuery object. Start the path with an index to reach the DOM element inside it, then read the element's own properties, such as the browser's [validity state](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState).\n\n```\ncy.get('#email').type('not-an-email')\ncy.get('#email').its('0.validity.valid').should('be.false')\n```\n",
      "section": "api",
      "anchors": [
        "dom-elements"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 213
    },
    {
      "id": "api/commands/its#get-the-length-property-of-a-dom-element",
      "doc_id": "api/commands/its",
      "heading": "Get the length property of a DOM element",
      "heading_level": 4,
      "content_markdown": "#### Get the `length` property of a DOM element\n\n```\ncy.get('ul li') // this yields us a jquery object\n  .its('length') // gets the 'length' property of that jQuery object\n  .should('be.gt', 2) // ensure the length is greater than 2\n```\n",
      "section": "api",
      "anchors": [
        "get-the-length-property-of-a-dom-element"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 53
    },
    {
      "id": "api/commands/its#wait-for-a-list-to-finish-rendering-with-its-length",
      "doc_id": "api/commands/its",
      "heading": "Wait for a list to finish rendering with .its('length')",
      "heading_level": 4,
      "content_markdown": "#### Wait for a list to finish rendering with `.its('length')`\n\n`.its()` is a query, so Cypress re-runs [`cy.get()`](/llm/markdown/api/commands/get.md) and `.its()` together until the assertion passes. If the app renders its list items over time, this waits until all three are on the page.\n\n```\ncy.get('#todo-list li').its('length').should('eq', 3)\n```\n\nIn the Command Log, `.its()` and its assertion stay pending while the list renders, then pass once the third item appears.\n",
      "section": "api",
      "anchors": [
        "wait-for-a-list-to-finish-rendering-with-its-length"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 92
    },
    {
      "id": "api/commands/its#get-a-property-of-the-dom-element-inside-the-jquery-object",
      "doc_id": "api/commands/its",
      "heading": "Get a property of the DOM element inside the jQuery object",
      "heading_level": 4,
      "content_markdown": "#### Get a property of the DOM element inside the jQuery object\n\nCommands like [`cy.get()`](/llm/markdown/api/commands/get.md) yield a jQuery object. Start the path with an index to reach the DOM element inside it, then read the element's own properties, such as the browser's [validity state](https://developer.mozilla.org/en-US/docs/Web/API/ValidityState).\n\n```\ncy.get('#email').type('not-an-email')\ncy.get('#email').its('0.validity.valid').should('be.false')\n```\n",
      "section": "api",
      "anchors": [
        "get-a-property-of-the-dom-element-inside-the-jquery-object"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 64
    },
    {
      "id": "api/commands/its#requests",
      "doc_id": "api/commands/its",
      "heading": "Requests",
      "heading_level": 3,
      "content_markdown": "### Requests\n\n#### Get the `user` object of the response's `body`\n\n```\ncy.request('/users/1')\n  .its('body.user')\n  .then((user) => {\n    // do something with the user\n  })\n```\n\nAlternatively, get the `body` and destructure it:\n\n```\ncy.request('/users/1')\n  .its('body')\n  .then(({ user }) => {\n    // do something with the user\n  })\n```\n",
      "section": "api",
      "anchors": [
        "requests"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 64
    },
    {
      "id": "api/commands/its#get-the-user-object-of-the-responses-body",
      "doc_id": "api/commands/its",
      "heading": "Get the user object of the response's body",
      "heading_level": 4,
      "content_markdown": "#### Get the `user` object of the response's `body`\n\n```\ncy.request('/users/1')\n  .its('body.user')\n  .then((user) => {\n    // do something with the user\n  })\n```\n\nAlternatively, get the `body` and destructure it:\n\n```\ncy.request('/users/1')\n  .its('body')\n  .then(({ user }) => {\n    // do something with the user\n  })\n```\n",
      "section": "api",
      "anchors": [
        "get-the-user-object-of-the-responses-body"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 61
    },
    {
      "id": "api/commands/its#intercepted-requests",
      "doc_id": "api/commands/its",
      "heading": "Intercepted requests",
      "heading_level": 3,
      "content_markdown": "### Intercepted requests\n\n[`cy.wait()`](/llm/markdown/api/commands/wait.md) on a [`cy.intercept()`](/llm/markdown/api/commands/intercept.md) alias yields the interception, so `.its()` can reach into its `request` and `response`.\n\n#### Assert on the status code of an intercepted response\n\n```\ncy.intercept('GET', '/comments').as('getComments')\ncy.get('#fetch-comments').click()\ncy.wait('@getComments').its('response.statusCode').should('eq', 200)\n```\n\n#### Assert on the body of an intercepted request\n\n```\ncy.intercept('POST', '/comments').as('postComment')\ncy.get('#post-comment').click()\ncy.wait('@postComment')\n  .its('request.body')\n  .should('deep.include', { comment: 'hi' })\n```\n",
      "section": "api",
      "anchors": [
        "intercepted-requests"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 77
    },
    {
      "id": "api/commands/its#functions",
      "doc_id": "api/commands/its",
      "heading": "Functions",
      "heading_level": 3,
      "content_markdown": "### Functions\n\n#### Get function as property\n\n```\nconst fn = () => {\n  return 42\n}\n\ncy.wrap({ getNum: fn }).its('getNum').should('be.a', 'function')\n```\n\n#### Access function properties\n\nYou can access functions to then drill into their own properties instead of invoking them.\n\napp.js\n\n```\n// a basic Factory constructor\nfunction Factory(arg) {\n  this.arg = arg\n}\n\nFactory.create = (arg) => {\n  return new Factory(arg)\n}\n\n// assign it to the window\nwindow.Factory = Factory\n```\n\nspec.cy.js\n\n```\ncy.window() // yields window object\n  .its('Factory') // yields Factory function\n  .invoke('create', 'arg') // now invoke properties on it\n```\n\n#### Use `.its()` to test `window.fetch`\n\n[Check out our example recipe on testing `window.fetch` using `.its()`](/llm/markdown/app/references/recipes.md#Stubbing-and-spying)\n",
      "section": "api",
      "anchors": [
        "functions"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 149
    },
    {
      "id": "api/commands/its#access-function-properties",
      "doc_id": "api/commands/its",
      "heading": "Access function properties",
      "heading_level": 4,
      "content_markdown": "#### Access function properties\n\nYou can access functions to then drill into their own properties instead of invoking them.\n\napp.js\n\n```\n// a basic Factory constructor\nfunction Factory(arg) {\n  this.arg = arg\n}\n\nFactory.create = (arg) => {\n  return new Factory(arg)\n}\n\n// assign it to the window\nwindow.Factory = Factory\n```\n\nspec.cy.js\n\n```\ncy.window() // yields window object\n  .its('Factory') // yields Factory function\n  .invoke('create', 'arg') // now invoke properties on it\n```\n",
      "section": "api",
      "anchors": [
        "access-function-properties"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 97
    },
    {
      "id": "api/commands/its#application-state",
      "doc_id": "api/commands/its",
      "heading": "Application state",
      "heading_level": 3,
      "content_markdown": "### Application state\n\n#### Read app state from a store exposed on `window`\n\nWhen your app exposes its store on `window`, `.its()` and [`.invoke()`](/llm/markdown/api/commands/invoke.md) can read that state directly. The whole chain retries, so the assertion waits for the app to update its state.\n\napp.js\n\n```\n// expose the store only when the app runs inside Cypress\nif (window.Cypress) {\n  window.store = store\n}\n```\n\nspec.cy.js\n\n```\ncy.window()\n  .its('store')\n  .invoke('getState')\n  .its('cart.items')\n  .should('have.length', 2)\n```\n",
      "section": "api",
      "anchors": [
        "application-state"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 99
    },
    {
      "id": "api/commands/its#read-app-state-from-a-store-exposed-on-window",
      "doc_id": "api/commands/its",
      "heading": "Read app state from a store exposed on window",
      "heading_level": 4,
      "content_markdown": "#### Read app state from a store exposed on `window`\n\nWhen your app exposes its store on `window`, `.its()` and [`.invoke()`](/llm/markdown/api/commands/invoke.md) can read that state directly. The whole chain retries, so the assertion waits for the app to update its state.\n\napp.js\n\n```\n// expose the store only when the app runs inside Cypress\nif (window.Cypress) {\n  window.store = store\n}\n```\n\nspec.cy.js\n\n```\ncy.window()\n  .its('store')\n  .invoke('getState')\n  .its('cart.items')\n  .should('have.length', 2)\n```\n",
      "section": "api",
      "anchors": [
        "read-app-state-from-a-store-exposed-on-window"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 95
    },
    {
      "id": "api/commands/its#nested-properties",
      "doc_id": "api/commands/its",
      "heading": "Nested properties",
      "heading_level": 3,
      "content_markdown": "### Nested properties\n\nYou can drill into nested properties by using _dot notation_.\n\n```\nconst user = {\n  contacts: {\n    work: {\n      name: 'Kamil',\n    },\n  },\n}\n\ncy.wrap(user).its('contacts.work.name').should('eq', 'Kamil') // true\n```\n\nInclude an array index in the path with a numeric segment or bracket notation.\n\n```\nconst order = {\n  items: [{ name: 'Apple' }, { name: 'Banana' }],\n}\n\ncy.wrap(order).its('items[1].name').should('eq', 'Banana') // true\ncy.wrap(order).its('items.1.name').should('eq', 'Banana') // true\n```\n",
      "section": "api",
      "anchors": [
        "nested-properties"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 93
    },
    {
      "id": "api/commands/its#existence",
      "doc_id": "api/commands/its",
      "heading": "Existence",
      "heading_level": 3,
      "content_markdown": "### Existence\n\n#### Wait for some property to exist on `window`\n\n```\ncy.window()\n  .its('globalProp')\n  .then((globalProp) => {\n    // do something now that window.globalProp exists\n  })\n```\n\n#### Assert that a property does not exist on `window`\n\n```\ncy.window().its('evilProp').should('not.exist')\n```\n\n#### Assert that a property is `null` or `undefined`\n\n`.its()` normally retries until a property has a value. Chain an assertion that expects `null` or `undefined`, and `.its()` leaves the decision to that assertion instead.\n\n```\ncy.wrap({ deletedAt: null }).its('deletedAt').should('be.null')\ncy.wrap({ name: 'Jane' }).its('nickname').should('be.undefined')\n```\n\n#### Wait longer for a property with the `timeout` option\n\nPass `timeout` when a property takes longer to appear than [`defaultCommandTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) allows, such as a flag an app sets after a slow startup.\n\n```\ncy.window().its('appReady', { timeout: 10000 }).should('be.true')\n```\n",
      "section": "api",
      "anchors": [
        "existence"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 165
    },
    {
      "id": "api/commands/its#assert-that-a-property-is-null-or-undefined",
      "doc_id": "api/commands/its",
      "heading": "Assert that a property is null or undefined",
      "heading_level": 4,
      "content_markdown": "#### Assert that a property is `null` or `undefined`\n\n`.its()` normally retries until a property has a value. Chain an assertion that expects `null` or `undefined`, and `.its()` leaves the decision to that assertion instead.\n\n```\ncy.wrap({ deletedAt: null }).its('deletedAt').should('be.null')\ncy.wrap({ name: 'Jane' }).its('nickname').should('be.undefined')\n```\n",
      "section": "api",
      "anchors": [
        "assert-that-a-property-is-null-or-undefined"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 60
    },
    {
      "id": "api/commands/its#wait-longer-for-a-property-with-the-timeout-option",
      "doc_id": "api/commands/its",
      "heading": "Wait longer for a property with the timeout option",
      "heading_level": 4,
      "content_markdown": "#### Wait longer for a property with the `timeout` option\n\nPass `timeout` when a property takes longer to appear than [`defaultCommandTimeout`](/llm/markdown/app/references/configuration.md#Timeouts) allows, such as a flag an app sets after a slow startup.\n\n```\ncy.window().its('appReady', { timeout: 10000 }).should('be.true')\n```\n",
      "section": "api",
      "anchors": [
        "wait-longer-for-a-property-with-the-timeout-option"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 53
    },
    {
      "id": "api/commands/its#notes",
      "doc_id": "api/commands/its",
      "heading": "Notes",
      "heading_level": 2,
      "content_markdown": "## Notes\n\n### Choosing between `.its()`, `.invoke()`, and `.then()`\n\nAll three work with the subject, but they do different jobs:\n\n*   `.its()` reads a property. When the property holds a function, `.its()` yields the function itself without calling it.\n*   [`.invoke()`](/llm/markdown/api/commands/invoke.md) calls a function on the subject and yields what it returns.\n*   [`.then()`](/llm/markdown/api/commands/then.md) runs a callback with the subject, for logic that doesn't fit a single property read or function call.\n\n`.its()` and `.invoke()` are queries, so Cypress retries them together with the queries before them until chained assertions pass. `.then()` runs its callback once and is not [retried](/llm/markdown/app/core-concepts/retry-ability.md#Only-queries-are-retried), so prefer `.its()` or `.invoke()` whenever you assert on the value they yield.\n",
      "section": "api",
      "anchors": [
        "notes"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 151
    },
    {
      "id": "api/commands/its#choosing-between-its-invoke-and-then",
      "doc_id": "api/commands/its",
      "heading": "Choosing between .its(), .invoke(), and .then()",
      "heading_level": 3,
      "content_markdown": "### Choosing between `.its()`, `.invoke()`, and `.then()`\n\nAll three work with the subject, but they do different jobs:\n\n*   `.its()` reads a property. When the property holds a function, `.its()` yields the function itself without calling it.\n*   [`.invoke()`](/llm/markdown/api/commands/invoke.md) calls a function on the subject and yields what it returns.\n*   [`.then()`](/llm/markdown/api/commands/then.md) runs a callback with the subject, for logic that doesn't fit a single property read or function call.\n\n`.its()` and `.invoke()` are queries, so Cypress retries them together with the queries before them until chained assertions pass. `.then()` runs its callback once and is not [retried](/llm/markdown/app/core-concepts/retry-ability.md#Only-queries-are-retried), so prefer `.its()` or `.invoke()` whenever you assert on the value they yield.\n",
      "section": "api",
      "anchors": [
        "choosing-between-its-invoke-and-then"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 148
    },
    {
      "id": "api/commands/its#rules",
      "doc_id": "api/commands/its",
      "heading": "Rules",
      "heading_level": 2,
      "content_markdown": "## Rules\n\n### Requirements\n\n*   `.its()` requires being chained off a previous command.\n\n### Assertions\n\n*   `.its()` automatically [retries](/llm/markdown/app/core-concepts/retry-ability.md) until the property is not `null` or `undefined`, unless the next assertion is one that can pass on those values: `not.exist`, `be.undefined`, `be.null`, `not.be.ok`, `eq`, or `not.eq`. In that case, the assertion alone decides when `.its()` passes.\n*   `.its()` automatically [retries](/llm/markdown/app/core-concepts/retry-ability.md) until all chained assertions have passed.\n\n### Timeouts\n\n*   `.its()` can time out waiting for the property to exist.\n*   `.its()` can time out waiting for assertions you've added to pass.\n",
      "section": "api",
      "anchors": [
        "rules"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 121
    },
    {
      "id": "api/commands/its#assertions",
      "doc_id": "api/commands/its",
      "heading": "Assertions",
      "heading_level": 3,
      "content_markdown": "### Assertions\n\n*   `.its()` automatically [retries](/llm/markdown/app/core-concepts/retry-ability.md) until the property is not `null` or `undefined`, unless the next assertion is one that can pass on those values: `not.exist`, `be.undefined`, `be.null`, `not.be.ok`, `eq`, or `not.eq`. In that case, the assertion alone decides when `.its()` passes.\n*   `.its()` automatically [retries](/llm/markdown/app/core-concepts/retry-ability.md) until all chained assertions have passed.\n",
      "section": "api",
      "anchors": [
        "assertions"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 71
    },
    {
      "id": "api/commands/its#command-log",
      "doc_id": "api/commands/its",
      "heading": "Command Log",
      "heading_level": 2,
      "content_markdown": "## Command Log\n\n**_Get `response.body` of an aliased intercept_**\n\n```\ncy.intercept('/comments', { fixture: 'comments.json' }).as('getComments')\ncy.get('#fetch-comments').click()\ncy.wait('@getComments')\n  .its('response.body')\n  .should('deep.eq', [\n    { id: 1, comment: 'hi' },\n    { id: 2, comment: 'there' },\n  ])\n```\n\nThe commands above display in the Command Log as:\n\nClicking `its` in the Command Log prints the following to the console:\n",
      "section": "api",
      "anchors": [
        "command-log"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 73
    },
    {
      "id": "api/commands/its#history",
      "doc_id": "api/commands/its",
      "heading": "History",
      "heading_level": 2,
      "content_markdown": "## History\n\n| Version | Changes |\n| --- | --- |\n| [12.0.0](/llm/markdown/app/references/changelog.md#12-0-0) | `.its()` is now a query. Overwrite it with [`Cypress.Commands.overwriteQuery()`](/llm/markdown/api/cypress-api/custom-queries.md#Overwriting-Existing-Queries) rather than `Cypress.Commands.overwrite()`. |\n| [3.8.0](/llm/markdown/app/references/changelog.md#3-8-0) | Added support for `options` argument |\n| [3.7.0](/llm/markdown/app/references/changelog.md#3-7-0) | Added support for arguments of type Number for `propertyName` |\n",
      "section": "api",
      "anchors": [
        "history"
      ],
      "path": "/llm/json/chunked/api/commands/its.json",
      "token_estimate": 67
    }
  ]
}