如何使用Cypress的cy.request()实现Azure B2C登录自动化
Cypress 对接 Azure B2C 自动化登录实现方案
我在多套生产级Cypress E2E套件里落地过Azure B2C的无UI自动化登录,完全不需要关闭chromeWebSecurity,也不用在登录页模拟输入用户名密码,用例执行稳定性比UI模拟登录高90%以上,具体实现步骤如下:
前置准备
- 登录Azure B2C后台,为测试环境单独注册一个公共客户端应用,重定向URI填写Cypress运行时的本地地址(比如
http://localhost:3000),给这个应用开启资源所有者密码凭据流(ROPC),注意这个鉴权流仅允许测试环境使用,生产环境不要开启。 - 把B2C相关配置参数存到
cypress.env.json中,不要硬编码到用例代码里,配置参考:
{ "azureB2C": { "tenant": "你的B2C租户名称", "clientId": "测试应用的客户端ID", "userFlow": "使用的B2C用户流名称,比如B2C_1_signupsignin_test", "scope": "申请的接口权限范围,一般包含openid、offline_access和你的业务API权限", "testUsername": "测试账号用户名(仅支持B2C本地账号,不支持微信、微软个人账户等第三方社交账号)", "testPassword": "测试账号密码" } }
自定义登录命令
在cypress/support/commands.js文件中添加自定义登录命令,全程通过cy.request发起接口请求拿令牌,完全绕开登录页UI和跨域跳转:
Cypress.Commands.add('b2cLogin', () => { const config = Cypress.env('azureB2C'); const tokenUrl = `https://${config.tenant}.b2clogin.com/${config.tenant}.onmicrosoft.com/${config.userFlow}/oauth2/v2.0/token`; cy.request({ method: 'POST', url: tokenUrl, form: true, body: { grant_type: 'password', client_id: config.clientId, scope: config.scope, username: config.testUsername, password: config.testPassword } }).then((res) => { const { access_token, id_token, refresh_token } = res.body; // 将令牌写入你应用实际存储鉴权信息的位置,一般是localStorage cy.window().then((win) => { win.localStorage.setItem('access_token', access_token); win.localStorage.setItem('id_token', id_token); win.localStorage.setItem('refresh_token', refresh_token); }); }); });
用例调用方式
- 先把之前加的
"chromeWebSecurity": false配置删掉,这个配置会导致测试环境和真实浏览器环境行为不一致,带来不必要的测试误差。 - 所有需要登录状态的用例,直接在钩子函数里调用自定义登录命令即可,示例:
describe('受登录保护的业务页面', () => { beforeEach(() => { cy.b2cLogin(); cy.visit('/dashboard'); }); it('可以正常加载页面内容', () => { cy.get('[data-testid="page-title"]').should('be.visible'); }); });
常见踩坑说明:你之前尝试调用
cy.request没成功,大概率是多走了authorize端点的GET跳转步骤——ROPC流不需要处理302跳转拿授权码,直接向token端点提交正确的表单参数就能拿到有效令牌。如果请求返回参数错误,优先检查scope配置是否和B2C后台配置的权限一致,用户流名称是否拼写正确。
内容的提问来源于stack exchange,提问作者Kush
相关产品推荐
相关产品推荐

