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

Code before:
      const content = await page.locator('ion-modal ion-content');
      await dragElementBy(content, page, 0, 500);

      await ionModalDidDismiss.next();
    });
    test('it should not swipe to close when swiped on the content but the content is scrolled', async ({ page }) => {
      const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');

      await page.click('#card');
      await ionModalDidPresent.next();

      const modal = await page.locator('ion-modal');
      const content = (await page.$('ion-modal ion-content'))!;

      await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));

      await dragElementBy(content, page, 0, 500);

      await content.waitForElementState('stable');

      expect(modal).toBeVisible();
    });
    test('content should be scrollable after gesture ends', async ({ page }) => {
      const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');

      await page.click('#card');
      await ionModalDidPresent.next();

      const content = await page.locator('ion-modal ion-content');
      await dragElementBy(content, page, 0, 20);

      expect(content).toHaveJSProperty('scrollY', true);
    });
  });
  test.describe('card modal: rendering - tablet', () => {
    test.beforeEach(async ({ page }) => {
      await page.setViewportSize(TabletViewport);
    });
    test('should not have visual regressions', async ({ page }) => {
      const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');

      await page.click('#card');

      await ionModalDidPresent.next();

      expect(await page.screenshot()).toMatchSnapshot(`modal-card-present-tablet-${page.getSnapshotSettings()}.png`);
    });
    test('should not have visual regressions with custom modal', async ({ page }) => {
      const ionModalDidPresent = await page.spyOnEvent('ionModalDidPresent');

      await page.click('#card-custom');

Review comment (refactor):
Would it be possible to bring these tests into a helper method so we don't have so much repeated code? Ditto for the other tests where tablet versions have been added, but especially this one since it has so many `test` calls and may have more added later.

Code after:
      await cardModalPage.swipeToCloseModal('ion-modal ion-header');
    });
    test('it should swipe to close when swiped on the content', async () => {
      await cardModalPage.openModalByTrigger('#card');
      await cardModalPage.swipeToCloseModal('ion-modal ion-content');
    });
    test('it should not swipe to close when swiped on the content but the content is scrolled', async ({ page }) => {
      const modal = await cardModalPage.openModalByTrigger('#card');

      const content = (await page.$('ion-modal ion-content'))!;
      await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom(0));

      await cardModalPage.swipeToCloseModal('ion-modal ion-content', false);

      await content.waitForElementState('stable');
      expect(modal).toBeVisible();
    });
    test('content should be scrollable after gesture ends', async ({ page }) => {
      await cardModalPage.openModalByTrigger('#card');
      await cardModalPage.swipeToCloseModal('ion-modal ion-content', false, 20);

      const content = await page.locator('ion-modal ion-content');
      expect(content).toHaveJSProperty('scrollY', true);
    });
  });
  test.describe('card modal: rendering - tablet', () => {
    test.beforeEach(async ({ page }) => {
      await page.setViewportSize(Viewports.tablet.portrait);
    });
    test('should not have visual regressions', async ({ page }) => {
      await cardModalPage.openModalByTrigger('#card');

      expect(await page.screenshot()).toMatchSnapshot(`modal-card-present-tablet-${page.getSnapshotSettings()}.png`);
    });
    test('should not have visual regressions with custom modal', async ({ page }) => {
      await cardModalPage.openModalByTrigger('#card-custom');

      expect(await page.screenshot()).toMatchSnapshot(
        `modal-card-custom-present-tablet-${page.getSnapshotSettings()}.png`
      );
    });
    test('should not have visual regressions with stacked cards', async ({ page }) => {
      await cardModalPage.openModalByTrigger('#card');
      await cardModalPage.openModalByTrigger('.add');

      expect(await page.screenshot()).toMatchSnapshot(
        `modal-card-stacked-present-tablet-${page.getSnapshotSettings()}.png`
      );
    });
    test('should not have visual regressions with stacked custom cards', async ({ page }) => {
      await cardModalPage.openModalByTrigger('#card-custom');