1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
  2. Anuncie Aqui
    Anuncie aqui você Também: fdantas@4each.com.br

Test on a style directive with cypress

Discussão em 'Angular' iniciado por your.Disciple, Outubro 15, 2024.

  1. I haven't found much help on the internet on how to do tests on directives with cypress. I have done tests before on a lot of components. but I am quite 'stupidly' stuck here.

    I have done only few lines. I don't know if I am supposed to test the methods as I do with components or just test the html.

    Here is the directive I am supposed to test :

    @Directive({
    selector: '[style-paginator]'
    })
    export class StylePaginatorDirective implements OnInit, OnChanges {

    private _pageGapTxt = '...';
    private _rangeStart: number;
    private _rangeEnd: number;
    private _isPaginatorReady = false;
    private _buttons = [];
    private _curPageObj: PageObject = {
    length: 0,
    pageIndex: 0,
    pageSize: 0,
    previousPageIndex: 0,
    };

    private _showTotalPages = 2;

    @Input()
    get showTotalPages(): number {
    return this._showTotalPages;
    }

    @Input() dataLength: number;

    set showTotalPages(value: number) {
    this._showTotalPages = value % 2 == 0 ? value + 1 : value;
    }

    get inc(): number {
    return this._showTotalPages % 2 == 0
    ? this.showTotalPages / 2
    : (this.showTotalPages - 1) / 2;
    }

    get numOfPages(): number {
    return this.matPag.getNumberOfPages();
    }

    get lastPageIndex(): number {
    return this.matPag.getNumberOfPages() - 1;
    }

    constructor(
    @Host() @Self() @Optional() private readonly matPag: MatPaginator,
    private vr: ViewContainerRef,
    private ren: Renderer2,
    private translate: TranslateService
    ) {
    //to rerender buttons on items per page change and first, last, next and prior buttons
    this.matPag.page.subscribe((e: PageObject) => {
    if (
    this._curPageObj.pageSize != e.pageSize &&
    this._curPageObj.pageIndex != 0
    ) {
    e.pageIndex = 0;
    this._rangeStart = 0;
    this._rangeEnd = this._showTotalPages - 1;
    }
    this._curPageObj = e;

    this.initPageRange();
    });

    // On fait un setTimeOut pour que le component finisse le rendering des éléments avant d'ajouter les boutons du paginateur
    /* setTimeout(() => {
    this._rangeStart = 0;
    this._rangeEnd = this._showTotalPages - 1;
    this.initPageRange();
    }, 500); */
    }

    ngOnChanges(changes: SimpleChanges): void {
    this._rangeStart = 0;
    this._rangeEnd = this._showTotalPages - 1;
    this.initPageRange();
    }

    private buildPageNumbers() {
    // On ajoute la classe table-paginator au mat-paginator
    this.ren.addClass(this.vr.element.nativeElement, 'table-paginator');

    const actionContainer = this.vr.element.nativeElement.querySelector(
    'div.mat-mdc-paginator-range-actions'
    );
    const nextPageNode = this.vr.element.nativeElement.querySelector(
    'button.mat-mdc-paginator-navigation-next'
    );
    const prevButtonCount = this._buttons.length;

    // Ajout de la classe paginator-range-label sur le label qui affiche le compteur des éléments actuellement affichés
    if (this.vr.element.nativeElement.querySelector('div.mat-mdc-paginator-range-label')){
    setTimeout(() => {
    this.ren.addClass(this.vr.element.nativeElement.querySelector('div.mat-mdc-paginator-range-label'), 'paginator-range-label');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('div.mat-mdc-select-value'), 'paginator-page-size-value');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('div[matformfieldnotchedoutline]'), 'paginator-page-size-default-outline');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('div.mat-mdc-form-field-flex'), 'paginator-page-size-form-field-flex');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('mat-form-field'), 'paginator-page-size-form-field');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('.mat-mdc-paginator-page-size-label'), 'paginator-page-size-label');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('.mat-mdc-select-arrow-wrapper'), 'paginator-page-size-arrow-wrapper');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('.mat-mdc-select-arrow'), 'paginator-page-size-arrow');

    this.ren.addClass(this.vr.element.nativeElement.querySelector('div.mat-mdc-paginator-container'), 'paginator-container');

    this.vr.element.nativeElement.querySelector('.paginator-page-size-label').innerHTML = this.translate.instant('ITEMS_PER_PAGE');



    const pageSizeArrow = this.vr.element.nativeElement.querySelector('.mat-mdc-select-arrow');
    const arrowSvg = pageSizeArrow.childNodes[0];
    const arrowImg = this.ren.createElement('img');
    this.ren.addClass(arrowImg, 'icon-paginator-select-page');
    this.ren.insertBefore(pageSizeArrow, arrowImg, arrowSvg);
    this.ren.removeChild(pageSizeArrow, arrowSvg);

    // remove buttons before creating new ones
    if (this._buttons.length > 0) {
    this._buttons.forEach((button) => {
    this.ren.removeChild(actionContainer, button);
    });
    //Empty state array
    this._buttons.length = 0;
    }

    //initialize next page and last page buttons
    if (this._buttons.length == 0) {
    let nodeArray =
    this.vr.element.nativeElement.childNodes[0].childNodes[0].childNodes[2]
    .childNodes;
    setTimeout(() => {
    for (let i = 0; i < nodeArray.length; i++) {
    if (nodeArray.nodeName === 'BUTTON') {
    if (nodeArray.innerHTML.length > 100 && nodeArray.disabled) {
    this.ren.addClass(nodeArray, 'paginator-navigation-next-previous');
    } else if (
    nodeArray.innerHTML.length > 100 &&
    !nodeArray.disabled
    ) {
    this.ren.addClass(nodeArray, 'paginator-navigation-next-previous');
    }
    }
    }
    });
    }

    // On affiche toujours la première page si elle n'est pas déjà visible
    if (this._rangeStart >= 1)
    this.ren.insertBefore(
    actionContainer,
    this.createFirstPageButton(),
    nextPageNode
    );

    // On affiche toujours '...' au début si la deuxième page n'est pas visible
    if (this._rangeStart > 1)
    this.ren.insertBefore(
    actionContainer,
    this.createFirstThreeDots(),
    nextPageNode
    )

    // On affiche tous les boutons sauf la dernière
    for (let i = 0; i < this.numOfPages; i++) {
    this._isPaginatorReady = true;
    if (i >= this._rangeStart && i <= this._rangeEnd) {
    this.ren.insertBefore(
    actionContainer,
    this.createButton(i, this.matPag.pageIndex),
    nextPageNode
    );
    }

    // Enfin on ajoute '...' (si l'avant dernière page n'est pas visible)
    if (i == this._rangeEnd) {
    this.ren.insertBefore(
    actionContainer,
    this.createButton(this._pageGapTxt, this._rangeEnd),
    nextPageNode
    );
    }
    }

    // On ajoute toujours la dernière page sauf si elle déja visible
    if (this._rangeEnd < this.lastPageIndex)
    this.ren.insertBefore(
    actionContainer,
    this.createLastPageButton(),
    nextPageNode
    )
    },2);
    }
    }

    private createFirstPageButton() {
    const linkBtn: MatButton = this.ren.createElement('button');
    this.ren.addClass(linkBtn, 'paginator-navigation-page');

    const text = this.ren.createText(1 + '');

    this.ren.listen(linkBtn, 'click', () => {
    this.switchPage(0);
    });

    this.ren.appendChild(linkBtn, text);
    //Add button to private array for state
    this._buttons.push(linkBtn);
    return linkBtn;
    }

    private createFirstThreeDots() {
    const linkBtn: MatButton = this.ren.createElement('button');
    this.ren.addClass(linkBtn, 'paginator-navigation-page');

    const text = this.ren.createText(this._pageGapTxt);
    let newIndex = this._rangeStart-1;
    if (newIndex < 0) newIndex = 0;

    this.ren.listen(linkBtn, 'click', () => {
    this.switchPage(newIndex);
    });

    this.ren.appendChild(linkBtn, text);
    //Add button to private array for state
    this._buttons.push(linkBtn);
    return linkBtn
    }

    private createLastPageButton() {
    const linkBtn: MatButton = this.ren.createElement('button');
    this.ren.addClass(linkBtn, 'paginator-navigation-page');

    const text = this.ren.createText(this.lastPageIndex + 1 + '');

    this.ren.listen(linkBtn, 'click', () => {
    this.switchPage(this.lastPageIndex);
    });

    this.ren.appendChild(linkBtn, text);
    //Add button to private array for state
    this._buttons.push(linkBtn);
    return linkBtn;
    }

    private createButton(i: any, pageIndex: number): any {
    const linkBtn: MatButton = this.ren.createElement('button');
    //this.ren.addClass(linkBtn, "mat-mini-fab");
    this.ren.addClass(linkBtn, 'paginator-navigation-page');

    const pagingTxt = isNaN(i) ? this._pageGapTxt : +(i + 1);
    const text = this.ren.createText(pagingTxt + '');
    switch (i) {
    case pageIndex:
    this.ren.setAttribute(linkBtn, 'disabled', 'disabled');
    this.ren.addClass(linkBtn, 'page-active');
    break;
    case this._pageGapTxt:
    let newIndex = this._rangeEnd + 1;

    if (newIndex >= this.numOfPages) newIndex = this.lastPageIndex;

    if (pageIndex != this.lastPageIndex) {
    this.ren.setStyle(linkBtn, 'display', 'inline-block');
    this.ren.listen(linkBtn, 'click', () => {
    this.switchPage(newIndex);
    });
    }

    if (pageIndex == this.lastPageIndex || pageIndex == this.lastPageIndex-1) {
    this.ren.setAttribute(linkBtn, 'disabled', 'disabled');
    this.ren.setStyle(linkBtn, 'display', 'none');
    }

    break;
    default:
    this.ren.listen(linkBtn, 'click', () => {
    this.switchPage(i);
    });
    break;
    }

    this.ren.appendChild(linkBtn, text);
    //Add button to private array for state
    this._buttons.push(linkBtn);
    return linkBtn;
    }
    //calculates the button range based on class input parameters and based on current page index value. Used to render new buttons after event.
    private initPageRange(): void {
    const middleIndex = (this._rangeStart + this._rangeEnd) / 2;

    this._rangeStart = this.calcRangeStart(middleIndex);
    this._rangeEnd = this.calcRangeEnd(middleIndex);

    this.buildPageNumbers();
    }

    //Helper function To calculate start of button range
    private calcRangeStart(middleIndex: number): number {
    switch (true) {
    case this._curPageObj.pageIndex == 0 && this._rangeStart != 0:
    return 0;
    case this._curPageObj.pageIndex > this._rangeEnd:
    return this._curPageObj.pageIndex + this.inc > this.lastPageIndex
    ? this.lastPageIndex - this.inc * 2
    : this._curPageObj.pageIndex - this.inc;
    case this._curPageObj.pageIndex > this._curPageObj.previousPageIndex &&
    this._curPageObj.pageIndex > middleIndex &&
    this._rangeEnd < this.lastPageIndex:
    return this._rangeStart + 1;
    case this._curPageObj.pageIndex < this._curPageObj.previousPageIndex &&
    this._curPageObj.pageIndex < middleIndex &&
    this._rangeStart > 0:
    return this._rangeStart - 1;
    default:
    return this._rangeStart;
    }
    }
    //Helpter function to calculate end of button range
    private calcRangeEnd(middleIndex: number): number {
    switch (true) {
    case this._curPageObj.pageIndex == 0 &&
    this._rangeEnd != this._showTotalPages:
    return this._showTotalPages - 1;
    case this._curPageObj.pageIndex > this._rangeEnd:
    return this._curPageObj.pageIndex + this.inc > this.lastPageIndex
    ? this.lastPageIndex
    : this._curPageObj.pageIndex + 1;
    case this._curPageObj.pageIndex > this._curPageObj.previousPageIndex &&
    this._curPageObj.pageIndex > middleIndex &&
    this._rangeEnd < this.lastPageIndex:
    return this._rangeEnd + 1;
    case this._curPageObj.pageIndex < this._curPageObj.previousPageIndex &&
    this._curPageObj.pageIndex < middleIndex &&
    this._rangeStart >= 0 &&
    this._rangeEnd > this._showTotalPages - 1:
    return this._rangeEnd - 1;
    default:
    return this._rangeEnd;
    }
    }
    //Helper function to switch page on non first, last, next and previous buttons only.
    private switchPage(i: number): void {
    const previousPageIndex = this.matPag.pageIndex;
    this.matPag.pageIndex = i;
    this.matPag['_emitPageEvent'](previousPageIndex);
    this.initPageRange();
    }

    //Initialize default state after view init
    public ngOnInit() {
    const interval = setInterval(() => {
    if (!this._isPaginatorReady) {
    this._rangeStart = 0;
    this._rangeEnd = this._showTotalPages - 1;
    this.initPageRange();
    }
    else clearInterval(interval);
    }, 300);
    }

    }


    Here is what i have done so far, which is basically nothing.

    @Component({
    template: `
    <mat-paginator [length]="100" [pageSize]="10" [pageIndex]="0" data-cy="paginator"></mat-paginator>
    <div data-cy="buttons">
    <ng-container *ngFor="let button of buttons">
    <div class="paginator-navigation-page" data-cy="page-button">{{ button }}</div>
    </ng-container>
    </div>
    `,
    })

    class TestPaginatorComponent {
    buttons: string[] = [];
    }

    const mockTranslateService = {
    get: (key: string) => key,
    instant: (key: string) => key,
    use: () => {},
    };

    describe('StylePaginatorDirective', () => {

    it('should display the paginator and navigate between pages', fakeAsync(() => {

    cy.mount(TestPaginatorComponent, {
    declarations: [StylePaginatorDirective],
    imports: [
    MatPaginatorModule,
    NoopAnimationsModule,
    TranslateModule.forRoot(),
    ],
    providers: [
    { provide: TranslateService, useValue: mockTranslateService },
    ]
    });

    cy.get('[data-cy=paginator]').should('be.visible');

    cy.get('.mat-mdc-paginator-range-label').should('contain', '1 – 10 of 100');

    cy.get('button.mat-mdc-paginator-navigation-next')
    .should('be.visible')
    .click();

    cy.get('.mat-mdc-paginator-range-label').should('contain', '11 – 20 of 100');

    cy.get('button.mat-mdc-paginator-navigation-previous').click();
    cy.get('.mat-mdc-paginator-range-label').should('contain', '1 – 10 of 100');


    }));
    });

    Continue reading...

Compartilhe esta Página