1import { expect, test } from "@playwright/test"
2
3import {
4 canvasChecksum,
5 masukHias,
6 masukHiasDenganQr,
7 matikanGesture,
8} from "./helpers"
9
10/* M6 (SH-04 sampai SH-06): link strip dan QR. Server tidak lagi menyimpan
11 apa pun (backend Cloudflare dibongkar), jadi spek ini memeriksa sakelar QR,
12 kartu bagikan, jalur "belum tersedia" dari rute yang selalu 503, dan
13 halaman strip yang selalu 404. */
14
15/* Konvensi yang sama dengan spek lain (lihat helpers.ts): Gesture Snap
16 dimatikan lewat localStorage. Di Chromium headless tanpa GPU, inferensi
17 MediaPipe menahan main thread beberapa ratus milidetik per bingkai, dan alur
18 kamera empat foto di berkas ini bisa melewati batas 30 detik uji saat mesin
19 sedang sibuk. Perilaku gesture sendiri diuji `gesture.spec.ts`. */
20test.beforeEach(async ({ page }) => {
21 await matikanGesture(page)
22})
23
24test.describe("QR di strip", () => {
25 test("sakelar QR menyalakan kotak QR di kanvas dan pemberitahuan izin", async ({
26 page,
27 }) => {
28 await masukHias(page)
29 const sebelum = await canvasChecksum(page)
30
31 const sakelar = page.getByRole("switch", { name: "QR di strip" })
32 await expect(sakelar).not.toBeChecked()
33 await sakelar.click()
34 await expect(sakelar).toBeChecked()
35 await expect(
36 page.getByText("Kamu akan dimintai izin unggah saat mengunduh.")
37 ).toBeVisible()
38 /* Kanvas digambar ulang setelah state berubah, jadi kotak QR-nya ditunggu
39 (M9: penggambaran ulang tidak sinkron dengan klik di server produksi). */
40 await expect.poll(() => canvasChecksum(page)).not.toBe(sebelum)
41
42 /* Ledakan kartu mengikuti teks acuan customize.html. */
43 await expect(
44 page.getByText(
45 "QR membuka halaman strip. Fotomu diunggah ke link pribadi dan terhapus otomatis setelah 7 hari."
46 )
47 ).toBeVisible()
48
49 await sakelar.click()
50 await expect(
51 page.getByText("Kamu akan dimintai izin unggah saat mengunduh.")
52 ).toHaveCount(0)
53 })
54
55 test("persetujuan unggah muncul dan server tanpa env menjawab belum tersedia", async ({
56 page,
57 }) => {
58 await masukHiasDenganQr(page)
59 await page.getByRole("link", { name: "Selesai & Unduh" }).click()
60 await page.waitForURL("**/booth/result")
61 await expect(page.getByAltText("Pratinjau strip")).toBeVisible()
62
63 await expect(page.getByText("Semua diproses di perangkat ini")).toBeVisible()
64 await page.getByRole("button", { name: "Buat Link dan Unggah" }).click()
65
66 /* SE-02: apa yang diunggah, siapa yang bisa melihat, kapan terhapus. */
67 const dialog = page.getByRole("dialog")
68 await expect(
69 dialog.getByText("Unggah strip?", { exact: true })
70 ).toBeVisible()
71 await expect(
72 dialog.getByText(/Siapa pun yang punya link bisa melihatnya sampai 7 hari/)
73 ).toBeVisible()
74
75 await page
76 .getByRole("dialog")
77 .getByRole("button", { name: "Buat Link dan Unggah" })
78 .click()
79 await expect(page.getByText("Pembuatan link belum tersedia.")).toBeVisible()
80 /* Gagal berarti belum ada yang terunggah, jadi tawaran unggah tetap ada. */
81 await expect(
82 page.getByRole("button", { name: "Buat Link dan Unggah" })
83 ).toBeVisible()
84 })
85
86 test("halaman strip yang tidak ada menjawab 404 dan tidak diindeks", async ({
87 page,
88 }) => {
89 const response = await page.goto("/s/tidakada1234")
90 expect(response?.status()).toBe(404)
91 await expect(page.getByText("Halaman tidak ditemukan.")).toBeVisible()
92 await expect(
93 page.getByRole("link", { name: "Mulai Foto" })
94 ).toBeVisible()
95 })
96})
97