diff --git a/assets/img/guides/references/cy-visit-subsequent-commands-timed-out.png b/assets/img/guides/references/cy-visit-subsequent-commands-timed-out.png
new file mode 100644
index 0000000000..122f4c496f
Binary files /dev/null and b/assets/img/guides/references/cy-visit-subsequent-commands-timed-out.png differ
diff --git a/content/_data/sidebar.json b/content/_data/sidebar.json
index a42e602aaa..5972cb3d09 100644
--- a/content/_data/sidebar.json
+++ b/content/_data/sidebar.json
@@ -320,6 +320,14 @@
{
"title": "Cross Browser Testing",
"slug": "cross-browser-testing"
+ },
+ {
+ "title": "Cross Origin Testing",
+ "slug": "cross-origin-testing"
+ },
+ {
+ "title": "Web Security",
+ "slug": "web-security"
}
]
},
diff --git a/content/api/commands/origin.md b/content/api/commands/origin.md
index 9265053963..741723c151 100644
--- a/content/api/commands/origin.md
+++ b/content/api/commands/origin.md
@@ -22,7 +22,10 @@ patterns commonly found in framebusting. When using the `cy.origin()` command,
the third party code may also need to be modified for framebusting techniques.
This can be enabled by setting the
[`experimentalModifyObstructiveThirdPartyCode`](/guides/references/experiments)
-flag to `true` in the Cypress configuration.
+flag to `true` in the Cypress configuration. More information about this
+experimental flag can be found on our
+[Web Security](/guides/guides/web-security#Modifying-Obstructive-Third-Party-Code)
+page.
diff --git a/content/faq/questions/using-cypress-faq.md b/content/faq/questions/using-cypress-faq.md
index d08b9db4eb..bc3126ade5 100644
--- a/content/faq/questions/using-cypress-faq.md
+++ b/content/faq/questions/using-cypress-faq.md
@@ -919,6 +919,8 @@ application under test runs in any way, so you can safely ignore this warning.
The network traffic between Cypress and the backend server still happens via
HTTPS.
+See also the [Web Security](/guides/guides/web-security) guide.
+
## Is there an option to run Cypress in CI with Developer Tools open? We want to track network and console issues.
No. There is not currently a way to run Cypress in `cypress run` with Developer
diff --git a/content/guides/end-to-end-testing/okta-authentication.md b/content/guides/end-to-end-testing/okta-authentication.md
index 006a71323d..f3d7f679d1 100644
--- a/content/guides/end-to-end-testing/okta-authentication.md
+++ b/content/guides/end-to-end-testing/okta-authentication.md
@@ -12,7 +12,9 @@ e2eSpecific: true
- Programmatically authenticate with [Okta](https://okta.com) via a custom
Cypress command
- Adapting your [Okta](https://okta.com) application for programmatic
- authentication during testing
+ authentication during testing
+
+
diff --git a/content/guides/guides/cross-browser-testing.md b/content/guides/guides/cross-browser-testing.md
index f25a0398cc..b0f946b5a1 100644
--- a/content/guides/guides/cross-browser-testing.md
+++ b/content/guides/guides/cross-browser-testing.md
@@ -14,7 +14,7 @@ browser engine), and Firefox.
Tests that require the
-[`chromeWebSecurity` configuration option to be disabled](/guides/references/configuration#Browser)
+[`chromeWebSecurity` configuration option to be disabled](/guides/guides/web-security#Disabling-Web-Security)
may experience issues in non-Chromium based browsers.
diff --git a/content/guides/guides/cross-origin-testing.md b/content/guides/guides/cross-origin-testing.md
new file mode 100644
index 0000000000..40bc5f4bc0
--- /dev/null
+++ b/content/guides/guides/cross-origin-testing.md
@@ -0,0 +1,152 @@
+---
+title: Cross Origin Testing
+---
+
+
+
+
+
+As of Cypress [v12.0.0](https://on.cypress.io/changelog#12-0-0), Cypress has the
+capability to visit multiple origins in a single test via the
+[cy.origin()](https://on.cypress.io/origin) command!
+
+
+
+Cypress limits each test to visiting domains that share the same superdomain. If
+a navigation occurs that does not meet the same superdomain rule, the
+[`cy.origin()`](/api/commands/origin) command must be used to execute Cypress
+commands inside the newly navigated origin.
+
+But what is same superdomain? It is actually very similar to that of same
+origin! Two URLs have the same origin if the protocol, port (if specified), and
+host match. Cypress automatically handles hosts of the same superdomain by
+injecting the
+[`document.domain`](https://developer.mozilla.org/en-US/docs/Web/API/Document/domain)
+property into the visited `text/html` pages. This is why navigations without the
+use of the [`cy.origin()`](/api/commands/origin) command are solely scope to the
+same superdomain.
+
+We understand this is a bit complicated to understand, so we have built a nifty
+chart to help clarify the differences!
+
+### Parts of a URL
+
+```
+┌───────────────────────────────────────────────────────────────────────────────────────┐
+│ href │
+├──────────┬──┬─────────────────────────────────────┬───────────────────────────┬───────┤
+│ protocol │ │ host │ path │ hash │
+│ │ ├──────────────────────────────┬──────┼──────────┬────────────────┤ │
+│ │ │ hostname │ port │ pathname │ search │ │
+| | ├───────────┬──────────────────┤ │ │ │ │
+│ │ │ subdomain │ superdomain (sd) │ │ │ │ │
+| | ├───────────┼─────────┬────────┤ │ ├─┬──────────────┤ │
+│ │ │ │ domain │ TLD │ │ │ │ query │ │
+│ │ │ │ │ │ │ │ │ │ │
+" https: // sub . example . com : 8080 /p/a/t/h ? query=string #hash "
+│ │ │ │ │
+│ origin │ | │ │
+├─────────────┬───────────┬─────────────────────────┤ │ │ │
+│ (sd) origin │ │ (sd) origin │ │ │ │
+└─────────────┴───────────┴─────────────────────────┴──────────┴────────────────┴───────┘
+```
+
+Given the URLs below, all have the same superdomain compared to
+`https://www.cypress.io`.
+
+- `https://cypress.io`
+- `https://docs.cypress.io`
+- `https://example.cypress.io/commands/querying`
+
+The URLs below, however, will have different superdomains/origins compared to
+`https://www.cypress.io`.
+
+- `http://www.cypress.io` (Different protocol)
+- `https://docs.cypress.io:81` (Different port)
+- `https://www.auth0.com/` (Different host of different superdomain)
+
+The `http://localhost` URLs differ if their ports are different. For example,
+the `http://localhost:3000` URL is considered to be a different origin from the
+`http://localhost:8080` URL.
+
+The rules are:
+
+- You **cannot**
+ [visit](/api/commands/visit) two domains of different superdomains in the same
+ test and continue to interact with the page without the use of the
+ [`cy.origin()`](/api/commands/origin) command.
+- You **can**
+ [visit](/api/commands/visit) two or more domains of different origin in
+ **different** tests without needing [`cy.origin()`](/api/commands/origin).
+
+For practical purposes, this means the following:
+
+```javascript
+// This test will run without error
+it('navigates', () => {
+ cy.visit('https://www.cypress.io')
+ cy.visit('https://docs.cypress.io')
+ cy.get('selector') // yup all good
+})
+```
+
+```javascript
+// this will error because stackoverflow.com doesn't match the cypress.io superdomain
+it('navigates', () => {
+ cy.visit('https://www.cypress.io')
+ cy.visit('https://stackoverflow.com')
+ cy.get('selector')
+})
+```
+
+To fix the above cross-origin error, use `cy.origin()` to indicate which origin
+the sequential command should run against:
+
+```javascript
+it('navigates', () => {
+ cy.visit('https://www.cypress.io')
+ cy.visit('https://stackoverflow.com')
+ cy.origin('https://stackoverflow.com', () => {
+ cy.get('selector') // yup all good
+ })
+})
+```
+
+```javascript
+it('navigates', () => {
+ cy.visit('https://www.cypress.io')
+})
+
+// split visiting different origin in another test
+it('navigates to new origin', () => {
+ cy.visit('https://stackoverflow.com')
+ cy.get('selector') // yup all good
+})
+```
+
+This limitation exists because Cypress switches to the domain under each
+specific test when it runs. For more information on this, please see our Web
+Security page regarding
+[Different superdomain per test requires cy.origin command](/guides/guides/web-security#Different-superdomain-per-test-requires-cy-origin-command).
+
+#### Other workarounds
+
+There are other ways of testing the interaction between two superdomains. 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.
+
+As a best practice, you should not visit or interact with a 3rd party service
+not under your control. However, there are exceptions! If your organization uses
+Single Sign On (SSO) or OAuth then you might involve a 3rd party service other
+than your superdomain, which can be safely tested with
+[`cy.origin()`](/api/commands/origin).
+
+We've written several other guides specifically about handling this situation.
+
+- [Best Practices: Visiting external sites](/guides/references/best-practices#Visiting-external-sites)
+- [Web Security: Common Workarounds](/guides/guides/web-security#Common-Workarounds)
+- [Recipes: Logging In - Single Sign On](/examples/examples/recipes#Logging-In)
+- [Guides: Amazon Cognito Authentication](/guides/end-to-end-testing/amazon-cognito-authentication)
+- [Guides: Okta Authentication](/guides/end-to-end-testing/okta-authentication)
diff --git a/content/guides/guides/web-security.md b/content/guides/guides/web-security.md
new file mode 100644
index 0000000000..1e5a203ec1
--- /dev/null
+++ b/content/guides/guides/web-security.md
@@ -0,0 +1,485 @@
+---
+title: Web Security
+e2eSpecific: true
+---
+
+Browsers adhere to a strict
+[same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy).
+This means that browsers restrict access between `` when their origin
+policies do not match.
+
+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.
+
+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 is 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.
+
+#### Examples of what Cypress does under the hood:
+
+- Injects
+ [`document.domain`](https://developer.mozilla.org/en-US/docs/Web/API/Document/domain)
+ into `text/html` pages.
+- Proxies all HTTP / HTTPS traffic.
+- Changes the hosted URL to match that of the application under test.
+- Uses the browser's internal APIs for network level traffic.
+
+When Cypress first loads, the internal Cypress web application is hosted on a
+random port: something like `http://localhost:65874/__/`.
+
+After the first [`cy.visit()`](/api/commands/visit) 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.
+
+
+
+
+
+Cypress does some pretty interesting things under the hood to make testing HTTPS
+sites work. Cypress enables you to control and stub at the network level.
+Therefore, 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 normal and correct. 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 superdomain currently
+under test, and bypass other traffic. That's why if you open a tab in Cypress to
+another host, the certificates match as expected.
+
+Note, that Cypress allows you to optionally specify CA / client certificate
+information for use with HTTPS sites. See
+[Configuring client certificates](/guides/references/client-certificates). If
+the remote server requests a client certificate for a configured URL, Cypress
+will supply it.
+
+
+
+## Limitations
+
+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.
+
+### Different superdomain per test requires `cy.origin` command
+
+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 superdomain for the entirety of a single test.
+
+If you attempt to visit two different superdomains, 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.
+
+Without `cy.origin`, you can visit different superdomains in _different_ tests,
+but not in the _same_ test. Please read our
+[Cross Origin Testing Guide](/guides/guides/cross-origin-testing) for more
+information.
+
+Although Cypress tries to enforce this limitation, it is possible for your
+application to bypass Cypress's ability to detect this.
+
+#### Examples of test cases that will error without the use of `cy.origin`
+
+1. [`.click()`](/api/commands/click) an `` with an `href` to a different
+ superdomain with subsequent Cypress commands being run.
+2. [`.submit()`](/api/commands/submit) a `