Repository: ionic-team/ionic-framework
File: core/src/components/refresher/test/basic/refresher.e2e.ts (TypeScript)

Code before:

        await pullToRefresh(page);

        expect(await items.count()).toBe(60);
      });

      test('should emit ionPullStart and ionPullEnd with reason complete', async ({ page }) => {
        await page.locator('ion-refresher.hydrated').waitFor({ state: 'attached' });

        const ionPullStartEvent = await page.spyOnEvent('ionPullStartFired');
        const ionPullEndEvent = await page.spyOnEvent('ionPullEndFired');

        await pullToRefresh(page);

        // Wait for the close animation timeout (600ms) to complete
        await page.waitForTimeout(700);

        expect(ionPullStartEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventDetail({ reason: 'complete' });
      });

      test('should emit ionPullEnd with reason cancel when pull is released early', async ({ page }) => {
        const target = page.locator('body');

        await page.locator('ion-refresher.hydrated').waitFor({ state: 'attached' });

        const ionPullStartEvent = await page.spyOnEvent('ionPullStartFired');
        const ionPullEndEvent = await page.spyOnEvent('ionPullEndFired');

        // Pull down only 40px (less than pullMin of 60px) to trigger cancel
        await dragElementByYAxis(target, page, 40);

        // Wait for the cancel animation to complete
        await page.waitForTimeout(700);

        expect(ionPullStartEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventDetail({ reason: 'cancel' });
      });
    });

    test.describe('native refresher', () => {
      test('should load more items when performing a pull-to-refresh', async ({ page }) => {
        const refresherContent = page.locator('ion-refresher-content');
        refresherContent.evaluateHandle((el: any) => {
          // Resets the pullingIcon to enable the native refresher
          el.pullingIcon = undefined;
        });

        await page.waitForChanges();

Review comment (suggestion):
Same [question](https://github.com/ionic-team/ionic-framework/pull/30946/changes#r2783854946) applies here.

Code after:

        await pullToRefresh(page);

        expect(await items.count()).toBe(60);
      });

      test('should emit ionPullStart and ionPullEnd with reason complete', async ({ page }) => {
        const ionPullStartEvent = await page.spyOnEvent('ionPullStartFired');
        const ionPullEndEvent = await page.spyOnEvent('ionPullEndFired');

        await pullToRefresh(page);

        // Wait for the close animation to complete
        await page.waitForTimeout(700);

        expect(ionPullStartEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventDetail({ reason: 'complete' });
      });

      test('should emit ionPullEnd with reason cancel when pull is released early', async ({ page }) => {
        const target = page.locator('body');

        const ionPullStartEvent = await page.spyOnEvent('ionPullStartFired');
        const ionPullEndEvent = await page.spyOnEvent('ionPullEndFired');

        // Pull down only 40px (less than pullMin of 60px) to trigger cancel
        await dragElementByYAxis(target, page, 40);

        // Wait for the cancel animation to complete
        await page.waitForTimeout(700);

        expect(ionPullStartEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventTimes(1);
        expect(ionPullEndEvent).toHaveReceivedEventDetail({ reason: 'cancel' });
      });
    });

    test.describe('native refresher', () => {
      test('should load more items when performing a pull-to-refresh', async ({ page }) => {
        const refresherContent = page.locator('ion-refresher-content');
        refresherContent.evaluateHandle((el: any) => {
          // Resets the pullingIcon to enable the native refresher
          el.pullingIcon = undefined;
        });

        await page.waitForChanges();

        const items = page.locator('ion-item');
        expect(await items.count()).toBe(30);