Issue
When I write my Cypress e2e tests for my Angular application, I often use the visit() command like this:
.visit('/foo/bar')
This get's the job done, i.e. Cypress navigates to /foo/bar
, but the entire application reloads. This is very slow, and does not mimic actual user behaviour.
Is it possible to navigate/visit the Angular application, without full page reloads?
I did try:
cy.window().then((win) => {
win.history.pushState({}, '', '/foo/bar')
})
But angular does not react to this.
Solution
I solved this by adding a custom cypress command that calls a method on the Angular applications app.component.ts
. The solution look like this Updated to Ivy:
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.getComponent(el);
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: {
getComponent: (element: any) => any;
};
}
We have used this for 2 months now, and it works great in local development, speeding up test executions with x3. But in CI it's another story.
Answered By - DauleDK
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.