PAYATHON 2026

Playwright 使用现有 Chrome Profile 2 启动后卡住并超时,如何解决?

数据阿明

结论

先将 userDataDir 改为独立的自动化目录,在该目录中完成登录,再持续使用这个目录。当前代码直接使用日常 Chrome 的 User Data 根目录,Playwright 官方明确不支持这种用法。通过 --profile-directory=Profile 2 选择子配置文件也无法避开这一限制。Playwright 持久化上下文文档

从日志只能确认执行停在 launchPersistentContext(),并最终触发测试的 30 秒超时。结合现有配置,应优先排查默认用户数据目录限制,同时检查组织策略和目录占用。仅凭这段日志无法确定唯一原因。

为什么窗口打开了,代码却没有继续?

Chrome 进程显示窗口后,Playwright 未必已经建立控制连接。只要 launchPersistentContext() 尚未返回,后面的 page.goto() 就不会执行,因此此时不应先调整 Gemini 的页面加载等待方式。

Chrome 从 136 开始限制通过 --remote-debugging-port 和 --remote-debugging-pipe 调试默认用户数据目录,调试时要求 --user-data-dir 指向非默认目录。题目报告的 Chrome 146 也适用这一规则。Chrome 官方说明

这里要区分两个路径:

User Data              ← 用户数据根目录
└── Profile 2           ← 根目录中的一个配置文件

原代码将根目录作为 userDataDir,再通过参数选择子配置文件,路径层级并没有写反。问题在于它仍然使用日常浏览器的默认数据根目录。将 userDataDir 改成 User Data\Profile 2 也不能解决这个问题。

launchPersistentContext() 会启动浏览器实例,不会接管已经打开的 Chrome 窗口。同一个用户数据目录不能同时供多个浏览器实例使用。Playwright API 文档

使用独立目录保存登录状态

删除原来的锁文件清理逻辑,改用新的、可写的目录。下面的代码保留了交互暂停,方便首次登录和检查页面:

// @ts-check
import { chromium, test } from '@playwright/test';
import os from 'os';
import path from 'path';

test('open gemini with persistent chrome profile', async () => {
  const userDataDir = path.join(
    os.homedir(),
    'playwright-profiles',
    'gemini'
  );

  const context = await chromium.launchPersistentContext(userDataDir, {
    channel: 'chrome',
    headless: false,
    timeout: 20_000,
  });

  try {
    const page = context.pages()[0] ?? (await context.newPage());

    await page.goto('https://gemini.google.com/', {
      waitUntil: 'domcontentloaded',
    });

    // 首次运行时暂停,在浏览器中手动登录并检查页面。
    await page.pause();
  } finally {
    await context.close();
  }
});

假设文件名仍是 example.spec.js,在 PowerShell 中运行:

npx playwright test example.spec.js --debug --workers=1

--debug 会开启交互调试,并将默认测试超时设为 0,便于手动操作。示例中的浏览器启动超时仍为 20 秒。Playwright 调试文档

首次运行时,如果账号和组织允许在该浏览器会话中登录,就在暂停期间完成登录,再点击 Inspector 的 Resume,让代码正常关闭上下文。后续运行继续使用同一个目录。需要无人值守运行时,删除 await page.pause(),改为等待实际业务需要的页面元素,并使用普通测试命令。

新目录不会自动继承原有 Profile 2 的登录状态,但可以保存独立的浏览器配置,供后续重复使用。能否登录成功、会话是否过期,仍取决于 Google 及组织的认证要求。

直接复制 Profile 2 也不一定能完成迁移。配置文件中的加密数据和登录会话未必能在新目录中继续使用。

独立目录仍然卡住时怎么排查?

检查组织管理策略

在受管理的 Chrome 中打开 chrome://policy,检查 RemoteDebuggingAllowed 的实际生效值。禁用该策略会禁止远程调试;即使已启用或未配置,仍需满足 Chrome 的其他调试限制。Chrome 策略定义

如果组织禁止远程调试,需要由管理员确认允许的自动化方式。更换用户数据目录不会自动解除机器级策略。

检查目录是否被占用

确保其他测试进程或浏览器实例没有占用新的 playwright-profiles\gemini 目录。--workers=1 可以减少当前测试运行中的并发,但不能排除其他进程占用。如果配置了多个项目,也应只运行需要的项目。

不要再依靠删除 SingletonLock、SingletonCookie、SingletonSocket 来解决问题。删除这些文件不能解除活跃进程对目录的使用,也不能修复调试策略限制。

获取浏览器启动日志

在 PowerShell 中启用浏览器日志后重跑:

$env:DEBUG = 'pw:browser'
npx playwright test example.spec.js --workers=1
Remove-Item Env:DEBUG

重点检查实际启动参数、Chrome 标准错误输出和进程退出信息,看看是否有目录占用或远程调试相关提示。分享日志前应隐藏个人路径和账号信息。

原报错 Test timeout of 30000ms exceeded. 表示整个测试触发了超时,不能据此断定浏览器只是需要更长的启动时间。临时增加 test.setTimeout() 可以留出诊断时间,但无法解决目录限制或策略禁用。Playwright 超时文档

如果必须操作已经打开的浏览器,需要另行评估 chromium.connectOverCDP(),并提供浏览器实际开放的 CDP 端点。它不能仅凭 Profile 2 的目录路径连接现有窗口,也不能绕过调试权限限制。Playwright CDP 连接文档

备注:内容仅供参考。