{
  "doc": {
    "id": "app/guides/cross-origin-testing",
    "title": "Cross Origin Testing: Cypress Guide",
    "description": "Learn how to test cross-origin content with Cypress.",
    "section": "app",
    "source_path": "/llm/markdown/app/guides/cross-origin-testing.md",
    "version": "48b03b5502f7aea1d0454750cce208f775403542",
    "updated_at": "2026-05-20T19:00:20.270Z",
    "headings": [
      {
        "id": "app/guides/cross-origin-testing#cross-origin-testing",
        "text": "Cross Origin Testing",
        "level": 1
      },
      {
        "id": "app/guides/cross-origin-testing#what-youll-learn",
        "text": "What you'll learn",
        "level": 5
      },
      {
        "id": "app/guides/cross-origin-testing#web-security",
        "text": "Web Security",
        "level": 2
      },
      {
        "id": "app/guides/cross-origin-testing#what-cypress-does-under-the-hood",
        "text": "What Cypress does under the hood",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#limitations",
        "text": "Limitations",
        "level": 2
      },
      {
        "id": "app/guides/cross-origin-testing#different-origins-per-test-require-cy-origin",
        "text": "Different origins per test require cy.origin()",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#examples-of-test-cases-that-will-error-without-the-use-of-cy-origin",
        "text": "Examples of test cases that will error without the use of cy.origin",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#parts-of-a-url",
        "text": "Parts of a URL",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#origin",
        "text": "Origin",
        "level": 5
      },
      {
        "id": "app/guides/cross-origin-testing#cross-origin-iframes",
        "text": "Cross-origin iframes",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#examples-of-uses-for-cross-origin-iframes",
        "text": "Examples of uses for cross-origin iframes",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#insecure-content",
        "text": "Insecure Content",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#example-of-accessing-insecure-content",
        "text": "Example of accessing insecure content",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#the-solution",
        "text": "The solution",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#same-port-per-test",
        "text": "Same port per test",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#common-workarounds",
        "text": "Common Workarounds",
        "level": 2
      },
      {
        "id": "app/guides/cross-origin-testing#external-navigation",
        "text": "External Navigation",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#form-submission-redirects",
        "text": "Form Submission Redirects",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#javascript-redirects",
        "text": "JavaScript Redirects",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#cross-origin-errors-with-cy-origin",
        "text": "Cross-Origin Errors with cy.origin",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#disabling-web-security",
        "text": "Disabling Web Security",
        "level": 2
      },
      {
        "id": "app/guides/cross-origin-testing#set-chromewebsecurity-to-false",
        "text": "Set chromeWebSecurity to false",
        "level": 3
      },
      {
        "id": "app/guides/cross-origin-testing#set-chromewebsecurity-to-false-in-the-cypress-configuration",
        "text": "Set chromeWebSecurity to false in the Cypress configuration",
        "level": 4
      },
      {
        "id": "app/guides/cross-origin-testing#modifying-obstructive-third-party-code",
        "text": "Modifying Obstructive Third Party Code",
        "level": 2
      },
      {
        "id": "app/guides/cross-origin-testing#other-workarounds",
        "text": "Other workarounds",
        "level": 2
      }
    ]
  },
  "content": {
    "type": "root",
    "children": [
      {
        "type": "heading",
        "depth": 1,
        "children": [
          {
            "type": "text",
            "value": "Cross Origin Testing"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "What you'll learn"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "What strategies Cypress uses to work around same-origin policy"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Limitations and workarounds with cross-origin content"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Web Security"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Browsers adhere to a strict "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy",
            "children": [
              {
                "type": "text",
                "value": "same-origin policy"
              }
            ]
          },
          {
            "type": "text",
            "value": ". This means that browsers restrict access between `<iframes>` when their origin policies don't match."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because Cypress works from within the browser, Cypress must be able to directly communicate with your remote application at all times. Unfortunately, browsers naturally try to prevent Cypress from doing this."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To get around these restrictions, Cypress implements some strategies involving JavaScript code, the browser's internal APIs, and network proxying to play by the rules of same-origin policy. It's our goal to fully automate the application under test without you needing to modify your application's code - and we are mostly able to do this."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "What Cypress does under the hood"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Proxies all HTTP / HTTPS traffic."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Changes the hosted URL to match that of the application under test."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Uses the browser's internal APIs for network level traffic."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When Cypress first loads, the internal Cypress web application is hosted on a random port: something like `http://localhost:64874/__/`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "After the first "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/visit.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.visit()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command is issued in a test, Cypress changes its URL to match the origin of your remote application, thereby solving the first major hurdle of same-origin policy. Your application's code executes the same as it does outside of Cypress, and everything works as expected."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "How is HTTPS supported?"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress must assign and manage browser certificates to be able to modify the traffic in real time. You'll notice Chrome display a warning that the 'SSL certificate does not match'. This is expected behavior. Under the hood we act as our own CA authority and issue certificates dynamically in order to intercept requests otherwise impossible to access. We only do this for the origin currently under test, and bypass other traffic."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Note, that Cypress allows you to optionally specify CA / client certificate information for use with HTTPS sites. See "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/client-certificates.md",
            "children": [
              {
                "type": "text",
                "value": "configuring client certificates"
              }
            ]
          },
          {
            "type": "text",
            "value": ". If the remote server requests a client certificate for a configured URL, Cypress will supply it."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Limitations"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "It's important to note that although we do our very best to ensure your application works normally inside of Cypress, there are some limitations you need to be aware of."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Different-origins-per-test-require-cyorigin",
                    "children": [
                      {
                        "type": "text",
                        "value": "Different origins per test require cy.origin()"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Cross-origin-iframes",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cross-origin iframes are not supported"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Insecure-Content",
                    "children": [
                      {
                        "type": "text",
                        "value": "Navigating from HTTPS to HTTP will error"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "#Same-port-per-test",
                    "children": [
                      {
                        "type": "text",
                        "value": "Cypress requires that the URLs navigated to have the same port"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Different origins per test require `cy.origin()`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress changes its own host URL to match that of your applications. With the exception of `cy.origin`, Cypress requires that the URLs navigated to have the same "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin",
            "children": [
              {
                "type": "text",
                "value": "origin"
              }
            ]
          },
          {
            "type": "text",
            "value": " for the entirety of a single test."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you attempt to visit two different origins, the `cy.origin` command must be used to wrap Cypress commands of the second visited domain. Otherwise, Cypress commands will timeout after the navigation and will eventually error. This is because the commands that were expected to run on the second domain are actually being run on the first domain."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Without `cy.origin()`, you can visit different origins in different tests, but not in the same test."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Examples of test cases that will error without the use of `cy.origin`"
          }
        ]
      },
      {
        "type": "list",
        "ordered": true,
        "start": 1,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/click.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.click()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " an `<a>` with an `href` to a different origin with subsequent Cypress commands being run."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/api/commands/submit.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "`.submit()`"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " a `<form>` that causes your web server to redirect you to a different origin where additional Cypress commands are run."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Issue a JavaScript redirect in your application, such as `window.location.href = '...'`, which navigates to a different origin where additional Cypress commands are run."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In each of these situations, Cypress will lose the ability to automate your application and will error via command timeout unless the `cy.origin` command is used."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Read on to learn about "
          },
          {
            "type": "link",
            "title": null,
            "url": "#Common-Workarounds",
            "children": [
              {
                "type": "text",
                "value": "working around these common problems"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Re-Enabling document.domain Injection"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As of Cypress "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/changelog.md#14-0-0",
            "children": [
              {
                "type": "text",
                "value": "v14.0.0"
              }
            ]
          },
          {
            "type": "text",
            "value": ", "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/API/Document/domain",
            "children": [
              {
                "type": "text",
                "value": "`document.domain`"
              }
            ]
          },
          {
            "type": "text",
            "value": " will no longer be injected into `text/html` pages by default."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This means you must now use `cy.origin()` when navigating between different origins in the same test. Previously, `cy.origin()` was only necessary when navigating between different "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cross-origin-testing.md#Parts-of-a-URL",
            "children": [
              {
                "type": "text",
                "value": "superdomains"
              }
            ]
          },
          {
            "type": "text",
            "value": " in the same test."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "By setting the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#injectDocumentDomain",
            "children": [
              {
                "type": "text",
                "value": "injectDocumentDomain"
              }
            ]
          },
          {
            "type": "text",
            "value": " configuration option to `true`, Cypress will attempt to inject `document.domain` into `text/html` pages."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A superdomain is comprised of the trailing two elements of the hostname, delimited by a `.` (period). Given `https://www.cypress.io`, the superdomain is determined to be `cypress.io`. When this option is enabled, `cy.origin()` is not necessary when navigating between `https://www.cypress.io` and `https://docs.cypress.io`, but is necessary when navigating between `https://www.cypress.io` and `https://www.auth0.com`."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "This will cause issues with certain sites, especially those that use "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin-Agent-Cluster",
                    "children": [
                      {
                        "type": "text",
                        "value": "origin-keyed agent cluster"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": "s."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "This option is deprecated, and will be removed in a future version of Cypress."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Parts of a URL"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We understand this is a bit complicated to understand, so we have built a nifty chart to help clarify the differences!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 5,
        "children": [
          {
            "type": "text",
            "value": "Origin"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "An `origin` is comprised of a URL's `scheme`, `hostname`, and `port`. Given the URLs below, all have the same origin compared to `https://www.cypress.io`:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`https://www.cypress.io/cloud`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`https://www.cypress.io/app`"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "But the following have different origins compared to `https://www.cypress.io`:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`http://www.cypress.io` (different `scheme`)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`https://docs.cypress.io` (different `hostname` due to the subdomain)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`https://www.auth0.com` (different `hostname`)"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "`https://www.cypress.io:81` (different `port`)"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You cannot "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/visit.md",
            "children": [
              {
                "type": "text",
                "value": "visit"
              }
            ]
          },
          {
            "type": "text",
            "value": " two different origins in the same test and continue to interact with the page without the use of the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " command."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/visit.md",
            "children": [
              {
                "type": "text",
                "value": "visit"
              }
            ]
          },
          {
            "type": "text",
            "value": " two or more origins in different tests without needing "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": ". :::"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "For practical purposes, this means the following:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// This test will run without errorit('navigates', () => {  cy.visit('https://www.cypress.io')  cy.visit('https://www.cypress.io/app')  cy.get('selector') // yup all good})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// this will error because the origin https://docs.cypress.io doesn't match the origin https://www.cypress.ioit('navigates', () => {  cy.visit('https://www.cypress.io')  cy.visit('https://docs.cypress.io')  cy.get('selector')})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "To fix the above cross-origin error, use `cy.origin()` to indicate which origin the sequential command should run against:"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "it('navigates', () => {  cy.visit('https://example.cypress.io')  cy.visit('https://docs.cypress.io')  cy.origin('https://docs.cypress.io', () => {    cy.get('selector') // yup all good  })})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "it('navigates', () => {  cy.visit('https://www.cypress.io')})// split visiting different origin in another testit('navigates to new origin', () => {  cy.visit('https://cypress-dx.com')  cy.get('selector') // yup all good})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cross-origin iframes"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your site embeds an `<iframe>` that is a cross-origin frame, Cypress won't be able to automate or communicate with this `<iframe>`."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Examples of uses for cross-origin iframes"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Embedding a Vimeo or YouTube video."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Displaying a credit card form from Stripe or Braintree."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Displaying an embedded login form from Auth0."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Showing comments from Disqus."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you'd like support for this (check our "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/issues/136",
            "children": [
              {
                "type": "text",
                "value": "open issue"
              }
            ]
          },
          {
            "type": "text",
            "value": "), or you can "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cross-origin-testing.md#Disabling-Web-Security",
            "children": [
              {
                "type": "text",
                "value": "disable web security"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Insecure Content"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Because of the way Cypress is designed, if you're testing an HTTPS site, Cypress will error anytime you attempt to navigate back to an HTTP site. This behavior helps highlight a pretty serious security problem with your application."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Example of accessing insecure content"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('https://example.cypress.io')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In your application code, you set `cookies` and store a session on the browser. Now let's imagine you have a single `insecure` link (or JavaScript redirect) in your application code."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<html>  <a href=\"http://example.cypress.io/page2\">Page 2</a></html>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress will immediately fail with the following test code:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('https://example.cypress.io')cy.get('a').click() // will fail"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Browsers refuse to display insecure content on a secure page. Because Cypress initially changed its URL to match `https://example.cypress.io` when the browser followed the `href` to `http://example.cypress.io/page2`, the browser will refuse to display the contents."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Now you may be thinking, This sounds like a problem with Cypress because when I work with my application outside of Cypress it works just fine."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "However, the truth is, Cypress is exposing a security vulnerability in your application, and you want it to fail in Cypress."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "`cookies` that don't have their `secure` flag set to `true` will be sent as clear text to the insecure URL. This leaves your application vulnerable to session hijacking."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "This security vulnerability exists even if your web server forces a `301 redirect` back to the HTTPS site. The original HTTP request was still made once, exposing insecure session information."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "The solution"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Update your HTML or JavaScript code to not navigate to an insecure HTTP page and instead only use HTTPS. Additionally make sure that cookies have their `secure` flag set to `true`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're in a situation where you don't control the code, or otherwise cannot work around this, you can bypass this restriction in Cypress by "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cross-origin-testing.md#Disabling-Web-Security",
            "children": [
              {
                "type": "text",
                "value": "disabling web security"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Same port per test"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress requires that the URLs navigated to have the same port (if specified) for the entirety of a single test. This matches the behavior of the browser's normal "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy",
            "children": [
              {
                "type": "text",
                "value": "same-origin policy"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Common Workarounds"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Let's investigate how you might encounter cross-origin errors in your test code and break down how to work around them in Cypress."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "External Navigation"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "The most common situation where you might encounter this error is when you click on an `<a>` that navigates to another origin."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<html>  <a href=\"https://example.cypress.io\">Cypress</a></html>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080') // where your web server + HTML is hostedcy.get('a').click() // browser navigates to https://cypress.iocy.get('selector').should('exist') // Cypress errors"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We don't recommend visiting an origin that you don't control in your tests which you can read more about "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Visiting-External-Sites",
            "children": [
              {
                "type": "text",
                "value": "here"
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you control this origin, either by owning the hosted instance or by other means, we recommend testing this origin with `cy.origin`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080') // where your web server + HTML is hostedcy.get('a').click() // browser navigates to https://example.cypress.iocy.origin('https://example.cypress.io', () => {  // declare cy.origin command on expected domain  cy.get('selector').should('exist') // Yup all good})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you're not in control of this origin, we recommend you test that the `href` property is correct instead of performing the navigation. This will help lead to more deterministic tests."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// this test verifies the behavior and will run considerably fastercy.visit('http://localhost:8080')cy.get('a').should('have.attr', 'href', 'https://example.cypress.io') // no page load!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If for any reason the two above methods cannot be used, "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": " may be an option to verify content as `cy.request()` is NOT bound to CORS or same-origin policy."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080')cy.get('a').then(($a) => {  // pull off the fully qualified href from the <a>  const url = $a.prop('href')  // make a cy.request to it  cy.request(url).its('body').should('include', '</html>')})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Form Submission Redirects"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When you submit a regular HTML form, the browser will follow the HTTP(s) request."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<html>  <form method=\"POST\" action=\"/submit\">    <input type=\"text\" name=\"email\" />    <input type=\"submit\" value=\"Submit\" />  </form></html>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080')cy.get('form').submit() // submit the form!"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your back end server handling the `/submit` route does a `30x` redirect to a different origin, you'll need to use the `cy.origin` command if running additional Cypress commands after submitting the form."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "routes.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "// node / express code on localhost:8080 serverapp.post('/submit', (req, res) => {  // redirect the browser to cypress.io  res.redirect('https://example.cypress.io')})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can test this with `cy.origin`, which may look like the following test case:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080')cy.get('form').submit() // submit the form!cy.origin('cypress.io', () => {  cy.url().should('contain', 'cypress.io')})"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "A common use case for this is Single sign-on (SSO), OAuth, Open ID Connect (OIDC), or Authentication as a Service platforms, such as "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/authentication-testing/auth0-authentication.md",
            "children": [
              {
                "type": "text",
                "value": "Auth0"
              }
            ]
          },
          {
            "type": "text",
            "value": ", "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/authentication-testing/okta-authentication.md",
            "children": [
              {
                "type": "text",
                "value": "Okta"
              }
            ]
          },
          {
            "type": "text",
            "value": ", "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/authentication-testing/amazon-cognito-authentication.md",
            "children": [
              {
                "type": "text",
                "value": "Amazon Cognito"
              }
            ]
          },
          {
            "type": "text",
            "value": ", and others."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In these situations, if controlling the domain under test, we recommend that you test these with `cy.origin`."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080')cy.get('#login').click() // click a login button, which takes us to our authentication page.cy.origin('cypress.io', () => {  cy.get('#username').type('User1')  cy.get('#password').type('Password123')  // prompts a sign in that redirects to http://localhost:8080 with a token, cookie, or other means of acknowledgement  cy.get('button').contains('Sign In').click()})cy.get('#user-name-welcome').should('equal', 'Welcome, User1!')"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If for any reason you can't leverage `cy.origin`, programmatic authentication is still an option. In this situation you may `POST` to a different server and are redirected elsewhere (typically with the session token in the URL). If that's the case, you can still test this behavior with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/request.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.request()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "In fact we can likely bypass the initial visit altogether and `POST` directly to your SSO server."
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.request('POST', 'https://sso.corp.com/auth', {  username: 'foo',  password: 'bar',}).then((response) => {  // pull out the location redirect  const loc = response.headers['Location']  // parse out the token from the url (assuming its in there)  const token = parseOutMyToken(loc)  // do something with the token that your web application expects  // likely the same behavior as what your SSO does under the hood  // assuming it handles query string tokens like this  cy.visit('http://localhost:8080?token=' + token)  // if you don't need to work with the token you can sometimes  // visit the location header directly  cy.visit(loc)})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "JavaScript Redirects"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "When we say JavaScript Redirects we are talking about any kind of code that does something like this:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "index.html"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "<html>  <button id=\"nav\">Navigate to Cypress example</button>  <script>    document.querySelector('#nav').addEventListener('click', () => {      window.location.href = 'https://example.cypress.io'    })  </script></html>"
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "You can test this with `cy.origin`, which may look like the following test case:"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "test.cy.js"
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "cy.visit('http://localhost:8080')cy.get('#nav').submit() // trigger a javascript redirect!cy.origin('https://example.cypress.io', () => {  cy.url().should('contain', 'cypress.io')})"
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Cross-Origin Errors with `cy.origin`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Sometimes, when using `cy.origin` and especially with websites that are not under your immediate test control, cross-origin errors may still tend to creep up. We don't recommend visiting or interacting with sites you "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/core-concepts/best-practices.md#Visiting-External-Sites",
            "children": [
              {
                "type": "text",
                "value": "do not control"
              }
            ]
          },
          {
            "type": "text",
            "value": ". However, if this is necessary, most of these issues can usually be remedied by applying` the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/experiments.md#Configuration",
            "children": [
              {
                "type": "text",
                "value": "modify obstructive third-party code"
              }
            ]
          },
          {
            "type": "text",
            "value": " experimental flag or by "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cross-origin-testing.md#Disabling-Web-Security",
            "children": [
              {
                "type": "text",
                "value": "disabling web security"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Disabling Web Security"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "So if you cannot work around any of the issues using the suggested workarounds above, including "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/guides/cross-origin-testing.md#Modifying-Obstructive-Third-Party-Code",
            "children": [
              {
                "type": "text",
                "value": "modifying obstructive third-party code"
              }
            ]
          },
          {
            "type": "text",
            "value": " with `cy.origin`, you may want to disable web security."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "One last thing to consider here is that every once in a while we discover bugs in Cypress that lead to cross-origin errors that can otherwise be fixed. If you think you're experiencing a bug, "
          },
          {
            "type": "link",
            "title": null,
            "url": "https://github.com/cypress-io/cypress/issues/new/choose",
            "children": [
              {
                "type": "text",
                "value": "open an issue"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Chrome only"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Disabling web security is only supported in Chrome-based browsers. Settings in `chromeWebSecurity` will have no effect in other browsers. We will log a warning in this case."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If you rely on disabling web security, you will not be able to run tests on browsers that do not support this feature."
          }
        ]
      },
      {
        "type": "heading",
        "depth": 3,
        "children": [
          {
            "type": "text",
            "value": "Set `chromeWebSecurity` to `false`"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Setting `chromeWebSecurity` to `false` in Chrome-based browsers allows you to do the following:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Display insecure content"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Navigate to any origin without cross-origin errors with or without `cy.origin`"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Access cross-origin iframes that are embedded in your application"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Still here? That's cool, let's disable web security!"
          }
        ]
      },
      {
        "type": "heading",
        "depth": 4,
        "children": [
          {
            "type": "text",
            "value": "Set `chromeWebSecurity` to `false` in the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md",
            "children": [
              {
                "type": "text",
                "value": "Cypress configuration"
              }
            ]
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')module.exports = defineConfig({  chromeWebSecurity: false,})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default defineConfig({  chromeWebSecurity: false,})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Modifying Obstructive Third Party Code"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Cypress today has the concept of "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#modifyObstructiveCode",
            "children": [
              {
                "type": "text",
                "value": "modifying obstructive code"
              }
            ]
          },
          {
            "type": "text",
            "value": ", which is code that may interfere with Cypress being able to run your web application. The `experimentalModifyObstructiveThirdPartyCode` flag provides the same benefits of the "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/app/references/configuration.md#modifyObstructiveCode",
            "children": [
              {
                "type": "text",
                "value": "modifyObstructiveCode"
              }
            ]
          },
          {
            "type": "text",
            "value": " flag, but additionally applies it to third-party `.js` and `.html` that is being either loaded or navigated to inside your application. In addition to this, this flag also does the following:"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Adjusts the User Agent in Electron to appear more chrome-like. This option can be overridden with the "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/configuration.md#Browser",
                    "children": [
                      {
                        "type": "text",
                        "value": "userAgent"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " config option."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Removes "
                  },
                  {
                    "type": "link",
                    "title": null,
                    "url": "https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity",
                    "children": [
                      {
                        "type": "text",
                        "value": "Subresource Integrity (SRI)"
                      }
                    ]
                  },
                  {
                    "type": "text",
                    "value": " from modified scripts as they will not execute otherwise."
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "Updates the `Sec-Fetch-Dest` Metadata header from `iframe` to `document` in cases where requests come from the application under test."
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "Want to enable `experimentalModifyObstructiveThirdPartyCode`? Let's do it!"
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.js"
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "text",
                    "value": "cypress.config.ts"
                  }
                ]
              }
            ]
          }
        ]
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "const { defineConfig } = require('cypress')module.exports = defineConfig({  experimentalModifyObstructiveThirdPartyCode: true,})"
      },
      {
        "type": "code",
        "lang": null,
        "meta": null,
        "value": "import { defineConfig } from 'cypress'export default defineConfig({  experimentalModifyObstructiveThirdPartyCode: true,})"
      },
      {
        "type": "heading",
        "depth": 2,
        "children": [
          {
            "type": "text",
            "value": "Other workarounds"
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "There are other ways of testing the interaction between two origins. The browser has a natural security barrier called `origin policy` this means that state like `localStorage`, `cookies`, `service workers` and many other APIs are not shared between them anyways. Cypress does offer APIs around `localStorage`, `sessionStorage`, and `cookies` that are not limited to this restriction."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "As a best practice, you should not visit or interact with any website not under your control."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "If your organization uses Single Sign On (SSO) or OAuth then you might choose to test a 3rd party service other than your origin, which can be tested with "
          },
          {
            "type": "link",
            "title": null,
            "url": "/llm/markdown/api/commands/origin.md",
            "children": [
              {
                "type": "text",
                "value": "`cy.origin()`"
              }
            ]
          },
          {
            "type": "text",
            "value": "."
          }
        ]
      },
      {
        "type": "paragraph",
        "children": [
          {
            "type": "text",
            "value": "We've written several other guides specifically about handling this situation."
          }
        ]
      },
      {
        "type": "list",
        "ordered": false,
        "start": null,
        "spread": false,
        "children": [
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/core-concepts/best-practices.md#Visiting-External-Sites",
                    "children": [
                      {
                        "type": "text",
                        "value": "Best Practices: Visiting external sites"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/references/recipes.md#Logging-In",
                    "children": [
                      {
                        "type": "text",
                        "value": "Recipes: Logging In - Single Sign On"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/guides/authentication-testing/amazon-cognito-authentication.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Guides: Amazon Cognito Authentication"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/guides/authentication-testing/auth0-authentication.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Guides: Auth0 Authentication"
                      }
                    ]
                  }
                ]
              }
            ]
          },
          {
            "type": "listItem",
            "spread": false,
            "checked": null,
            "children": [
              {
                "type": "paragraph",
                "children": [
                  {
                    "type": "link",
                    "title": null,
                    "url": "/llm/markdown/app/guides/authentication-testing/okta-authentication.md",
                    "children": [
                      {
                        "type": "text",
                        "value": "Guides: Okta Authentication"
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "token_estimate": 3625
}