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

Playwright(Edge)切换Edge配置文件后登录测试失败问题求助

问题背景与求助

测试目标

  • 以有头模式运行一次测试
  • 手动完成M365+MFA登录
  • 用storageState持久化会话
  • 在无头测试中复用会话

遇到的问题

运行初始化测试时,被重定向至Microsoft登录流程,因公司政策要求必须使用带工作配置文件的Microsoft Edge,登录过程中出现强制「Switch Edge profile」步骤,点击按钮后当前浏览器窗口关闭,Playwright抛出错误:

Error: page.waitForURL: Target page, context or browser has been closed

错误发生在await page.waitForURL('https://awesome-website.com');,原因是配置文件切换导致受控页面/上下文被关闭。

尝试直接用现有Edge工作配置文件启动持久化上下文时,进程被终止,推测是企业安全策略限制。

约束条件

  • 必须使用Microsoft Edge
  • 必须使用指定的工作Edge配置文件,不允许匿名/无配置文件访问
  • 无法用工作凭据创建新配置文件
  • 无法绕过配置文件强制要求
  • 无法禁用MFA或登录流程

具体求助

  1. 如何避免「Switch Edge profile」步骤破坏Playwright测试?
  2. 如何让Playwright直接启动正确的Edge工作配置文件?
  3. 如何可靠持久化认证信息?

倾向于UI-based方案,若Playwright+Edge配置文件完全不兼容,也接受通过Microsoft端点获取令牌的无头认证替代方案。


解决方案

1. 规避「Switch Edge profile」步骤的UI方案

配置文件切换会导致原页面被关闭,可通过监听浏览器的目标创建事件捕获新窗口,转而控制新窗口继续流程:

// auth.setup.ts
import { test as setup, Page } from '@playwright/test';

setup('persist authentication', async ({ browser }) => {
  const context = await browser.newContext({ channel: 'msedge' });
  const page = await context.newPage();

  await page.goto('https://awesome-website.com');

  // 监听新页面(配置文件切换后的窗口)
  let newPage: Page | null = null;
  context.on('page', (page) => {
    if (page.url().includes('microsoftonline.com') || page.url().includes('awesome-website.com')) {
      newPage = page;
    }
  });

  // 等待手动完成登录和配置文件切换
  console.log('请完成登录及配置文件切换,完成后按任意键继续...');
  await new Promise(resolve => process.stdin.once('data', resolve));

  // 切换到新页面并验证登录状态
  if (!newPage) throw new Error('未捕获到配置文件切换后的页面');
  await newPage.waitForURL('https://awesome-website.com');

  // 保存会话状态
  await context.storageState({ path: 'playwright/.auth/user.json' });
  await context.close();
});

核心逻辑是通过context.on('page')监听新窗口创建,手动操作完成后接管新窗口,避免原窗口关闭导致的流程中断。

2. 直接启动指定Edge工作配置文件

尝试通过指定配置文件目录启动Edge,注意不同系统的配置文件路径差异:

// playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
  use: {
    channel: 'msedge',
    launchOptions: {
      // 替换为你的工作配置文件目录(Windows示例)
      args: ['--profile-directory="Profile 1"', '--no-first-run', '--no-default-browser-check'],
    },
  },
});

配置文件路径参考:

  • Windows: C:\Users\<用户名>\AppData\Local\Microsoft\Edge\User Data\Profile 1
  • macOS: ~/Library/Application Support/Microsoft Edge/Profile 1
  • Linux: ~/.config/microsoft-edge/Profile 1

如果企业策略禁止直接访问配置文件目录,此方法可能失效,需转向令牌方案。

3. 可靠持久化认证信息的两种方案

方案一:UI-based会话持久化

使用上述目标监听方案,在配置文件切换完成后,从新窗口所在的上下文导出storageState,确保会话数据完整。

方案二:无头令牌认证(绕过UI限制)

若UI方案完全不可行,可通过Microsoft身份服务获取访问令牌,注入到测试上下文:

// auth.setup.ts
import { test as setup } from '@playwright/test';
import { ClientSecretCredential } from '@azure/identity';

setup('get M365 token and persist', async ({ browser }) => {
  // 需管理员配置服务主体权限
  const credential = new ClientSecretCredential(
    '你的租户ID',
    '你的客户端ID',
    '你的客户端密钥'
  );

  // 获取目标门户的访问令牌
  const tokenResponse = await credential.getToken('https://awesome-website.com/.default');

  const context = await browser.newContext({
    channel: 'msedge',
    extraHTTPHeaders: {
      'Authorization': `Bearer ${tokenResponse.token}`
    }
  });

  // 验证令牌有效性
  const page = await context.newPage();
  await page.goto('https://awesome-website.com');
  await page.waitForSelector('#logged-in-user');

  // 保存包含令牌的上下文状态
  await context.storageState({ path: 'playwright/.auth/user.json' });
  await context.close();
});

此方案需要企业管理员创建服务主体并授予对应门户的访问权限,令牌权限需匹配门户的认证要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 10:22:43