cypress - 如何从导航器设置状态或调度操作(例如:柏树测试)
问题描述
赛普拉斯(e2e 测试)给出的一个好的做法是以编程方式设置应用程序的状态,而不是使用 UI。这当然是有道理的。
在此视频https://www.youtube.com/watch?v=5XQOK0v_YRE Brian Mann 提出了这个解决方案来公开 Redux 商店:
NGXS 是否有可能在测试期间以编程方式访问不同的状态?一个例子是登录过程:直接调度登录操作或使用访问令牌设置存储,以便在任何测试之前登录,会很好。
解决方案
这种配置对我有用:在模型的 app 文件夹中:
export interface IWindowCypress {
Cypress: {
__store__: Store;
};
}
在 app.module.ts 中:
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {NgxsModule, Store} from '@ngxs/store';
import {AppComponent, IWindowCypress} from './app.component';
import {ZooState} from './state/zoo.state';
import {NgxsReduxDevtoolsPluginModule} from '@ngxs/devtools-plugin';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, NgxsModule.forRoot([ZooState], {}),
NgxsReduxDevtoolsPluginModule.forRoot()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(protected store: Store) {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
console.log('ustawiłem store');
windowSore.Cypress.__store__ = store;
}
}
}
在应用程序组件中使用:
import {Component} from '@angular/core';
import {Store} from '@ngxs/store';
import {FeedAnimals} from './state/zoo.state';
/// <reference types="Cypress" />
export interface IWindowCypress {
Cypress: {
__store__: Store;
};
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'cypress-ngxs';
constructor() {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
}
}
}
在柏树规范中使用:
/// <reference types="Cypress" />
import {Store} from '@ngxs/store';
import {IWindowCypress} from 'src/app/app.component';
import {FeedAnimals, ZooState} from '../../../src/app/state/zoo.state';
import {Observable} from 'rxjs';
describe('My Second Test Suite', () => {
it('My FirstTest case', () => {
cy.visit(' http://localhost:4200/ ');
cy.get('.content > :nth-child(2)').should(item => {
const windowSore: IWindowCypress = window as unknown as IWindowCypress;
if (windowSore.Cypress) {
// get store
const store: Store = windowSore.Cypress.__store__;
// declare observable
const myObs: Observable<boolean> = store.select(ZooState.zoo$);
// subscribe
myObs.pipe().subscribe((feed) => console.log('from subscribe: ', feed));
// make some dispatch
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
(windowSore.Cypress.__store__ as Store).dispatch(new FeedAnimals());
}
});
});
});
和动物园状态:
import {Injectable} from '@angular/core';
import {Action, Selector, State, StateContext} from '@ngxs/store';
export class FeedAnimals {
static readonly type = '[Zoo] FeedAnimals';
}
export interface ZooStateModel {
feed: boolean;
}
@State<ZooStateModel>({
name: 'zoo',
defaults: {
feed: false
}
})
@Injectable()
export class ZooState {
@Selector()
static zoo$(state: ZooStateModel): boolean {
return state.feed;
}
@Action(FeedAnimals)
feedAnimals(ctx: StateContext<ZooStateModel>): void {
console.log('fedeeeeeed');
const state = ctx.getState();
ctx.setState({
...state,
feed: !state.feed
});
}
}
推荐阅读
- python - Youtube-dl 不允许我写入我有权访问的文件夹
- php - 安装 ACF Pro 插件后,WordPress 自定义字段选项卡消失了
- reactjs - 使用反应钩子过滤类别
- twitter-bootstrap - 如何使用 Bootstrap 4 创建可独立滚动的列?
- java - 由 1st Spinner 创建的 2nd Spinner 应该更新 textview
- angular - 在每个管道中使用 takeUntil 是一个多余的步骤?
- mongodb - 无法连接到 Docker 容器内的 MongoDB Atlas
- python - nltk ngrams >> TypeError:'_io.TextIOWrapper'对象不可调用
- r - R 在文件中(文件名,“r”,编码 = 编码):
- javascript - 如何使用 Node.js 和 Redis 在多个集群中只运行一次 flushall?