You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Status: Proposed Author: Lucas da Cunha Rodrigues Date: 03/09/2025 Type: Feature Request
Summary
This RFC proposes adding native support for multiple tabs and windows in Cypress, addressing one of the primary limitations compared to Playwright. The proposal includes a comprehensive architectural analysis, API design, and implementation roadmap.
Motivation
Current Limitations
Cypress operates in a single page context, unable to interact with popups, new tabs, or multiple windows
Users must resort to workarounds like cy.window() or external libraries, which are fragile and limited
This creates a significant competitive disadvantage against Playwright, which has native multi-context support
Use Cases
OAuth Flows: Testing login with external providers that open popups
Payment Processing: Testing payment flows that redirect to external services
File Downloads: Testing download functionality that opens new tabs
Multi-step Workflows: Testing complex user journeys spanning multiple windows
Third-party Integrations: Testing integrations that require popup-based authentication
Historical Context
Important Note: This RFC addresses a different problem than what was solved by cy.origin().
These are related but technically distinct challenges:
cy.origin(): Cross-domain communication within the same tab
This RFC: Multiple tabs/windows management (regardless of domain)
The Cypress team has not yet addressed the multiple tabs/windows use case, making this a legitimate new feature request.
Technical Analysis
Current Architecture Gap
The core issue is Cypress's injection architecture. The Driver is injected into a single page context and lacks inherent visibility or control over other document contexts (tabs, iframes, windows).
Key Gaps:
Context Isolation: Each tab/window is an isolated JavaScript environment
Communication & Synchronization: No mechanism for commands in one tab to wait for or react to events in another tab
Lifecycle Control: Cypress manages the lifecycle of a single page only
API Integration: The synchronous, chainable API (cy.get(...).click(...).should(...)) needs to be preserved
Existing Infrastructure Analysis
80% of the required infrastructure already exists in the Cypress codebase:
// Already implemented: List all browser targetsconst{targetInfos: targets}=awaitthis.browserClient.send('Target.getTargets')consttarget=targets.find((target)=>target.url===url)// Already implemented: Create new tabstarget=awaitthis.browserClient.send('Target.createTarget',{url: 'about:blank'})// Already implemented: Close specific tabsawaitthis.browserClient.send('Target.closeTarget',{targetId: this.currentlyAttachedTarget.targetId})
// Already implemented: Create CDP connection with specific targetthis.currentlyAttachedTarget=awaitCriClient.create({target: target.targetId,// Can be ANY targetId// ... other parameters})// Already implemented: Clone connections for separate protocolsthis.currentlyAttachedProtocolTarget=awaitthis.currentlyAttachedTarget.clone()
Context State Management (packages/driver/src/cypress/state.ts:27)
// Already implemented: Active context tracking(k: 'currentActiveOrigin',v?: string): string
cy.openNewTab()// Triggers action that opens popup/new tab.then((newPage)=>{cy.wrap(newPage).find('#elementInNewTab').should('be.visible');newPage.close();// Explicitly close the tab});
Option 2: Context Switching (Cypress-native)
cy.origin('https://another-tab.com',()=>{// This callback executes in the NEW TAB contextcy.get('button').click();// Searches for button in new tab});// Context automatically returns to original tab after callback
Option 3: Imperative Switch Command
cy.switchToTab({url: 'https://another-tab.com'});// Switch to tab with this URLcy.get('body').should('contain','Welcome');// Now searches in new tabcy.switchToTab({index: 0});// Return to first tab
Recommended Approach: Option 2 (cy.origin for tabs) aligns best with Cypress's philosophy and existing API.
Design Patterns
Facade: Simple API (cy.origin) hiding CDP management, events, and context stacking complexity
Proxy: The newPage object or internal context within cy.origin acts as a proxy, translating cy commands to target tab via CDP
Follow established patterns: Use cy.origin() context switching pattern for API consistency
Leverage proven architecture: Multiple CDP connections and state management already functional
This roadmap represents a 9-12 month investment of specialized development effort, but with significantly lower risk due to existing infrastructure. The return would be monumental: eliminating Cypress's primary competitive weakness against Playwright and empowering thousands of developers and companies with applications following this pattern.
Next Steps
Community Discussion: Open new GitHub discussion (not reusing closed issues) to gather feedback and use cases
Maintainer Engagement: Present proposal to Cypress maintainers for initial feedback
Proof of Concept: If approved, begin Phase 1 with minimal CDP Manager prototype
Iterative Development: Follow phased approach with continuous community feedback
Questions for Discussion:
Which API approach (Options 1, 2, or 3) resonates most with the community?
Are there additional use cases not covered in this proposal?
How can this feature build upon the existing cy.origin() architecture?
What concerns do maintainers have about the proposed architecture?
Would experimental release under feature flag be acceptable for initial testing?
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
RFC: Support for Multiple Tabs/Windows in Cypress
Status
Status: Proposed
Author: Lucas da Cunha Rodrigues
Date: 03/09/2025
Type: Feature Request
Summary
This RFC proposes adding native support for multiple tabs and windows in Cypress, addressing one of the primary limitations compared to Playwright. The proposal includes a comprehensive architectural analysis, API design, and implementation roadmap.
Motivation
Current Limitations
cy.window()
or external libraries, which are fragile and limitedUse Cases
Historical Context
Important Note: This RFC addresses a different problem than what was solved by
cy.origin()
.cy.origin()
was released as the official solution for "supporting multiple superdomains in a test"cy.origin()
solves cross-domain testing, it does not solve the multiple tabs/windows problemcy.origin()
: Cross-domain communication within the same tabThe Cypress team has not yet addressed the multiple tabs/windows use case, making this a legitimate new feature request.
Technical Analysis
Current Architecture Gap
The core issue is Cypress's injection architecture. The Driver is injected into a single page context and lacks inherent visibility or control over other document contexts (tabs, iframes, windows).
Key Gaps:
Existing Infrastructure Analysis
80% of the required infrastructure already exists in the Cypress codebase:
Target Management (packages/server/lib/browsers/browser-cri-client.ts:545-551)
Multiple CDP Connections (packages/server/lib/browsers/browser-cri-client.ts:553-570)
Context State Management (packages/driver/src/cypress/state.ts:27)
Context Switching Pattern (packages/driver/src/cy/commands/origin/index.ts:94-98)
Component Viability Assessment
Target.getTargets
,Target.createTarget
,Target.closeTarget
(browser-cri-client.ts:545-551)currentActiveOrigin
,cy.state()
(state.ts:27, origin/index.ts:94)currentlyAttachedTarget
,currentlyAttachedProtocolTarget
(browser-cri-client.ts:189-190)cy.origin()
as proof of concept (origin/index.ts:94-98)clone()
,close()
, cleanup patterns (browser-cri-client.ts:567-570)Key Insight: This is not an architectural rewrite but an intelligent extension of mature, proven systems.
Detailed Design
Proposed Architecture
Core Components
CDP Manager
Context Stack
Cross-Context Event Bridge
API Design
Option 1: Explicit Page Management (Playwright-style)
Option 2: Context Switching (Cypress-native)
Option 3: Imperative Switch Command
Recommended Approach: Option 2 (cy.origin for tabs) aligns best with Cypress's philosophy and existing API.
Design Patterns
Implementation Roadmap
Phase 0: Research and Advocacy (1-2 months) ⭐ CURRENT PHASE
Phase 1: CDP Manager Prototype (2-3 months) ✅ HIGHLY VIABLE
Target.getTargets
,CriClient.create
, and connection managementPhase 2: Core Context Integration (3-4 months) ✅ VIABLE
cypress/state.ts
followingcurrentActiveOrigin
patternPhase 3: High-Level API Implementation (2-3 months)
Phase 4: Lifecycle Management and Robustness (2 months)
Phase 5: Polish and Release (1-2 months)
Risk Analysis and Mitigations
Definition of Done
Functional Requirements
Non-Functional Requirements
Release Strategy
Experimental Release
experimentalMultiTabSupport: true
in cypress.config.jsStabilization Period
Alternatives Considered
Conclusion
Implementing native multiple tab support is highly viable because it builds upon existing, proven infrastructure:
This roadmap represents a 9-12 month investment of specialized development effort, but with significantly lower risk due to existing infrastructure. The return would be monumental: eliminating Cypress's primary competitive weakness against Playwright and empowering thousands of developers and companies with applications following this pattern.
Next Steps
Questions for Discussion:
cy.origin()
architecture?cy.origin()
, how should we position this as a distinct but complementary feature?Beta Was this translation helpful? Give feedback.
All reactions