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

时间:2018-05-25 08:48:53

标签: angular testing web cypress

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

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

2 个答案:

答案 0 :(得分:3)

为了记录我们为此所做的是添加一个新的 waitforpageidle 命令,可以像这样使用:

cy.waitforpageidle();

打字稿如下:

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

        const pageIdleDetector = new PageIdleDetector();

        pageIdleDetector.WaitForPageToBeIdle();
    }
);

其中 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;
    }
}

答案 1 :(得分:0)

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

cy.server();
cy.route('**/api/getData').as('getData');
cy.visit('/home');
cy.wait('@getData');

Cypress best practices: Unnecessary-Waiting.

Cypress docs on wait Alias.