你如何在cypress.io测试中可靠地等待页面空闲

chr*_*_68 7 testing web angular cypress

使用cypress.io测试角度网页时,最好/最可靠的方法是检测页面何时完全加载和空闲.不只是onload事件.需要包括所有XHR请求,角度摘要周期完成以及所有渲染完成,包括所有动画完成.

原因是此时我想测试该页面不包含元素并且无法测试,直到上述所有内容完全完成.

chr*_*_68 10

根据记录,我们为此(对于 AngularJS)所做的是添加一个waitforpageidle可以像这样使用的新命令:

cy.waitforpageidle();
Run Code Online (Sandbox Code Playgroud)

打字稿如下:

Cypress.Commands.add(
    "waitforpageidle",
    () => {
        console.warn("Waiting for page idle state");

        const pageIdleDetector = new PageIdleDetector();

        pageIdleDetector.WaitForPageToBeIdle();
    }
);
Run Code Online (Sandbox Code Playgroud)

其中PageIdleDetector如下:

export class PageIdleDetector
{   
    defaultOptions: Object = { timeout: 60000 };

    public WaitForPageToBeIdle(): void
    {
        this.WaitForPageToLoad();
        this.WaitForAngularRequestsToComplete();
        this.WaitForAngularDigestCycleToComplete();
        this.WaitForAnimationsToStop();
    }

    public WaitForPageToLoad(options: Object = this.defaultOptions): void
    {
        cy.document(options).should((myDocument: any) =>
        {
            expect(myDocument.readyState, "WaitForPageToLoad").to.be.oneOf(["interactive", "complete"]);
        });
    }

    public WaitForAngularRequestsToComplete(options: Object = this.defaultOptions): void
    {
        cy.window(options).should((myWindow: any) =>
        {
            if (!!myWindow.angular)
            {
                expect(this.NumberOfPendingAngularRequests(myWindow), "WaitForAngularRequestsToComplete").to.have.length(0);
            }
        });
    }

    public WaitForAngularDigestCycleToComplete(options: Object = this.defaultOptions): void
    {
        cy.window(options).should((myWindow: any) =>
        {
            if (!!myWindow.angular)
            {
                expect(this.AngularRootScopePhase(myWindow), "WaitForAngularDigestCycleToComplete").to.be.null;
            }
        });
    }

    public WaitForAnimationsToStop(options: Object = this.defaultOptions): void
    {
        cy.get(":animated", options).should("not.exist");
    }

    private getInjector(myWindow: any)
    {
        return myWindow.angular.element(myWindow.document.body).injector();
    }

    private NumberOfPendingAngularRequests(myWindow: any)
    {
        return this.getInjector(myWindow).get('$http').pendingRequests;
    }

    private AngularRootScopePhase(myWindow: any)
    {
        return this.getInjector(myWindow).get("$rootScope").$$phase;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 看起来不错,但这不是 AngularJS 的代码(而不是 Angular 2+) (2认同)

Rui*_*ues 6

您可以让 Cypress 等待任何请求完成后再继续。因此,如果您想等待某个页面的所有 XHR,您可以对每个 XHR 执行以下操作。等待的时间由responseTimeout 配置定义。

cy.server();
cy.route('**/api/getData').as('getData');
cy.visit('/home');
cy.wait('@getData');
Run Code Online (Sandbox Code Playgroud)

或者等待几条路线:

cy.server();
cy.route('**/api/getData').as('getDataX');
cy.route('**/api/getData').as('getDataY');

cy.visit('/home');
cy.wait(['@getDataX', '@getDataY']);
Run Code Online (Sandbox Code Playgroud)

Cypress 最佳实践:不必要的等待。

赛普拉斯文档等待别名。