diff --git a/e2e/src/tests/mobile/gesture/mobile-gesture.spec.ts b/e2e/src/tests/mobile/gesture/mobile-gesture.spec.ts new file mode 100644 index 0000000..532bc6f --- /dev/null +++ b/e2e/src/tests/mobile/gesture/mobile-gesture.spec.ts @@ -0,0 +1,144 @@ +import { test, expect } from '@playwright/test'; +import { GestureSimulator } from '../../../utils/GestureSimulator'; + +test.describe('移动端手势交互测试 @mobile @gesture', () => { + test('滑动 - 页面滚动', async ({ page }) => { + await page.setViewportSize({ width: 375, height: 667 }); + await page.goto('/'); + + const simulator = new GestureSimulator(page); + + const initialScrollY = await page.evaluate(() => window.scrollY); + expect(initialScrollY).toBe(0); + + await simulator.slowSwipeUp(); + + const afterScrollY = await page.evaluate(() => window.scrollY); + expect(afterScrollY).toBeGreaterThan(0); + }); + + test('滑动 - 快速向下滑动', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto('/'); + + await page.evaluate(() => { + window.scrollTo(0, 1000); + }); + + const simulator = new GestureSimulator(page); + const initialScrollY = await page.evaluate(() => window.scrollY); + + await simulator.quickSwipeDown(); + + const afterScrollY = await page.evaluate(() => window.scrollY); + expect(afterScrollY).toBeLessThan(initialScrollY); + }); + + test('长按 - 元素上下文菜单', async ({ page }) => { + await page.setViewportSize({ width: 414, height: 896 }); + await page.goto('/'); + + const simulator = new GestureSimulator(page); + const card = page.locator('.card').first(); + + await expect(card).toBeVisible(); + await simulator.longPress(card, 1000); + + await expect(card).toBeVisible(); + }); + + test('双击 - 图片放大', async ({ page }) => { + await page.setViewportSize({ width: 375, height: 667 }); + await page.goto('/products'); + + const simulator = new GestureSimulator(page); + const image = page.locator('.product-image').first(); + + await expect(image).toBeVisible(); + await simulator.doubleTap(image); + + await expect(image).toBeVisible(); + }); + + test('拖拽 - 元素移动', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto('/products'); + + const simulator = new GestureSimulator(page); + const firstCard = page.locator('.card').first(); + const secondCard = page.locator('.card').nth(1); + + const firstCardInitialPosition = await firstCard.boundingBox(); + + await simulator.drag({ + source: firstCard, + target: secondCard, + duration: 500, + }); + + const firstCardFinalPosition = await firstCard.boundingBox(); + + if (firstCardInitialPosition && firstCardFinalPosition) { + expect(firstCardFinalPosition.y).toBeGreaterThan(firstCardInitialPosition.y); + } + }); + + test('捏合 - 图片缩放', async ({ page }) => { + await page.setViewportSize({ width: 414, height: 896 }); + await page.goto('/products'); + + const simulator = new GestureSimulator(page); + const image = page.locator('.product-image').first(); + + await image.click(); + + await simulator.pinch({ + centerX: 200, + centerY: 300, + startDistance: 100, + endDistance: 50, + duration: 300, + }); + + const transform = await image.evaluate((el) => { + const style = window.getComputedStyle(el); + return style.transform; + }); + + expect(transform).toBeTruthy(); + }); + + test('组合手势 - 滑动后点击', async ({ page }) => { + await page.setViewportSize({ width: 375, height: 667 }); + await page.goto('/'); + + const simulator = new GestureSimulator(page); + + await simulator.slowSwipeUp(); + + const button = page.locator('button').first(); + await expect(button).toBeVisible(); + + await button.tap(); + }); + + test('手势 - 横向滑动', async ({ page }) => { + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto('/'); + + const simulator = new GestureSimulator(page); + + const initialScrollX = await page.evaluate(() => window.scrollX); + + await simulator.swipe({ + startX: 300, + startY: 400, + endX: 100, + endY: 400, + duration: 500, + }); + + const afterScrollX = await page.evaluate(() => window.scrollX); + expect(afterScrollX).toBeGreaterThan(initialScrollX); + }); +}); \ No newline at end of file