用赛普拉斯测试Angular时如何防止重新加载整个页面?

时间:2019-03-21 15:00:49

标签: angular angular-routing cypress

当我为Angular应用程序编写Cypress e2e测试时,我经常像这样使用visit()命令:

.visit('/foo/bar')

这完成了工作,即Cypress导航到/foo/bar,但是整个应用程序都重新加载。这非常很慢,并且不能模仿实际的用户行为。

是否可以导航/访问Angular应用程序而无需重新加载整个页面?

我确实尝试过:

cy.window().then((win) => {
   win.history.pushState({}, '', '/foo/bar')
})

但是角度对此没有反应。

3 个答案:

答案 0 :(得分:2)

您可以使其在CI环境中运行,并注册一个全局函数而不是角度分量的调用:

app.component.ts

export class AppComponent {
    constructor(
        private router: Router,
        private ngZone: NgZone,
    ) {
        // Method Cypress will call
        if ((window as any).Cypress) {
            (window as any).cypressNavigateByUrl = (url: string) => this.cypressNavigateByUrl(url);
        }
    }

    public cypressNavigateByUrl(url: string) {
        this.ngZone.run(() => {
            this.router.navigateByUrl(url);
        });
    }
}

cypress / support / commands.ts

Cypress.Commands.add('visitAngular', (url) => {
    cy.window().then((win) => {
        win.cypressNavigateByUrl(url);
    });
});

答案 1 :(得分:1)

我通过添加一个自定义的cypress命令来解决此问题,该命令调用Angular应用程序app.component.ts上的方法。解决方案如下:

app.component.ts

export class AppComponent {
    constructor(
        private router: Router,
        private ngZone: NgZone,
    ) {}

    // Method Cypress will call
    public navigateByUrl(url: string) {
        this.ngZone.run(() => {
            this.router.navigateByUrl(url);
        });
    }
}

cypress / support / commands.ts

// add new command to the existing Cypress interface
declare global {
    namespace Cypress {
        interface Chainable {
            visitAngular: (url: string) => Chainable<Window>;
        }
    }
}

// Custom function
export function visitAngular(url: string) {
    cy.get('body').then($body => {
        try {
            const el = $body.find('app-root')[0];
            const win = el.ownerDocument.defaultView;
            const componentInstance = win.ng.probe(el).componentInstance;
            cy.log(`Angular nav to '${url}' `);
            componentInstance.navigateByUrl(url);
            cy.url().should('contain', url);
        } catch (error) {
            cy.log(`Cypress nav to '${url}' `);
            cy.visit(url);
        }
    });
}

Cypress.Commands.add('visitAngular', visitAngular);

cypress / support / index.d.ts

interface Window {
    ng: {
        probe: typeof import('@angular/platform-browser/src/dom/debug/ng_probe').inspectNativeElement
    };
}

我们已经使用了2个月了,它在本地开发中效果很好,可以通过x3加快测试执行速度。但是在CI中,这是另一个故事。

答案 2 :(得分:0)

如果您使用的是基于哈希的路由,则可以手动操作URL:

mkdir ~/ForceHome

sudo mv /usr/lib/jvm ~/ForceHome