You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cypress重定向测试问题:外部跳转后空白页解决方案咨询

Fixing Cypress Blank Page After External Redirect & Completing the Login Flow

Hey there, let's tackle this common Cypress issue head-on. The blank page happens because of Cypress' default same-origin policy restrictions—once you jump to an external domain, Cypress loses control of the browser context, leaving you stuck with a blank screen. Let's break down solutions based on whether you have control over the external login site or not.

If You Control the External Login Site (e.g., Internal SSO)

Option 1: Skip the UI Login (Fastest & Most Reliable)

Instead of going through the external site's login UI, directly call the login API to grab auth credentials, then inject them into your original site's browser context. This avoids cross-domain headaches entirely.

Here's a code example:

// In your test file
beforeEach(() => {
  // Send a POST request to the external login API
  cy.request({
    method: 'POST',
    url: 'https://your-external-login-site.com/api/login',
    body: {
      username: Cypress.env('TEST_USER'), // Store these in cypress.env.json
      password: Cypress.env('TEST_PASS')
    }
  }).then(response => {
    // Set the auth cookie/token on your original site's domain
    cy.setCookie('auth_session', response.body.session_token, {
      domain: 'your-original-site.com'
    });
  });

  // Directly navigate to the connections page—you're already authenticated!
  cy.visit('/connections');
});

it('verifies connections are visible', () => {
  cy.get('[data-testid="connections-container"]').should('be.visible');
});

Pro tip: Storing credentials in cypress.env.json keeps them out of your codebase—just add the file to .gitignore.

Option 2: Enable Cypress' Cross-Domain Support

Cypress has an experimental (but stable in v12+) feature to handle cross-origin navigation. Enable it in your config, then use cy.origin() to interact with the external site.

First, update cypress.config.js:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  e2e: {
    experimentalSessionAndOrigin: true, // Enable cross-origin support
    // Your other config options...
  }
});

Then write the test to handle the full flow:

it('navigates to external login, authenticates, and returns to connections', () => {
  cy.visit('/');
  
  // Click the redirect button to the external login site
  cy.get('[data-testid="external-login-btn"]').click();

  // Use cy.origin() to target the external domain
  cy.origin('https://your-external-login-site.com', () => {
    cy.get('#username-input').type(Cypress.env('TEST_USER'));
    cy.get('#password-input').type(Cypress.env('TEST_PASS'));
    cy.get('#submit-login').click();
  });

  // After redirecting back, verify the connections page loads
  cy.url().should('include', '/connections');
  cy.get('[data-testid="connections-list"]').should('have.length.greaterThan', 0);
});

If You Don't Control the External Login Site (e.g., Third-Party OAuth)

Third-party sites like Google or Facebook often have anti-automation measures (captchas, rate limits) that make UI-based testing tricky. Here are your best alternatives:

Option 1: Save & Reuse Authentication State

Manually complete the login flow once, save the browser's auth state (cookies, localStorage), then reuse it in your tests. You'll need the cypress-localstorage-commands plugin for this.

  1. Install the plugin:
npm install cypress-localstorage-commands --save-dev
  1. Add it to cypress/support/e2e.js:
import 'cypress-localstorage-commands';
  1. Write the test to save/restore state:
beforeEach(() => {
  cy.restoreLocalStorage();
  // Restore any auth cookies if needed
  cy.setCookie('third-party-auth-token', Cypress.env('SAVED_AUTH_TOKEN'), {
    domain: 'your-original-site.com'
  });
  cy.visit('/connections');
});

afterEach(() => {
  cy.saveLocalStorage();
});

it('loads connections using saved auth state', () => {
  cy.get('[data-testid="connections-container"]').should('be.visible');
});

Note: You'll need to manually grab the auth token/cookie once and store it in cypress.env.json.

Option 2: Simulate the OAuth Flow via API

If the third-party provider supports OAuth 2.0, you can simulate the authorization code flow directly via cy.request() to avoid the UI entirely. This requires knowing the provider's API endpoints and having valid client credentials.

Example code outline:

it('simulates OAuth authorization to access connections', () => {
  // Step 1: Get the authorization code (bypass the login UI)
  cy.request({
    method: 'GET',
    url: 'https://third-party-provider.com/oauth/authorize',
    qs: {
      client_id: Cypress.env('OAUTH_CLIENT_ID'),
      redirect_uri: 'https://your-original-site.com/oauth/callback',
      response_type: 'code',
      scope: 'openid profile'
    },
    followRedirect: false // Don't follow the redirect, grab the code from the header
  }).then(authRes => {
    const authCode = authRes.headers.location.match(/code=([^&]+)/)[1];

    // Step 2: Exchange the code for an access token
    return cy.request({
      method: 'POST',
      url: 'https://third-party-provider.com/oauth/token',
      body: {
        client_id: Cypress.env('OAUTH_CLIENT_ID'),
        client_secret: Cypress.env('OAUTH_CLIENT_SECRET'),
        code: authCode,
        grant_type: 'authorization_code',
        redirect_uri: 'https://your-original-site.com/oauth/callback'
      }
    });
  }).then(tokenRes => {
    // Step 3: Set the token in your site's context
    cy.setCookie('access_token', tokenRes.body.access_token, {
      domain: 'your-original-site.com'
    });
    cy.visit('/connections');
    cy.get('[data-testid="connections-list"]').should('be.visible');
  });
});

Caveat: Some third-party providers block this kind of direct API access or require additional security checks (like PKCE), so test this first.


内容的提问来源于stack exchange,提问作者ITguy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:51:05