The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Multiple cy.origin() calls are supported in one Cypress test when they are successive, top-level commands. The usual error comes from nesting one cy.origin() inside another, using a callback for the wrong origin, or relying on variables that were not passed through args. Cypress v14 also requires explicit origin handling in cases that older versions often covered through document.domain.
The working pattern: one top-level block per origin
Keep the test flow in the primary command chain and add one top-level cy.origin() for each external origin. A callback may contain commands that operate on its declared origin, but it may not contain another cy.origin().
it('works across several origins', () => {
const email = '[email protected]'
cy.visit('https://app.example.test')
cy.origin('https://login.example.test', { args: { email } }, ({ email }) => {
cy.get('[name=email]').type(email)
cy.get('button[type=submit]').click()
})
cy.origin('https://billing.example.test', () => {
cy.get('[data-cy=invoice]').should('be.visible')
})
})
The first block runs in the login origin, then Cypress returns to the test flow before entering the billing origin. Each URL must be treated as an origin made of its scheme, hostname, subdomain and port. Query strings and paths are not part of the origin string.
Why Cypress reports errors with multiple calls
Nested calls are prohibited
This structure is invalid:
cy.origin('https://login.example.test', () => {
cy.origin('https://billing.example.test', () => {
cy.get('[data-cy=invoice]')
})
})
Cypress documentation states that callbacks may not themselves contain cy.origin() calls. Move the second block beside the first, at the test’s top level.
#1 Best Overall
Commands are running under the wrong origin
After navigation, commands that target the new page must be inside the matching callback. Leaving a cy.get(), assertion, or click outside the block can cause a timeout because Cypress is still enforcing the active-origin boundary.
The origin string does not match exactly
These are different origins:
http://login.example.testandhttps://login.example.testhttps://login.example.testandhttps://www.example.testhttps://example.test:443andhttps://example.test:8443
Read the browser’s actual address at the first failing command. Match scheme, hostname, subdomain and port exactly. Do not append a path or query parameter.
Outer variables do not cross automatically
The callback executes in a separate Cypress-controlled context. Lexical variables, aliases and complex objects from the outer test are not automatically available. Pass small, serializable values through args and destructure them in the callback.
const credentials = {
email: '[email protected]',
password: 'not-a-real-password'
}
cy.origin('https://login.example.test', { args: credentials }, ({ email, password }) => {
cy.get('[name=email]').type(email)
cy.get('[name=password]').type(password)
})
Strings, numbers, booleans, arrays and plain JSON objects are appropriate. Recreate selectors, helper functions and page-specific setup inside the callback instead of trying to transfer functions, DOM nodes or Cypress chainables.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
How to test several domains in one test
- Start on the first page. Use
cy.visit()for the application entry point. - Identify every destination origin. Record the complete scheme, hostname, subdomain and port for login, payments, billing or other services.
- Add a top-level block for each destination. Put every interaction with that page inside its corresponding callback.
- Transfer only required data. Supply serializable values with
args; do not reference outer aliases or objects inside the callback. - Keep blocks sequential. Cypress queues commands, so place the second block after the first block’s commands in the test body.
For a flow that returns to the original application, continue with ordinary commands after the final origin block, provided the browser is back on an origin that Cypress permits for that test.
What changed in Cypress 14
Cypress no longer injects document.domain by default in Cypress v14. Tests that previously moved between subdomains under one superdomain may therefore fail after an upgrade even though the application flow has not changed.
For example, a test moving from https://app.example.test to https://login.example.test should use an explicit cy.origin('https://login.example.test', ...) block. Do not rely on the old same-superdomain behavior. Review every navigation in a test upgraded to v14 and add blocks for each different origin.
Free tools Windows power users keep installed
One-click scans. No signup required.
Diagnostic sequence for the first failure
- Read the first failing command, not the last error message. Identify the page that was active when the command timed out or Cypress reported a cross-origin problem.
- Compare the address bar with the block. Check protocol, complete hostname, subdomain and port character by character.
- Move page interactions inward. Any command that queries or clicks the destination page belongs inside its matching callback.
- Inspect callback contents. Remove nested
cy.origin(),cy.intercept()andcy.session()calls from the callback when the error points to unsupported command placement. - Audit data crossing. Replace outer-scope references with
args; recreate aliases and helper calls in the callback. - Check the Cypress version. If the failure began after v14, look specifically for navigation between different origins that previously depended on
document.domain. - Confirm the browser context. An origin block does not make cross-origin iframes, second tabs or second windows automatable through the same mechanism.
Common errors and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| “Callbacks may not themselves contain cy.origin() calls” | A block is nested inside another block. | Close the first callback and place the next cy.origin() at test level. |
| Command times out after redirect | The command is outside the block for the page now displayed, or the origin string is wrong. | Match the exact origin and move the command into that callback. |
| Second unique-domain or different-origin error | The test crossed an origin without an explicit block. | Add a top-level block for the newly visited origin; this is especially important after Cypress v14. |
| Variable is undefined inside callback | Outer lexical scope is unavailable in the callback. | Pass a serializable value through args and destructure it. |
| Alias or helper cannot be used inside callback | Cypress aliases, functions and chainables are not transferable callback data. | Recreate the alias or helper logic inside the callback and pass only plain data. |
| Cross-origin iframe cannot be controlled | The target is an iframe rather than the top-level page origin. | Redesign the test around a supported top-level flow; cy.origin() does not cover cross-origin iframes. |
| Second tab or window is not available | The flow depends on a separate browser context. | Test the destination in the same tab where possible, or use an application-level test strategy instead. |
Commands that need special care
Keep origin-specific network stubbing and session setup out of callbacks when Cypress reports them as unsupported in that context. In particular, the diagnostic guidance for this failure pattern is to confirm that callbacks contain no cy.intercept() or cy.session(). Define supported setup at the appropriate test level, then enter the origin block only for page interactions.
Rank #3
Selectors should also be declared or reconstructed inside the callback. A selector string can be passed as data, but a previously captured element, alias or chainable cannot be reused across origins.
Designing reliable multi-origin tests
Prefer one business flow per test
A single test can legitimately cover sign-in, billing and return-to-app behavior, but keep the number of origin transitions limited to the business outcome being verified. Smaller tests make the first failing origin easier to identify.
Use stable readiness checks
After entering an origin, wait for a meaningful element belonging to that page rather than adding arbitrary delays. Assertions such as should('be.visible') document what “ready” means and produce a more useful failure location.
Keep credentials and configuration explicit
Pass only the values needed by a callback. Avoid transferring secrets or large configuration objects unnecessarily, and use Cypress’s normal environment and secret-management practices for sensitive data.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Expect redirects to change the origin
Authentication providers often redirect through several hostnames. List each actual destination observed in the browser and add a separate top-level block where the test interacts with it. A redirect that changes only the path stays within the same origin; a scheme, hostname or port change does not.
Unsupported browser contexts
cy.origin() is for top-level page navigation between origins in the same Cypress-controlled browser flow. It does not solve every cross-domain problem:
- Cross-origin iframes remain outside its coverage.
- Separate tabs and second windows require a different design.
- An origin block cannot make commands from one page valid on another page.
When one of these contexts is fundamental to the feature, test the service boundary separately or redesign the application flow so the browser remains in a supported context.
Or skip the browser setup
If your goal is to capture the resulting pages rather than interactively test them, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in headers.
One request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for all options, including full-page and element capture, device and viewport settings, PDF output, custom JavaScript, waits, request blocking, cookies, headers, geolocation, caching, signed links, asynchronous jobs and bulk capture.
Best Value
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also includes MCP tools named take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Can I call cy.origin() twice in one test?
Yes. Multiple successive, top-level calls are valid when each callback targets its own exact origin.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Should the origin string include a path?
No. Supply only scheme, hostname, subdomain and port. Paths and query parameters belong in navigation commands inside the callback.
Why did a test pass before upgrading to Cypress 14?
The test may have depended on Cypress’s former default document.domain behavior. Add explicit origin blocks for each different origin and review redirects.
Can I use cy.origin() for a payment iframe?
No. Cross-origin iframes are not covered by cy.origin(); the test needs a different strategy.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

