## TL;DR

Cypress blocks cross-origin navigation unless you wrap the foreign-origin steps in `cy.origin()`. Put every command that runs on the other origin inside the callback, pass needed values via `args`, and keep assertions on each origin separate.

## Error

```text
CypressError: `cy.visit()` failed because you are attempting to visit a URL that is of a different origin.
You may only `cy.visit()` same-origin URLs, or use `cy.origin()` for cross-origin flows.
```

## Steps

1. Confirm the two URLs really are different origins (scheme, host, or port differs). Expected: you identify the exact origin boundary.
2. Wrap the foreign-origin steps: `cy.origin('https://auth.example.com', { args: { user } }, ({ user }) => { cy.get('#email').type(user.email); ... })`. Expected: commands inside run against the foreign origin.
3. Pass data via `args`; variables from the outer scope are not visible inside `cy.origin()`. Expected: no undefined variables inside the callback.
4. Keep the flow linear: visit app, `cy.origin()` for the provider, then continue on the app origin. Expected: each origin's steps are grouped, not interleaved.
5. Enable `experimentalModifyObstructiveThirdPartyCode` only if the provider's anti-automation scripts break the flow. Expected: last resort, documented in the test.

## When to use

- Login via Auth0, Okta, Google, or any external identity provider.
- Payment flows that redirect to Stripe, PayPal, or similar.

## When not to use

- Same-origin navigation (plain `cy.visit()` is fine).
- You control both apps and can use a test bypass for auth instead.

## Tool compatibility

- Cypress 12+ for stable `cy.origin()`; older versions need the experimental flag.

## Variant phrasings

### Cypress detected a cross origin error happened

The generic form; the fix is `cy.origin()` around the foreign steps.

### cy.origin is not a function

Cypress version too old; upgrade to 12+.

## Why it happens

Browsers enforce the same-origin policy and Cypress mirrors it. Without `cy.origin()`, Cypress cannot inject its automation hooks into the foreign page.

## Edge cases

- `cy.origin()` callbacks cannot use aliases defined outside; re-create what you need inside.
- Some providers detect automation and block it; a test auth bypass is more reliable than driving the real provider.
- Cookies set inside `cy.origin()` are visible afterward, but localStorage is per-origin.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_rIcAfRCI4yOs-9Vg3TTuzQ
