How to test CDK virtual scroll in a mat-select?

Discussão em 'Angular' iniciado por fservantdev, Abril 16, 2025.

  1. fservantdev

    fservantdev Guest

    I have a <mat-select> displaying 100k items in a <cdk-virtual-scroll-viewport> and I would like to test it:

    <mat-select
    hideSingleSelectionIndicator
    [formControl]="selectedItem"
    (openedChange)="onOpenedChange($event)"
    >
    <cdk-virtual-scroll-viewport
    [itemSize]="OPTION_HEIGHT"
    [style.height.px]="scrollViewportHeight()"
    >
    <mat-option *cdkVirtualFor="let item of items()" [value]="item.value">
    {{ item.viewValue }}
    </mat-option>
    </cdk-virtual-scroll-viewport>
    </mat-select>


    it('should display the first options', async () => {
    const select = await loader.getHarness(MatSelectHarness);
    await select.open();

    const options = await select.getOptions();
    expect(options.length).toBe(10); // ❔ Why 10 by default?
    expect(await options[0].getText()).toBe('Item #0'); // ✔️ passes
    expect(await options[9].getText()).toBe('Item #9'); // ✔️ passes
    });

    it('should be able to scroll options', async () => {
    const select = await loader.getHarness(MatSelectHarness);
    await select.open();

    const scrollViewPort =
    fixture.componentInstance.scrollViewPort() as CdkVirtualScrollViewport;
    expect(scrollViewPort).toBeTruthy();
    scrollViewPort.scrollable.scrollTo({ top: 8000 });

    const options = await select.getOptions();
    expect(options.length).toBe(10);
    expect(await options[0].getText()).toBe('Item #100'); // ❌ fails :(
    expect(await options[9].getText()).toBe('Item #109'); // ❌ fails :(
    });


    See Stackblitz;

    For this post, I forked an Angular Components Stackblitz which uses Jasmine for the test,
    but in real I use Jest >= 29 and JSDom >= 26.

    • How do you trigger a scroll event so that I would be able to have other results in the await select.getOptions()?
    • Why do I have "e.scrollTo is not a function" console errors?

    I tried scrollViewPort.scrollable.scrollTo({ top: 8000 }); and also by dispatching a scroll event on the overlay, but without any success.

    Continue reading...

Compartilhe esta Página