diff --git a/packages/test-flicking/e2e/tests/basic/threshold/threshold.spec.ts b/packages/test-flicking/e2e/tests/basic/threshold/threshold.spec.ts index b6f4857c0..205d78de4 100644 --- a/packages/test-flicking/e2e/tests/basic/threshold/threshold.spec.ts +++ b/packages/test-flicking/e2e/tests/basic/threshold/threshold.spec.ts @@ -5,6 +5,16 @@ import { loadSpec } from "../../helpers/spec-loader"; const spec = loadSpec("basic/threshold"); +/** 데모의 인스턴스 순서 = threshold 값 */ +const LOW = 0; // threshold: 10 +const DEFAULT = 1; // threshold: 40 +const HIGH = 2; // threshold: 100 + +/** threshold:100 미만이면서 10/40은 넘는 거리 */ +const SHORT_DRAG = 50; +/** 세 인스턴스의 threshold를 모두 넘는 거리 */ +const LONG_DRAG = 150; + for (const framework of spec.frameworks) { test.describe(`${spec.id} [${framework}]`, () => { test.beforeEach(async ({ page }) => { @@ -12,24 +22,51 @@ for (const framework of spec.frameworks) { await waitForFlickingReady(page); }); - test("3개 인스턴스 렌더링 및 threshold 옵션 확인", async ({ page }) => { - const thresholds = await page.evaluate(() => { - return (window as any).__flickingInstances.map((f: any) => f.threshold); - }); + // focus: threshold가 다른 3개 인스턴스(10/40/100)가 렌더링된다 + test("threshold 10/40/100 인스턴스 렌더링", async ({ page }) => { + await expect(page.locator(".flicking-viewport")).toHaveCount(3); + + const thresholds = await page.evaluate(() => (window as any).__flickingInstances.map((f: any) => f.threshold)); expect(thresholds).toEqual([10, 40, 100]); }); - test("threshold:100에서 짧은 드래그는 패널 이동 안 됨", async ({ page }) => { - // 50px 짧은 드래그 → threshold:100에는 부족 - await dragLeft(page, { nth: 2, instanceIndex: 2, distance: 50 }); - const state = await getFlickingState(page, 2); + // focus: threshold 미만으로 드래그하면 패널이 바뀌지 않고 원래 패널로 되돌아온다 + test("threshold 미만 드래그는 원래 패널로 복귀", async ({ page }) => { + await dragLeft(page, { nth: HIGH, instanceIndex: HIGH, distance: SHORT_DRAG }); + + const state = await getFlickingState(page, HIGH); expect(state.currentIndex).toBe(0); + // 복귀 애니메이션까지 끝나 카메라가 원래 패널에 정확히 정렬되어야 한다 + expect(state.animating).toBe(false); }); - test("threshold:10에서 짧은 드래그로 패널 이동", async ({ page }) => { - await dragLeft(page, { nth: 0, instanceIndex: 0, distance: 50 }); - const state = await getFlickingState(page, 0); - expect(state.currentIndex).toBeGreaterThan(0); + // focus: threshold 이상으로 드래그하면 인접 패널로 이동한다 + test("threshold 이상 드래그는 인접 패널로 이동", async ({ page }) => { + await dragLeft(page, { nth: HIGH, instanceIndex: HIGH, distance: LONG_DRAG }); + + const state = await getFlickingState(page, HIGH); + expect(state.currentIndex).toBe(1); + }); + + // focus: 같은 거리를 드래그해도 threshold가 큰 인스턴스는 이동하지 않는다 + test(`같은 ${SHORT_DRAG}px 드래그에서 threshold 10/40만 이동`, async ({ page }) => { + for (const idx of [LOW, DEFAULT, HIGH]) { + await dragLeft(page, { nth: idx, instanceIndex: idx, distance: SHORT_DRAG }); + } + + const indices = await Promise.all( + [LOW, DEFAULT, HIGH].map(async idx => (await getFlickingState(page, idx)).currentIndex) + ); + expect(indices).toEqual([1, 1, 0]); + }); + + // focus: 되돌아온 인스턴스도 이후 충분한 드래그에는 정상적으로 이동한다 + test("복귀 후에도 충분한 드래그에는 정상 이동", async ({ page }) => { + await dragLeft(page, { nth: HIGH, instanceIndex: HIGH, distance: SHORT_DRAG }); + expect((await getFlickingState(page, HIGH)).currentIndex).toBe(0); + + await dragLeft(page, { nth: HIGH, instanceIndex: HIGH, distance: LONG_DRAG }); + expect((await getFlickingState(page, HIGH)).currentIndex).toBe(1); }); }); } diff --git a/packages/test-flicking/e2e/tests/basic/threshold/threshold.yaml b/packages/test-flicking/e2e/tests/basic/threshold/threshold.yaml index 4ef628923..cc53232d3 100644 --- a/packages/test-flicking/e2e/tests/basic/threshold/threshold.yaml +++ b/packages/test-flicking/e2e/tests/basic/threshold/threshold.yaml @@ -2,14 +2,22 @@ id: threshold category: basic demo: basic/Threshold -intent: "threshold 옵션으로 패널 이동에 필요한 최소 드래그 거리를 조절할 수 있음을 보여준다" +intent: "threshold 옵션으로 패널을 넘기는 데 필요한 최소 드래그 거리를 조절할 수 있음을 보여준다" focus: - - 3개의 Flicking 인스턴스가 렌더링됨 (10/40/100) - - threshold:100 인스턴스에서 짧은 드래그는 패널 이동 안 됨 - - threshold:10 인스턴스에서 짧은 드래그로도 패널 이동 + - threshold가 다른 3개 인스턴스(10/40/100)가 렌더링된다 + - threshold 미만으로 드래그하면 패널이 바뀌지 않고 원래 패널로 되돌아온다 + - threshold 이상으로 드래그하면 인접 패널로 이동한다 + - 같은 거리를 드래그해도 threshold가 큰 인스턴스는 이동하지 않는다 + - 되돌아온 인스턴스도 이후 충분한 드래그에는 정상적으로 이동한다 api: options: [threshold] frameworks: [vanilla, react, vue] + +limitations: + # SnapControl.moveToPosition은 raw 드래그 거리가 아니라 릴리스 시점의 관성이 실린 + # delta를 threshold와 비교한다. 따라서 임계값 바로 근처(예: threshold 100에 99px)는 + # 드래그 속도에 따라 결과가 갈리므로 단언하지 않고, 여유를 둔 거리로만 검증한다. + - "임계값 경계(±10px 이내)는 드래그 속도에 따라 결과가 달라져 검증 대상에서 제외"