1
votes

I am trying to solve a bug in an integration test, which should test if switching between pages using mat-paginator is working correctly. The paginator has a pageSize of 20, the response fixture contains 24 'items'. I expect to see 20 table rows, an enabled 'next' button and the remaining 4 rows when I click on that button. It works fine in the application, but when I run the test, it seems as if the pageSize is ignored. The 'next' button is disabled, the paginator says 'Page 1 of 1' and all 24 items are shown.

The error I get is Timed out retrying: cy.click() failed because this element is disabled, which makes sense because there's only one page instead of two.

I tried different things such as changing the amount of items and changing the pageSize in both the actual code of the application and inspecting the element in the test window (using Chrome 84). Also moving "items" into "data" did not work.

These are the test, manyItems and the paginator (I did remove some code that doesn't apply to this problem)

Test

cy.route({ method: 'POST', url: '**/graphql', response: manyItems }).as('manyItems');
cy.visit('/items');
cy.wait(['@manyItems', '@uset', '@colleagues', '@groups'], { requestTimeout: 10000 });
cy.get('.mat-paginator').find('button.mat-paginator-navigation-next.mat-icon-button').click();

manyItems

{
  "data": {
    "items": [
      { },
      { }, // etc.
    ]
  }
}

Paginator

<mat-paginator [pageSize]="20" [hidePageSize]="true" *ngIf="dataSource.data.length > 0"></mat-paginator>

Is there a way to fix this?

Edit

The dataSource paginator gets set with a timeout around it:

setTimeout(() => (this.dataSource.paginator = this.paginator));

Now when I remove the timeout, the paginator doesn't work in the actual application, so I'm thinking this issue might have to do something with it?

2
You try to assert on a DOM element based on API response which is not necessarily wrong, but it might take some time in order to render. Could you add a cy.reload() before cy.get('.mat-paginator') ... and run it again? Let's make sure is not about the component state.Alex Izbas
Reloading didn't work, it still loads all 24 items.Demivk

2 Answers

0
votes

If it is a settling problem as @AlexIzbas suggests, you could preceed the button click with a test of the range label,

cy.route({ method: 'POST', url: '**/graphql', response: manyItems }).as('manyItems');
cy.visit('/items');
cy.wait(['@manyItems'], { requestTimeout: 10000 });

cy.get('.mat-paginator')
  .find('.mat-paginator-range-label')
  .should('contain', `20 of ${dataSource.length}`);

cy.get('.mat-paginator')
  .find('button.mat-paginator-next')
  .click();
0
votes

So the setTimout was actually causing the issue! The way I fixed it is by simply adding cy.tick(1000) after the wait:

cy.route({ method: 'POST', url: '**/graphql', response: manyItems }).as('manyItems');
cy.visit('/items');
cy.wait(['@manyItems', '@uset', '@colleagues', '@groups'], { requestTimeout: 10000 });
cy.tick(1000);
cy.get('.mat-paginator').find('button.mat-paginator-navigation-next.mat-icon-button').click();

Thanks again for all the comments!