在Cypress E2E测试中操作Angular Store注入登录状态失败的问题排查
解决Cypress无法访问Angular NGRX Store的问题
我之前也碰到过一模一样的问题,咱们一步步来排查和解决:
1. 最关键的遗漏:测试前没有加载应用页面
你的Cypress测试代码里的before钩子直接去获取window.store,但此时Cypress打开的是空白页面,Angular应用根本没初始化,AppComponent的构造函数都没执行,自然不会把store挂载到window上!
修改你的Cypress测试代码,先访问应用的任意页面(比如首页),再去获取store:
describe('ContactListComponent', () => { before(() => { // 先访问应用,触发AppComponent初始化 cy.visit('/'); // 等待store被挂载到window上 cy.window() .should('have.property', 'store') .invoke('dispatch', { type: '[User Effect] Load user success', user: { isLoggedIn : true } }); }); // 你的测试用例... });
2. 优化Angular中Store的挂载逻辑
你的类型定义可以更简洁,直接扩展全局Window接口,避免类型断言的潜在问题;同时确保Cypress的环境判断更可靠:
修改app.component.ts:
// 扩展全局Window接口,添加store和Cypress属性 declare global { interface Window { store?: Store; Cypress?: Cypress.Cypress; } } @Component({ selector: 'my-root', templateUrl: './app.component.html', changeDetection: ChangeDetectionStrategy.OnPush, }) export class AppComponent { constructor(protected store: Store) { console.log('AppComponent'); // 更可靠的Cypress环境判断 if (window.Cypress) { console.log('save store to window'); window.store = store; } } }
3. 排查是否构建优化移除了console.log
如果测试时还是看不到save store to window的日志,可能是测试环境的构建配置开启了优化,把console.log给树摇掉了。
检查angular.json里的测试配置,确保关闭不必要的优化:
{ "projects": { "your-app": { "architect": { "test": { "options": { "optimization": false, "buildOptimizer": false } } } } } }
4. 备选方案:直接通过Angular Injector获取Store
如果挂载window.store的方式还是有问题,可以直接从Angular的全局注入器中获取Store,无需挂载到window:
修改Cypress测试代码:
describe('ContactListComponent', () => { before(() => { cy.visit('/'); cy.window().then(win => { // 通过Angular全局ng对象获取注入器 const injector = win.ng.getInjector(); const store = injector.get(Store); store.dispatch({ type: '[User Effect] Load user success', user: { isLoggedIn : true } }); }); }); // 你的测试用例... });
这个方案不需要修改Angular代码,适合不想把Store暴露到window的场景,但需要确保Angular的全局ng对象可用(开发环境默认开启,生产环境如果需要的话要开启调试模式)。
内容的提问来源于stack exchange,提问作者TCH
相关产品推荐
相关产品推荐

