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

如何在Playwright中跳过Microsoft身份验证?

处理Microsoft身份验证时,Playwright存储登录状态后仍出现登录界面的问题排查

问题描述

我已经编写了global-setup.ts文件,通过Playwright完成Microsoft账号登录流程,并生成userLogin.json存储登录状态;同时在playwright.config.ts中配置了该storageState文件。但运行测试用例时,仍会出现登录界面。请问处理Microsoft身份验证时,是否需要额外的操作?

相关代码

global-setup.ts

// global-setup.ts
import { chromium, expect, FullConfig } from '@playwright/test';
import { loginPO } from './PageObjects/login.pageObject';

async function globalSetup(config: FullConfig) {
  const { baseURL } = config.projects[0].use;
  const browser = await chromium.launch();
  const page = await browser.newPage();
  const login = new loginPO(page);
  await page.goto(baseURL!);
  require('dotenv').config();
  await login.signIn.click();
  await expect(login.usernameInput).toBeVisible();
  await login.usernameInput.pressSequentially(process.env.uname, {delay:100});
  await page.keyboard.press('Enter');
  await expect(page.locator('id=displayName')).toBeVisible();
  await login.passwordInput.pressSequentially(process.env.pword, {delay:100});
  await page.keyboard.press('Enter');
  await expect(login.stayLoggedInText).toBeVisible();
  await expect(login.passwordInput).toBeHidden();
  await login.continueButton.click();
  await expect(page.locator('//p[contains(text(), "View your data from Microsoft Graph")]')).toBeVisible({timeout:10000});
  await page.context().storageState({ path: 'userLogin.json' });
  await browser.close();
}
export default globalSetup;

playwright.config.ts

import { PlaywrightTestConfig } from '@playwright/test';
require('./playwright.config');
require('dotenv').config();
const config: PlaywrightTestConfig = {
  globalSetup: require.resolve('./global-setup'),
  workers: 1,
  retries: 1,
  projects: [
    {
      name: 'Backstage',
      use: {
        baseURL: process.env.URL,
        screenshot: "only-on-failure",
        video: "retain-on-failure",
        headless: true,
        storageState: 'userLogin.json', 
        viewport: { width: 1536, height: 850 },
        ignoreHTTPSErrors: true,
      } 
    }
  ]
};
export default config;

测试用例代码

import { expect, test } from '@playwright/test';
import { mainToolActions } from '../Actions/mainTool.actions';


test.describe('Navigate to different domains', () => {
  let mainTool;

  test.beforeEach(async ({ page }) => {
    mainTool = new mainToolActions(page);
    test.setTimeout(10000);
    page.goto('/', {timeout:10000});
    return test.setTimeout(10000);
  });

  test('Click on Main tool', async () => {
    await mainTool.clickMainOption();
  });
});

排查方向与解决方法

  • 调整环境变量加载时机
    将global-setup.ts中的require('dotenv').config();移到文件最顶部,避免登录时环境变量未加载导致账号密码为空或错误。

  • 等待登录流程完全结束再保存状态
    当前代码在权限授权页面(显示"View your data from Microsoft Graph")就保存状态,但此时可能还未完成跳转到目标应用的最终登录步骤,跨域Cookie也未完全写入。需要修改等待逻辑,改为等待目标应用主页的标志性元素出现后再保存状态,确保所有认证Cookie都已生成。

  • 使用绝对路径存储状态文件
    相对路径可能因运行目录不同导致状态文件找不到,引入path模块,用绝对路径生成userLogin.json:

    import path from 'path';
    // ...
    await page.context().storageState({ path: path.resolve(__dirname, 'userLogin.json') });
    

    同时确保playwright.config.ts中storageState也使用相同的绝对路径,或者确认相对路径指向的是同一文件。

  • 关闭Headless模式排查登录流程
    在global-setup.ts中启动浏览器时关闭Headless模式,手动查看登录过程是否存在未处理的步骤(如MFA验证、验证码、额外安全确认),这些步骤会导致登录状态不完整:

    const browser = await chromium.launch({ headless: false });
    
  • 验证测试用例的baseURL一致性
    确保测试用例中page.goto('/')使用的baseURL和globalSetup中登录的baseURL完全一致,否则会因域名不同导致Cookie无法复用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:24:54