import type { Page, Locator } from '@playwright/test'; /** * UploadSheet — the bottom-sheet UploadSheet.svelte + the `/upload` preview * page. Camera button is only useful on Chromium because fake-media is a * Chromium-only launch flag. * * Note on the actual flow: tapping the FAB opens UploadSheet.svelte; tapping * "Galerie" inside it opens the native file picker which sets the staged * files into the pending-upload-store; the app then navigates to /upload * where the user can edit the caption and submit. */ export class UploadSheet { readonly page: Page; readonly fileInput: Locator; readonly cameraButton: Locator; readonly galleryButton: Locator; readonly captionInput: Locator; readonly submitButton: Locator; constructor(page: Page) { this.page = page; // The file input lives inside the UploadSheet bottom sheet AND inside the // /upload preview page. Both work with setInputFiles. `.first()` keeps strict // mode happy when both happen to exist mid-transition. this.fileInput = page.locator('input[type="file"]').first(); this.cameraButton = page.getByRole('button', { name: /kamera/i }); this.galleryButton = page.getByRole('button', { name: /galerie/i }); this.captionInput = page.getByTestId('upload-caption'); this.submitButton = page.getByTestId('upload-submit'); } /** Stage one or more files via the hidden file input — bypasses the native picker. */ async stageFiles(paths: string[]) { await this.fileInput.setInputFiles(paths); } async fillCaption(caption: string) { await this.captionInput.fill(caption); } async submit() { await this.submitButton.click(); } /** Helper: open sheet, stage one file, fill caption, submit. Returns when navigation back to feed completes. */ async uploadOne(page: Page, filePath: string, caption = '') { await this.stageFiles([filePath]); // The app may auto-navigate to /upload; wait for the caption editor to be ready. await this.captionInput.waitFor({ state: 'visible', timeout: 10_000 }); if (caption) await this.fillCaption(caption); await this.submit(); await page.waitForURL('**/feed', { timeout: 15_000 }); } }