{
  "doc": {
    "id": "api/commands/origin",
    "title": "cy.origin()",
    "description": "Visit multiple domains of different origin in a single test in Cypress.",
    "section": "api",
    "source_path": "/llm/markdown/api/commands/origin.md",
    "version": "f60251bf707b0077a9535579c9f90d615440cc35",
    "updated_at": "2026-10-16T10:56:58.670Z",
    "headings": [
      {
        "id": "api/commands/origin#origin",
        "text": "origin",
        "level": 1
      },
      {
        "id": "api/commands/origin#syntax",
        "text": "Syntax",
        "level": 2
      },
      {
        "id": "api/commands/origin#usage",
        "text": "Usage",
        "level": 3
      },
      {
        "id": "api/commands/origin#arguments",
        "text": "Arguments",
        "level": 3
      },
      {
        "id": "api/commands/origin#yields",
        "text": "Yields",
        "level": 3
      },
      {
        "id": "api/commands/origin#examples",
        "text": "Examples",
        "level": 2
      },
      {
        "id": "api/commands/origin#using-dynamic-data-in-a-secondary-origin",
        "text": "Using dynamic data in a secondary origin",
        "level": 3
      },
      {
        "id": "api/commands/origin#yielding-a-value",
        "text": "Yielding a value",
        "level": 3
      },
      {
        "id": "api/commands/origin#navigating-to-secondary-origin-with-cy-visit",
        "text": "Navigating to secondary origin with cy.visit",
        "level": 3
      },
      {
        "id": "api/commands/origin#alternative-navigation",
        "text": "Alternative navigation",
        "level": 4
      },
      {
        "id": "api/commands/origin#incorrect-usage",
        "text": "Incorrect Usage",
        "level": 4
      },
      {
        "id": "api/commands/origin#navigating-to-secondary-origin-with-ui",
        "text": "Navigating to secondary origin with UI",
        "level": 3
      },
      {
        "id": "api/commands/origin#navigating-to-multiple-secondary-origins-in-succession",
        "text": "Navigating to multiple secondary origins in succession",
        "level": 3
      },
      {
        "id": "api/commands/origin#sso-login-custom-command",
        "text": "SSO login custom command",
        "level": 3
      },
      {
        "id": "api/commands/origin#learn-more",
        "text": "Learn More",
        "level": 2
      },
      {
        "id": "api/commands/origin#how-to-test-multiple-origins",
        "text": "How to Test Multiple Origins",
        "level": 3
      },
      {
        "id": "api/commands/origin#notes",
        "text": "Notes",
        "level": 2
      },
      {
        "id": "api/commands/origin#serialization",
        "text": "Serialization",
        "level": 3
      },
      {
        "id": "api/commands/origin#dependencies-sharing-code",
        "text": "Dependencies / Sharing Code",
        "level": 3
      },
      {
        "id": "api/commands/origin#example",
        "text": "Example",
        "level": 4
      },
      {
        "id": "api/commands/origin#custom-commands",
        "text": "Custom commands",
        "level": 4
      },
      {
        "id": "api/commands/origin#shared-execution-context",
        "text": "Shared execution context",
        "level": 4
      },
      {
        "id": "api/commands/origin#page-objects",
        "text": "Page objects",
        "level": 4
      },
      {
        "id": "api/commands/origin#callback-restrictions",
        "text": "Callback restrictions",
        "level": 3
      },
      {
        "id": "api/commands/origin#other-limitations",
        "text": "Other limitations",
        "level": 3
      },
      {
        "id": "api/commands/origin#history",
        "text": "History",
        "level": 2
      },
      {
        "id": "api/commands/origin#see-also",
        "text": "See also",
        "level": 2
      }
    ]
  },
  "chunks": [
    {
      "id": "api/commands/origin#syntax",
      "doc_id": "api/commands/origin",
      "heading": "Syntax",
      "heading_level": 2,
      "content_markdown": "## Syntax\n\n```\ncy.origin(url, callbackFn)\ncy.origin(url, options, callbackFn)\n```\n\n### Usage\n\n**Correct Usage**\n\n```\nconst email = getEmail() // Defined elsewhere\n// Run commands in secondary origin, passing in serializable values\ncy.origin('https://example.cypress.io', { args: { email } }, ({ email }) => {\n  // Inside callback baseUrl is https://example.cypress.io\n  cy.visit('/commands/actions')\n  // Commands are executed in secondary origin\n  cy.get('h1').contains('Actions')\n  // Passed in values are accessed via callback args\n  cy.get('.action-email').type(email)\n})\n// Back outside the block, cy.visit uses the primary origin's baseUrl again\ncy.visit('/')\n// Continue running commands on primary origin\ncy.get('h1').contains('My cool site under test')\n```\n\n**Incorrect Usage**\n\n```\nconst email = getEmail()\ncy.visit('https://example.cypress.io/commands/actions')\n// To interact with cross-origin content, move this inside cy.origin() callback\ncy.get('h1').contains('Actions')\n// Origin must be a precise match including scheme, subdomain and port, i.e. https://www.cypress.io\ncy.origin('https://www.cypress.io', () => {\n  cy.visit('/')\n  // Fails because email is not passed in via args\n  cy.contains(email)\n})\n// Won't work because still on www.cypress.io\ncy.get('h1').contains('Actions')\n```\n\n### Arguments\n\n**origin _(String)_**\n\nA string specifying the origin in which the callback is to be executed. This should at the very least contain a hostname. It may also include the scheme and port number. The path may be included, but is not necessary. The hostname must precisely match that of the secondary origin, including all subdomains. Query params are not supported. If no scheme is provided, the scheme defaults to `https`.\n\nThis argument will be used in two ways:\n\n1.  It uniquely identifies a secondary origin in which the commands in the callback will be executed. Cypress will inject itself into this origin, and then send it code to evaluate in that origin, without violating the browser's same-origin policy.\n    \n2.  It overrides the `baseUrl` configured in your [global configuration](/llm/markdown/app/references/configuration.md#Global) while inside the callback. So `cy.visit()` and `cy.request()` will use this URL as a prefix, not the configured `baseUrl`.\n    \n\n**options _(Object)_**\n\nPass in an options object to control the behavior of `cy.origin()`.\n\n| option | description |\n| --- | --- |\n| args | Plain JavaScript object which will be serialized and sent from the primary origin to the secondary origin, where it will be deserialized and passed into the callback function as its first and only argument. |\n\nThe `args` object is the **only** mechanism via which data may be injected into the callback, the callback is **not** a closure and does not retain access to the JavaScript context in which it was declared. Values passed into `args` **must** be serializable.\n\n**callbackFn _(Function)_**\n\nThe function containing the commands to be executed in the secondary origin.\n\nThis function will be stringified, sent to the Cypress instance in the secondary origin and evaluated. If the `args` option is specified, the deserialized args object will be passed into the function as its first and only argument.\n\nThere are a number of limitations placed on commands run inside the callback, see [Callback restrictions](#Callback-restrictions) section below for a full list.\n\n### Yields\n\n*   `cy.origin()` yields the value yielded by the last Cypress command in the callback function.\n*   If the callback contains no Cypress commands, `cy.origin()` yields the return value of the function.\n*   In either of the two cases above, if the value is not serializable, attempting to access the yielded value will throw an error.\n",
      "section": "api",
      "anchors": [
        "syntax"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 719
    },
    {
      "id": "api/commands/origin#usage",
      "doc_id": "api/commands/origin",
      "heading": "Usage",
      "heading_level": 3,
      "content_markdown": "### Usage\n\n**Correct Usage**\n\n```\nconst email = getEmail() // Defined elsewhere\n// Run commands in secondary origin, passing in serializable values\ncy.origin('https://example.cypress.io', { args: { email } }, ({ email }) => {\n  // Inside callback baseUrl is https://example.cypress.io\n  cy.visit('/commands/actions')\n  // Commands are executed in secondary origin\n  cy.get('h1').contains('Actions')\n  // Passed in values are accessed via callback args\n  cy.get('.action-email').type(email)\n})\n// Back outside the block, cy.visit uses the primary origin's baseUrl again\ncy.visit('/')\n// Continue running commands on primary origin\ncy.get('h1').contains('My cool site under test')\n```\n\n**Incorrect Usage**\n\n```\nconst email = getEmail()\ncy.visit('https://example.cypress.io/commands/actions')\n// To interact with cross-origin content, move this inside cy.origin() callback\ncy.get('h1').contains('Actions')\n// Origin must be a precise match including scheme, subdomain and port, i.e. https://www.cypress.io\ncy.origin('https://www.cypress.io', () => {\n  cy.visit('/')\n  // Fails because email is not passed in via args\n  cy.contains(email)\n})\n// Won't work because still on www.cypress.io\ncy.get('h1').contains('Actions')\n```\n",
      "section": "api",
      "anchors": [
        "usage"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 195
    },
    {
      "id": "api/commands/origin#arguments",
      "doc_id": "api/commands/origin",
      "heading": "Arguments",
      "heading_level": 3,
      "content_markdown": "### Arguments\n\n**origin _(String)_**\n\nA string specifying the origin in which the callback is to be executed. This should at the very least contain a hostname. It may also include the scheme and port number. The path may be included, but is not necessary. The hostname must precisely match that of the secondary origin, including all subdomains. Query params are not supported. If no scheme is provided, the scheme defaults to `https`.\n\nThis argument will be used in two ways:\n\n1.  It uniquely identifies a secondary origin in which the commands in the callback will be executed. Cypress will inject itself into this origin, and then send it code to evaluate in that origin, without violating the browser's same-origin policy.\n    \n2.  It overrides the `baseUrl` configured in your [global configuration](/llm/markdown/app/references/configuration.md#Global) while inside the callback. So `cy.visit()` and `cy.request()` will use this URL as a prefix, not the configured `baseUrl`.\n    \n\n**options _(Object)_**\n\nPass in an options object to control the behavior of `cy.origin()`.\n\n| option | description |\n| --- | --- |\n| args | Plain JavaScript object which will be serialized and sent from the primary origin to the secondary origin, where it will be deserialized and passed into the callback function as its first and only argument. |\n\nThe `args` object is the **only** mechanism via which data may be injected into the callback, the callback is **not** a closure and does not retain access to the JavaScript context in which it was declared. Values passed into `args` **must** be serializable.\n\n**callbackFn _(Function)_**\n\nThe function containing the commands to be executed in the secondary origin.\n\nThis function will be stringified, sent to the Cypress instance in the secondary origin and evaluated. If the `args` option is specified, the deserialized args object will be passed into the function as its first and only argument.\n\nThere are a number of limitations placed on commands run inside the callback, see [Callback restrictions](#Callback-restrictions) section below for a full list.\n",
      "section": "api",
      "anchors": [
        "arguments"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 436
    },
    {
      "id": "api/commands/origin#yields",
      "doc_id": "api/commands/origin",
      "heading": "Yields",
      "heading_level": 3,
      "content_markdown": "### Yields\n\n*   `cy.origin()` yields the value yielded by the last Cypress command in the callback function.\n*   If the callback contains no Cypress commands, `cy.origin()` yields the return value of the function.\n*   In either of the two cases above, if the value is not serializable, attempting to access the yielded value will throw an error.\n",
      "section": "api",
      "anchors": [
        "yields"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 76
    },
    {
      "id": "api/commands/origin#examples",
      "doc_id": "api/commands/origin",
      "heading": "Examples",
      "heading_level": 2,
      "content_markdown": "## Examples\n\n### Using dynamic data in a secondary origin\n\nCallbacks are executed inside an entirely separate instance of Cypress, so arguments must be transmitted to the other instance by means of [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). The interface for this mechanism is the `args` option.\n\n```\nconst sentArgs = { username: 'username', password: 'P@55w0rd!' }\ncy.origin(\n  'supersecurelogons.com',\n  // Send the args here...\n  { args: sentArgs },\n  // ...and receive them at the other end here!\n  ({ username, password }) => {\n    cy.visit('/login')\n    cy.get('input#username').type(username)\n    cy.get('input#password').type(password)\n    cy.contains('button', 'Login').click()\n  }\n)\n```\n\n### Yielding a value\n\nValues returned or yielded from the callback function **must** be serializable or they will not be returned to the primary origin. For example, the following will not work:\n\n**Incorrect Usage**\n\n```\ncy.origin('https://example.cypress.io', () => {\n  cy.visit('/')\n  cy.get('h1') // Yields an element, which can't be serialized...\n}).contains('Kitchen Sink') // ...so this will fail\n```\n\nInstead, you must explicitly yield a serializable value:\n\n**Correct Usage**\n\n```\ncy.origin('https://example.cypress.io', () => {\n  cy.visit('/')\n  cy.get('h1').invoke('text') // Yields a string...\n}).should('equal', 'Kitchen Sink') // 👍\n```\n\n### Navigating to secondary origin with cy.visit\n\nWhen navigating to a secondary origin using `cy.visit()`, you can either navigate prior to or after the `cy.origin` block. Errors are no longer thrown on cross-origin navigation, but instead when commands interact with a cross-origin page.\n\n```\n// Do things in primary origin...\n\ncy.origin('example.cypress.io', () => {\n  // Visit https://example.cypress.io/commands/actions\n  cy.visit('/commands/actions')\n  cy.get('h1').contains('Actions')\n})\n```\n\nHere the `baseUrl` inside the `cy.origin()` callback is set to `example.cypress.io` and the protocol defaults to `https`. When `cy.visit()` is called with the path `/commands/actions`, the three are concatenated to make `https://example.cypress.io/commands/actions`.\n\n#### Alternative navigation\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// The cy.origin block is required to interact with the cross-origin page.\ncy.origin('example.cypress.io', () => {\n  cy.get('h1').contains('Actions')\n})\n```\n\nHere the cross-origin page is visited prior to the `cy.origin` block, but any interactions with the window are performed within the block which can communicate with the cross-origin page\n\n#### Incorrect Usage\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// This command will fail, it's executed on localhost but the application is at example.cypress.io\ncy.get('h1').contains('Actions')\n```\n\nHere `cy.get('h1')` fails because we are trying to interact with a cross-origin page outside of the cy.origin block, due to 'same-origin' restrictions, the 'localhost' javascript context can't communicate with 'example.cypress.io'.\n\n### Navigating to secondary origin with UI\n\nNavigating to a secondary origin by clicking a link or button in the primary origin is supported.\n\n```\n// Button in primary origin goes to https://example.cypress.io\ncy.contains('button', 'Go').click()\n\ncy.origin('example.cypress.io', () => {\n  // No cy.visit is needed as the button brought us here\n  cy.get('h1').contains('Kitchen Sink')\n})\n```\n\n### Navigating to multiple secondary origins in succession\n\nCallbacks may **not** themselves contain `cy.origin()` calls, so when visiting multiple origins, do so at the top level of the test.\n\n```\ncy.origin('example.cypress.com', () => {\n  cy.visit('/')\n  cy.url().should('contain', 'example.cypress.com')\n})\n\ncy.origin('cypress-dx.com', () => {\n  cy.visit('/')\n  cy.url().should('contain', 'cypress-dx.com')\n})\n```\n\n### SSO login custom command\n\nA very common requirement is logging in to a site before running a test. If login itself is not the specific focus of the test, it's good to encapsulate this functionality in a `login` [custom command](/llm/markdown/api/cypress-api/custom-commands.md) so you don't have to duplicate this login code in every test. Here's an idealized example of how to do this with `cy.origin()`.\n\n**Inefficient Usage**\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('login', (username, password) => {\n  // Remember to pass in arguments via `args`\n  const args = { username, password }\n  cy.origin('cypress.io', { args }, ({ username, password }) => {\n    // Go to https://example.cypress.com/login\n    cy.visit('/login')\n    cy.contains('Username').find('input').type(username)\n    cy.contains('Password').find('input').type(password)\n    cy.get('button').contains('Login').click()\n  })\n  // Confirm we're back at the primary origin before continuing\n  cy.url().should('contain', '/home')\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      login(username: string, password: string): Chainable<void>\n    }\n  }\n}\n\nCypress.Commands.add('login', (username, password) => {\n  // Remember to pass in arguments via `args`\n  const args = { username, password }\n  cy.origin('cypress.io', { args }, ({ username, password }) => {\n    // Go to https://example.cypress.com/login\n    cy.visit('/login')\n    cy.contains('Username').find('input').type(username)\n    cy.contains('Password').find('input').type(password)\n    cy.get('button').contains('Login').click()\n  })\n  // Confirm we're back at the primary origin before continuing\n  cy.url().should('contain', '/home')\n})\n```\n\nHaving to go through an entire login flow before every test is not very performant. Up until now you could get around this problem by putting login code in the first test of your file, then performing subsequent tests reusing the same session.\n\nHowever, this is no longer possible, since all session state is now cleared between tests. So to avoid this overhead we recommend you use the [`cy.session()`](/llm/markdown/api/commands/session.md) command, which caches session information and reuses it across tests. So now let's enhance our custom login command with `cy.session()` for a complete syndicated login flow with session caching and validation. No mocking, no workarounds, no third-party plugins!\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('login', (username, password) => {\n  const args = { username, password }\n  cy.session(\n    // Username & password can be used as the cache key too\n    args,\n    () => {\n      cy.origin('cypress.io', { args }, ({ username, password }) => {\n        cy.visit('/login')\n        cy.contains('Username').find('input').type(username)\n        cy.contains('Password').find('input').type(password)\n        cy.get('button').contains('Login').click()\n      })\n      cy.url().should('contain', '/home')\n    },\n    {\n      validate() {\n        cy.request('/api/user').its('status').should('eq', 200)\n      },\n    }\n  )\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      login(username: string, password: string): Chainable<void>\n    }\n  }\n}\n\nCypress.Commands.add('login', (username, password) => {\n  const args = { username, password }\n  cy.session(\n    // Username & password can be used as the cache key too\n    args,\n    () => {\n      cy.origin('cypress.io', { args }, ({ username, password }) => {\n        cy.visit('/login')\n        cy.contains('Username').find('input').type(username)\n        cy.contains('Password').find('input').type(password)\n        cy.get('button').contains('Login').click()\n      })\n      cy.url().should('contain', '/home')\n    },\n    {\n      validate() {\n        cy.request('/api/user').its('status').should('eq', 200)\n      },\n    }\n  )\n})\n```\n",
      "section": "api",
      "anchors": [
        "examples"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 1231
    },
    {
      "id": "api/commands/origin#using-dynamic-data-in-a-secondary-origin",
      "doc_id": "api/commands/origin",
      "heading": "Using dynamic data in a secondary origin",
      "heading_level": 3,
      "content_markdown": "### Using dynamic data in a secondary origin\n\nCallbacks are executed inside an entirely separate instance of Cypress, so arguments must be transmitted to the other instance by means of [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). The interface for this mechanism is the `args` option.\n\n```\nconst sentArgs = { username: 'username', password: 'P@55w0rd!' }\ncy.origin(\n  'supersecurelogons.com',\n  // Send the args here...\n  { args: sentArgs },\n  // ...and receive them at the other end here!\n  ({ username, password }) => {\n    cy.visit('/login')\n    cy.get('input#username').type(username)\n    cy.get('input#password').type(password)\n    cy.contains('button', 'Login').click()\n  }\n)\n```\n",
      "section": "api",
      "anchors": [
        "using-dynamic-data-in-a-secondary-origin"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 116
    },
    {
      "id": "api/commands/origin#yielding-a-value",
      "doc_id": "api/commands/origin",
      "heading": "Yielding a value",
      "heading_level": 3,
      "content_markdown": "### Yielding a value\n\nValues returned or yielded from the callback function **must** be serializable or they will not be returned to the primary origin. For example, the following will not work:\n\n**Incorrect Usage**\n\n```\ncy.origin('https://example.cypress.io', () => {\n  cy.visit('/')\n  cy.get('h1') // Yields an element, which can't be serialized...\n}).contains('Kitchen Sink') // ...so this will fail\n```\n\nInstead, you must explicitly yield a serializable value:\n\n**Correct Usage**\n\n```\ncy.origin('https://example.cypress.io', () => {\n  cy.visit('/')\n  cy.get('h1').invoke('text') // Yields a string...\n}).should('equal', 'Kitchen Sink') // 👍\n```\n",
      "section": "api",
      "anchors": [
        "yielding-a-value"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 112
    },
    {
      "id": "api/commands/origin#navigating-to-secondary-origin-with-cy-visit",
      "doc_id": "api/commands/origin",
      "heading": "Navigating to secondary origin with cy.visit",
      "heading_level": 3,
      "content_markdown": "### Navigating to secondary origin with cy.visit\n\nWhen navigating to a secondary origin using `cy.visit()`, you can either navigate prior to or after the `cy.origin` block. Errors are no longer thrown on cross-origin navigation, but instead when commands interact with a cross-origin page.\n\n```\n// Do things in primary origin...\n\ncy.origin('example.cypress.io', () => {\n  // Visit https://example.cypress.io/commands/actions\n  cy.visit('/commands/actions')\n  cy.get('h1').contains('Actions')\n})\n```\n\nHere the `baseUrl` inside the `cy.origin()` callback is set to `example.cypress.io` and the protocol defaults to `https`. When `cy.visit()` is called with the path `/commands/actions`, the three are concatenated to make `https://example.cypress.io/commands/actions`.\n\n#### Alternative navigation\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// The cy.origin block is required to interact with the cross-origin page.\ncy.origin('example.cypress.io', () => {\n  cy.get('h1').contains('Actions')\n})\n```\n\nHere the cross-origin page is visited prior to the `cy.origin` block, but any interactions with the window are performed within the block which can communicate with the cross-origin page\n\n#### Incorrect Usage\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// This command will fail, it's executed on localhost but the application is at example.cypress.io\ncy.get('h1').contains('Actions')\n```\n\nHere `cy.get('h1')` fails because we are trying to interact with a cross-origin page outside of the cy.origin block, due to 'same-origin' restrictions, the 'localhost' javascript context can't communicate with 'example.cypress.io'.\n",
      "section": "api",
      "anchors": [
        "navigating-to-secondary-origin-with-cy-visit"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 280
    },
    {
      "id": "api/commands/origin#alternative-navigation",
      "doc_id": "api/commands/origin",
      "heading": "Alternative navigation",
      "heading_level": 4,
      "content_markdown": "#### Alternative navigation\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// The cy.origin block is required to interact with the cross-origin page.\ncy.origin('example.cypress.io', () => {\n  cy.get('h1').contains('Actions')\n})\n```\n\nHere the cross-origin page is visited prior to the `cy.origin` block, but any interactions with the window are performed within the block which can communicate with the cross-origin page\n",
      "section": "api",
      "anchors": [
        "alternative-navigation"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 79
    },
    {
      "id": "api/commands/origin#incorrect-usage",
      "doc_id": "api/commands/origin",
      "heading": "Incorrect Usage",
      "heading_level": 4,
      "content_markdown": "#### Incorrect Usage\n\n```\n// Do things in primary origin...\n\ncy.visit('https://example.cypress.io/commands/actions')\n\n// This command will fail, it's executed on localhost but the application is at example.cypress.io\ncy.get('h1').contains('Actions')\n```\n\nHere `cy.get('h1')` fails because we are trying to interact with a cross-origin page outside of the cy.origin block, due to 'same-origin' restrictions, the 'localhost' javascript context can't communicate with 'example.cypress.io'.\n",
      "section": "api",
      "anchors": [
        "incorrect-usage"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 77
    },
    {
      "id": "api/commands/origin#navigating-to-secondary-origin-with-ui",
      "doc_id": "api/commands/origin",
      "heading": "Navigating to secondary origin with UI",
      "heading_level": 3,
      "content_markdown": "### Navigating to secondary origin with UI\n\nNavigating to a secondary origin by clicking a link or button in the primary origin is supported.\n\n```\n// Button in primary origin goes to https://example.cypress.io\ncy.contains('button', 'Go').click()\n\ncy.origin('example.cypress.io', () => {\n  // No cy.visit is needed as the button brought us here\n  cy.get('h1').contains('Kitchen Sink')\n})\n```\n",
      "section": "api",
      "anchors": [
        "navigating-to-secondary-origin-with-ui"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 72
    },
    {
      "id": "api/commands/origin#navigating-to-multiple-secondary-origins-in-succession",
      "doc_id": "api/commands/origin",
      "heading": "Navigating to multiple secondary origins in succession",
      "heading_level": 3,
      "content_markdown": "### Navigating to multiple secondary origins in succession\n\nCallbacks may **not** themselves contain `cy.origin()` calls, so when visiting multiple origins, do so at the top level of the test.\n\n```\ncy.origin('example.cypress.com', () => {\n  cy.visit('/')\n  cy.url().should('contain', 'example.cypress.com')\n})\n\ncy.origin('cypress-dx.com', () => {\n  cy.visit('/')\n  cy.url().should('contain', 'cypress-dx.com')\n})\n```\n",
      "section": "api",
      "anchors": [
        "navigating-to-multiple-secondary-origins-in-succession"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 63
    },
    {
      "id": "api/commands/origin#sso-login-custom-command",
      "doc_id": "api/commands/origin",
      "heading": "SSO login custom command",
      "heading_level": 3,
      "content_markdown": "### SSO login custom command\n\nA very common requirement is logging in to a site before running a test. If login itself is not the specific focus of the test, it's good to encapsulate this functionality in a `login` [custom command](/llm/markdown/api/cypress-api/custom-commands.md) so you don't have to duplicate this login code in every test. Here's an idealized example of how to do this with `cy.origin()`.\n\n**Inefficient Usage**\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('login', (username, password) => {\n  // Remember to pass in arguments via `args`\n  const args = { username, password }\n  cy.origin('cypress.io', { args }, ({ username, password }) => {\n    // Go to https://example.cypress.com/login\n    cy.visit('/login')\n    cy.contains('Username').find('input').type(username)\n    cy.contains('Password').find('input').type(password)\n    cy.get('button').contains('Login').click()\n  })\n  // Confirm we're back at the primary origin before continuing\n  cy.url().should('contain', '/home')\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      login(username: string, password: string): Chainable<void>\n    }\n  }\n}\n\nCypress.Commands.add('login', (username, password) => {\n  // Remember to pass in arguments via `args`\n  const args = { username, password }\n  cy.origin('cypress.io', { args }, ({ username, password }) => {\n    // Go to https://example.cypress.com/login\n    cy.visit('/login')\n    cy.contains('Username').find('input').type(username)\n    cy.contains('Password').find('input').type(password)\n    cy.get('button').contains('Login').click()\n  })\n  // Confirm we're back at the primary origin before continuing\n  cy.url().should('contain', '/home')\n})\n```\n\nHaving to go through an entire login flow before every test is not very performant. Up until now you could get around this problem by putting login code in the first test of your file, then performing subsequent tests reusing the same session.\n\nHowever, this is no longer possible, since all session state is now cleared between tests. So to avoid this overhead we recommend you use the [`cy.session()`](/llm/markdown/api/commands/session.md) command, which caches session information and reuses it across tests. So now let's enhance our custom login command with `cy.session()` for a complete syndicated login flow with session caching and validation. No mocking, no workarounds, no third-party plugins!\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('login', (username, password) => {\n  const args = { username, password }\n  cy.session(\n    // Username & password can be used as the cache key too\n    args,\n    () => {\n      cy.origin('cypress.io', { args }, ({ username, password }) => {\n        cy.visit('/login')\n        cy.contains('Username').find('input').type(username)\n        cy.contains('Password').find('input').type(password)\n        cy.get('button').contains('Login').click()\n      })\n      cy.url().should('contain', '/home')\n    },\n    {\n      validate() {\n        cy.request('/api/user').its('status').should('eq', 200)\n      },\n    }\n  )\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      login(username: string, password: string): Chainable<void>\n    }\n  }\n}\n\nCypress.Commands.add('login', (username, password) => {\n  const args = { username, password }\n  cy.session(\n    // Username & password can be used as the cache key too\n    args,\n    () => {\n      cy.origin('cypress.io', { args }, ({ username, password }) => {\n        cy.visit('/login')\n        cy.contains('Username').find('input').type(username)\n        cy.contains('Password').find('input').type(password)\n        cy.get('button').contains('Login').click()\n      })\n      cy.url().should('contain', '/home')\n    },\n    {\n      validate() {\n        cy.request('/api/user').its('status').should('eq', 200)\n      },\n    }\n  )\n})\n```\n",
      "section": "api",
      "anchors": [
        "sso-login-custom-command"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 585
    },
    {
      "id": "api/commands/origin#learn-more",
      "doc_id": "api/commands/origin",
      "heading": "Learn More",
      "heading_level": 2,
      "content_markdown": "## Learn More\n\n### How to Test Multiple Origins\n\nIn this video we walk through how to test multiple origins in a single test. We also look at how to use the `cy.session()` command to cache session information and reuse it across tests. The configuration option `experimentalSessionAndOrigin`, mentioned in the video, is not used since [Cypress 12.0.0](https://docs.cypress.io/app/references/changelog#12-0-0) and the associated functionality is enabled by default.\n",
      "section": "api",
      "anchors": [
        "learn-more"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 87
    },
    {
      "id": "api/commands/origin#how-to-test-multiple-origins",
      "doc_id": "api/commands/origin",
      "heading": "How to Test Multiple Origins",
      "heading_level": 3,
      "content_markdown": "### How to Test Multiple Origins\n\nIn this video we walk through how to test multiple origins in a single test. We also look at how to use the `cy.session()` command to cache session information and reuse it across tests. The configuration option `experimentalSessionAndOrigin`, mentioned in the video, is not used since [Cypress 12.0.0](https://docs.cypress.io/app/references/changelog#12-0-0) and the associated functionality is enabled by default.\n",
      "section": "api",
      "anchors": [
        "how-to-test-multiple-origins"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 83
    },
    {
      "id": "api/commands/origin#notes",
      "doc_id": "api/commands/origin",
      "heading": "Notes",
      "heading_level": 2,
      "content_markdown": "## Notes\n\n### Serialization\n\nWhen entering a `cy.origin()` block, Cypress injects itself at runtime, with all your configuration settings, into the requested origin, and sets up bidirectional communication with that instance. This coordination model requires that any data sent from one instance to another be [serialized](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) for transmission. It is very important to understand that variables **inside** the callback are not shared with the scope **outside** the callback. For example this will not work:\n\n**Incorrect Usage**\n\n```\nconst foo = 1\ncy.origin('cypress.io', () => {\n  cy.visit('/')\n  // This line will throw a ReferenceError because\n  // `foo` is not defined in the scope of the callback\n  cy.get('input').type(foo)\n})\n```\n\nInstead, the variable must be explicitly passed into the callback using the `args` option:\n\n**Correct Usage**\n\n```\nconst foo = 1\ncy.origin('cypress.io', { args: { foo } }, ({ foo }) => {\n  cy.visit('/')\n  // Now it will pass\n  cy.get('input').type(foo)\n})\n```\n\nCypress uses [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) to transfer the `args` option to the secondary origin. This introduces a number of [restrictions on the data which may be passed](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#things_that_dont_work_with_structured_clone) into the callback.\n\n### Dependencies / Sharing Code\n\nWithin the `cy.origin()` callback, [`Cypress.require()`](/llm/markdown/api/cypress-api/require.md) can be used to include [npm](https://www.npmjs.com/) packages and other files. It is functionally the same as using [CommonJS `require()`](https://nodejs.org/api/modules.html#requireid) in browser-targeted code.\n\nIt is not possible to use [CommonJS `require()`](https://nodejs.org/api/modules.html#requireid) or [ES module `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) within the callback.\n\nUsing `Cypress.require()` within the callback requires enabling the [`experimentalOriginDependencies`](/llm/markdown/app/references/experiments.md) option in the Cypress configuration.\n\nRead more in the [`Cypress.require()` doc](/llm/markdown/api/cypress-api/require.md) itself.\n\n#### Example\n\n```\ncy.origin('cypress.io', () => {\n  const _ = Cypress.require('lodash')\n  const utils = Cypress.require('../support/utils')\n\n  // ... use lodash and utils ...\n})\n```\n\n#### Custom commands\n\nThis makes it possible to share custom commands between tests run in primary and secondary origins. We recommend this pattern for setting up your [support file](/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Support-file) and setting up custom commands to run within the `cy.origin()` callback:\n\n`cypress/support/commands.js`:\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      clickLink(label: string): Chainable<JQuery<HTMLElement>>\n    }\n  }\n}\n\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n`cypress/support/e2e.js`:\n\n```\n// makes custom commands available to all Cypress tests in this spec,\n// outside of cy.origin() callbacks\nimport './commands'\n\n// code we only want run per test, so it shouldn't be run as part of\n// the execution of cy.origin() as well\nbeforeEach(() => {\n  // ... code to run before each test ...\n})\n```\n\n`cypress/e2e/spec.cy.js`:\n\n```\nbefore(() => {\n  // makes custom commands available to all subsequent cy.origin('cypress.io)\n  // calls in this spec. put it in your support file to make them available to\n  // all specs\n  cy.origin('cypress.io', () => {\n    Cypress.require('../support/commands')\n  })\n})\n\nit('tests cypress.io', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n```\n\n#### Shared execution context\n\nThe JavaScript execution context is persisted between `cy.origin()` callbacks that share the same origin. This can be used to share code between successive `cy.origin()` calls.\n\n```\nbefore(() => {\n  cy.origin('cypress.io', () => {\n    // makes commands defined in this file available to all callbacks\n    // for cypress.io\n    Cypress.require('../support/commands')\n  })\n})\n\nit('uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n\nit('also uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n\n  cy.origin('cypress-dx.com', () => {\n    // WARNING: cy.clickLink() will not be available because it is a\n    // different origin\n  })\n})\n```\n\n#### Page objects\n\nA common question is how to use Page Object class methods inside `cy.origin()`. You cannot pass a class instance into the callback: the callback is not a closure, so it has no access to variables defined or imported outside it (see [Serialization](#Serialization)), and a class passed through the `args` option arrives without its methods.\n\nInstead, import the page object _inside_ the callback with `Cypress.require()` and instantiate it there. As with any use of `Cypress.require()` in a callback, this requires enabling the [`experimentalOriginDependencies`](/llm/markdown/app/references/experiments.md) option in your Cypress configuration (see [Dependencies / Sharing Code](#Dependencies--Sharing-Code)).\n\n*   cypress/support/LoginPage.js\n*   cypress/support/LoginPage.ts\n\n```\nexport class LoginPage {\n  fillUsername(username) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n```\nexport class LoginPage {\n  fillUsername(username: string) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password: string) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n*   cypress/e2e/spec.cy.js\n*   cypress/e2e/spec.cy.ts\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\nAny data the methods need, such as the credentials above, is still passed in through the `args` option as serializable values.\n\nIf you would rather not import the class, pass only the serializable data the page object holds, such as a map of selectors, through `args` and call the Cypress commands directly inside the callback:\n\n```\nimport selectors from '../support/selectors.json'\n\ncy.origin(\n  'cypress.io',\n  { args: { selectors, username } },\n  ({ selectors, username }) => {\n    cy.visit('/login')\n    cy.get(selectors.username).type(username)\n  }\n)\n```\n\n### Callback restrictions\n\nBecause of the way in which the callback is transmitted and executed, there are certain limitations on what code may be run inside it. In particular, the following Cypress commands will throw errors if used in the callback:\n\n*   `cy.origin()`\n*   [`cy.intercept()`](/llm/markdown/api/commands/intercept.md)\n*   [`cy.session()`](/llm/markdown/api/commands/session.md)\n\n### Other limitations\n\nThere are other testing scenarios which are not currently covered by `cy.origin()`:\n\n*   It cannot run commands [in a different browser window](/llm/markdown/app/references/trade-offs.md#Multiple-browsers-open-at-the-same-time)\n*   It cannot run commands in a different browser tab\n*   It cannot run commands [inside an `<iframe>` element](/llm/markdown/app/faq.md#How-do-I-test-elements-inside-an-iframe)\n",
      "section": "api",
      "anchors": [
        "notes"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 1284
    },
    {
      "id": "api/commands/origin#serialization",
      "doc_id": "api/commands/origin",
      "heading": "Serialization",
      "heading_level": 3,
      "content_markdown": "### Serialization\n\nWhen entering a `cy.origin()` block, Cypress injects itself at runtime, with all your configuration settings, into the requested origin, and sets up bidirectional communication with that instance. This coordination model requires that any data sent from one instance to another be [serialized](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) for transmission. It is very important to understand that variables **inside** the callback are not shared with the scope **outside** the callback. For example this will not work:\n\n**Incorrect Usage**\n\n```\nconst foo = 1\ncy.origin('cypress.io', () => {\n  cy.visit('/')\n  // This line will throw a ReferenceError because\n  // `foo` is not defined in the scope of the callback\n  cy.get('input').type(foo)\n})\n```\n\nInstead, the variable must be explicitly passed into the callback using the `args` option:\n\n**Correct Usage**\n\n```\nconst foo = 1\ncy.origin('cypress.io', { args: { foo } }, ({ foo }) => {\n  cy.visit('/')\n  // Now it will pass\n  cy.get('input').type(foo)\n})\n```\n\nCypress uses [the structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm) to transfer the `args` option to the secondary origin. This introduces a number of [restrictions on the data which may be passed](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#things_that_dont_work_with_structured_clone) into the callback.\n",
      "section": "api",
      "anchors": [
        "serialization"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 239
    },
    {
      "id": "api/commands/origin#dependencies-sharing-code",
      "doc_id": "api/commands/origin",
      "heading": "Dependencies / Sharing Code",
      "heading_level": 3,
      "content_markdown": "### Dependencies / Sharing Code\n\nWithin the `cy.origin()` callback, [`Cypress.require()`](/llm/markdown/api/cypress-api/require.md) can be used to include [npm](https://www.npmjs.com/) packages and other files. It is functionally the same as using [CommonJS `require()`](https://nodejs.org/api/modules.html#requireid) in browser-targeted code.\n\nIt is not possible to use [CommonJS `require()`](https://nodejs.org/api/modules.html#requireid) or [ES module `import()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) within the callback.\n\nUsing `Cypress.require()` within the callback requires enabling the [`experimentalOriginDependencies`](/llm/markdown/app/references/experiments.md) option in the Cypress configuration.\n\nRead more in the [`Cypress.require()` doc](/llm/markdown/api/cypress-api/require.md) itself.\n\n#### Example\n\n```\ncy.origin('cypress.io', () => {\n  const _ = Cypress.require('lodash')\n  const utils = Cypress.require('../support/utils')\n\n  // ... use lodash and utils ...\n})\n```\n\n#### Custom commands\n\nThis makes it possible to share custom commands between tests run in primary and secondary origins. We recommend this pattern for setting up your [support file](/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Support-file) and setting up custom commands to run within the `cy.origin()` callback:\n\n`cypress/support/commands.js`:\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      clickLink(label: string): Chainable<JQuery<HTMLElement>>\n    }\n  }\n}\n\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n`cypress/support/e2e.js`:\n\n```\n// makes custom commands available to all Cypress tests in this spec,\n// outside of cy.origin() callbacks\nimport './commands'\n\n// code we only want run per test, so it shouldn't be run as part of\n// the execution of cy.origin() as well\nbeforeEach(() => {\n  // ... code to run before each test ...\n})\n```\n\n`cypress/e2e/spec.cy.js`:\n\n```\nbefore(() => {\n  // makes custom commands available to all subsequent cy.origin('cypress.io)\n  // calls in this spec. put it in your support file to make them available to\n  // all specs\n  cy.origin('cypress.io', () => {\n    Cypress.require('../support/commands')\n  })\n})\n\nit('tests cypress.io', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n```\n\n#### Shared execution context\n\nThe JavaScript execution context is persisted between `cy.origin()` callbacks that share the same origin. This can be used to share code between successive `cy.origin()` calls.\n\n```\nbefore(() => {\n  cy.origin('cypress.io', () => {\n    // makes commands defined in this file available to all callbacks\n    // for cypress.io\n    Cypress.require('../support/commands')\n  })\n})\n\nit('uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n\nit('also uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n\n  cy.origin('cypress-dx.com', () => {\n    // WARNING: cy.clickLink() will not be available because it is a\n    // different origin\n  })\n})\n```\n\n#### Page objects\n\nA common question is how to use Page Object class methods inside `cy.origin()`. You cannot pass a class instance into the callback: the callback is not a closure, so it has no access to variables defined or imported outside it (see [Serialization](#Serialization)), and a class passed through the `args` option arrives without its methods.\n\nInstead, import the page object _inside_ the callback with `Cypress.require()` and instantiate it there. As with any use of `Cypress.require()` in a callback, this requires enabling the [`experimentalOriginDependencies`](/llm/markdown/app/references/experiments.md) option in your Cypress configuration (see [Dependencies / Sharing Code](#Dependencies--Sharing-Code)).\n\n*   cypress/support/LoginPage.js\n*   cypress/support/LoginPage.ts\n\n```\nexport class LoginPage {\n  fillUsername(username) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n```\nexport class LoginPage {\n  fillUsername(username: string) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password: string) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n*   cypress/e2e/spec.cy.js\n*   cypress/e2e/spec.cy.ts\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\nAny data the methods need, such as the credentials above, is still passed in through the `args` option as serializable values.\n\nIf you would rather not import the class, pass only the serializable data the page object holds, such as a map of selectors, through `args` and call the Cypress commands directly inside the callback:\n\n```\nimport selectors from '../support/selectors.json'\n\ncy.origin(\n  'cypress.io',\n  { args: { selectors, username } },\n  ({ selectors, username }) => {\n    cy.visit('/login')\n    cy.get(selectors.username).type(username)\n  }\n)\n```\n",
      "section": "api",
      "anchors": [
        "dependencies-sharing-code"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 921
    },
    {
      "id": "api/commands/origin#custom-commands",
      "doc_id": "api/commands/origin",
      "heading": "Custom commands",
      "heading_level": 4,
      "content_markdown": "#### Custom commands\n\nThis makes it possible to share custom commands between tests run in primary and secondary origins. We recommend this pattern for setting up your [support file](/llm/markdown/app/core-concepts/writing-and-organizing-tests.md#Support-file) and setting up custom commands to run within the `cy.origin()` callback:\n\n`cypress/support/commands.js`:\n\n*   cypress/support/commands.js\n*   cypress/support/commands.ts\n\n```\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n```\ndeclare global {\n  namespace Cypress {\n    interface Chainable {\n      clickLink(label: string): Chainable<JQuery<HTMLElement>>\n    }\n  }\n}\n\nCypress.Commands.add('clickLink', (label) => {\n  cy.get('a').contains(label).click()\n})\n```\n\n`cypress/support/e2e.js`:\n\n```\n// makes custom commands available to all Cypress tests in this spec,\n// outside of cy.origin() callbacks\nimport './commands'\n\n// code we only want run per test, so it shouldn't be run as part of\n// the execution of cy.origin() as well\nbeforeEach(() => {\n  // ... code to run before each test ...\n})\n```\n\n`cypress/e2e/spec.cy.js`:\n\n```\nbefore(() => {\n  // makes custom commands available to all subsequent cy.origin('cypress.io)\n  // calls in this spec. put it in your support file to make them available to\n  // all specs\n  cy.origin('cypress.io', () => {\n    Cypress.require('../support/commands')\n  })\n})\n\nit('tests cypress.io', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n```\n",
      "section": "api",
      "anchors": [
        "custom-commands"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 252
    },
    {
      "id": "api/commands/origin#shared-execution-context",
      "doc_id": "api/commands/origin",
      "heading": "Shared execution context",
      "heading_level": 4,
      "content_markdown": "#### Shared execution context\n\nThe JavaScript execution context is persisted between `cy.origin()` callbacks that share the same origin. This can be used to share code between successive `cy.origin()` calls.\n\n```\nbefore(() => {\n  cy.origin('cypress.io', () => {\n    // makes commands defined in this file available to all callbacks\n    // for cypress.io\n    Cypress.require('../support/commands')\n  })\n})\n\nit('uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n})\n\nit('also uses cy.origin() + custom command', () => {\n  cy.origin('cypress.io', () => {\n    cy.visit('/page')\n    cy.clickLink('Click Me')\n  })\n\n  cy.origin('cypress-dx.com', () => {\n    // WARNING: cy.clickLink() will not be available because it is a\n    // different origin\n  })\n})\n```\n",
      "section": "api",
      "anchors": [
        "shared-execution-context"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 145
    },
    {
      "id": "api/commands/origin#page-objects",
      "doc_id": "api/commands/origin",
      "heading": "Page objects",
      "heading_level": 4,
      "content_markdown": "#### Page objects\n\nA common question is how to use Page Object class methods inside `cy.origin()`. You cannot pass a class instance into the callback: the callback is not a closure, so it has no access to variables defined or imported outside it (see [Serialization](#Serialization)), and a class passed through the `args` option arrives without its methods.\n\nInstead, import the page object _inside_ the callback with `Cypress.require()` and instantiate it there. As with any use of `Cypress.require()` in a callback, this requires enabling the [`experimentalOriginDependencies`](/llm/markdown/app/references/experiments.md) option in your Cypress configuration (see [Dependencies / Sharing Code](#Dependencies--Sharing-Code)).\n\n*   cypress/support/LoginPage.js\n*   cypress/support/LoginPage.ts\n\n```\nexport class LoginPage {\n  fillUsername(username) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n```\nexport class LoginPage {\n  fillUsername(username: string) {\n    cy.get('[data-test-id=\"username\"]').type(username)\n  }\n\n  fillPassword(password: string) {\n    cy.get('[data-test-id=\"password\"]').type(password)\n  }\n}\n```\n\n*   cypress/e2e/spec.cy.js\n*   cypress/e2e/spec.cy.ts\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\n```\nit('logs in on a secondary origin', () => {\n  cy.origin(\n    'cypress.io',\n    { args: { username, password } },\n    ({ username, password }) => {\n      const { LoginPage } = Cypress.require('../support/LoginPage')\n      const loginPage = new LoginPage()\n\n      cy.visit('/login')\n      loginPage.fillUsername(username)\n      loginPage.fillPassword(password)\n    }\n  )\n})\n```\n\nAny data the methods need, such as the credentials above, is still passed in through the `args` option as serializable values.\n\nIf you would rather not import the class, pass only the serializable data the page object holds, such as a map of selectors, through `args` and call the Cypress commands directly inside the callback:\n\n```\nimport selectors from '../support/selectors.json'\n\ncy.origin(\n  'cypress.io',\n  { args: { selectors, username } },\n  ({ selectors, username }) => {\n    cy.visit('/login')\n    cy.get(selectors.username).type(username)\n  }\n)\n```\n",
      "section": "api",
      "anchors": [
        "page-objects"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 401
    },
    {
      "id": "api/commands/origin#callback-restrictions",
      "doc_id": "api/commands/origin",
      "heading": "Callback restrictions",
      "heading_level": 3,
      "content_markdown": "### Callback restrictions\n\nBecause of the way in which the callback is transmitted and executed, there are certain limitations on what code may be run inside it. In particular, the following Cypress commands will throw errors if used in the callback:\n\n*   `cy.origin()`\n*   [`cy.intercept()`](/llm/markdown/api/commands/intercept.md)\n*   [`cy.session()`](/llm/markdown/api/commands/session.md)\n",
      "section": "api",
      "anchors": [
        "callback-restrictions"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 63
    },
    {
      "id": "api/commands/origin#other-limitations",
      "doc_id": "api/commands/origin",
      "heading": "Other limitations",
      "heading_level": 3,
      "content_markdown": "### Other limitations\n\nThere are other testing scenarios which are not currently covered by `cy.origin()`:\n\n*   It cannot run commands [in a different browser window](/llm/markdown/app/references/trade-offs.md#Multiple-browsers-open-at-the-same-time)\n*   It cannot run commands in a different browser tab\n*   It cannot run commands [inside an `<iframe>` element](/llm/markdown/app/faq.md#How-do-I-test-elements-inside-an-iframe)\n",
      "section": "api",
      "anchors": [
        "other-limitations"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 59
    },
    {
      "id": "api/commands/origin#history",
      "doc_id": "api/commands/origin",
      "heading": "History",
      "heading_level": 2,
      "content_markdown": "## History\n\n| Version | Changes |\n| --- | --- |\n| [14.0.0](/llm/markdown/app/references/changelog.md#14-0-0) | `cy.origin()` is now required when navigating between origins in the same test, rather than superdomains. |\n| [12.6.0](/llm/markdown/app/references/changelog.md#10-7-0) | Support for `Cypress.require()` added and support for CommonJS `require()` and ES module `import()` removed |\n| [10.11.0](/llm/markdown/app/references/changelog.md#10-7-0) | Support for CommonJS `require()` and ES module `import()` added and support for `Cypress.require()` removed |\n| [10.7.0](/llm/markdown/app/references/changelog.md#10-7-0) | Support for `Cypress.require()` added |\n",
      "section": "api",
      "anchors": [
        "history"
      ],
      "path": "/llm/json/chunked/api/commands/origin.json",
      "token_estimate": 100
    }
  ]
}