Merge branch 'test/webkit-idb-blob-limitation'

This commit is contained in:
fabi
2026-07-28 19:14:37 +02:00
4 changed files with 40 additions and 0 deletions

29
e2e/helpers/webkit.ts Normal file
View File

@@ -0,0 +1,29 @@
import { test } from '@playwright/test';
/**
* Skip a test that depends on persisting a Blob/File in IndexedDB when running on
* Playwright's WebKit.
*
* The client upload queue (`frontend/src/lib/upload-queue.ts`) stores the file itself in
* IndexedDB so a backgrounded or reloaded phone can resume the upload. Playwright's Linux
* WebKit build cannot store Blobs in IndexedDB at all — `put()` fails with
* "UnknownError: Error preparing Blob/File data to be stored in object store". Verified to
* be the harness, not the app: a Blob constructed in-page with `new Blob([bytes])` fails
* exactly the same way, while Chromium stores both that and a `setInputFiles` File fine.
* Real iOS Safari supports Blobs in IndexedDB, so this is NOT evidence of a bug on the
* platform these tests exist to protect.
*
* Any test that drives the composer (FAB → UploadSheet → /upload → submit) hits this,
* because `handleSubmit` awaits `addToQueue`, which throws before it can navigate.
*
* This is deliberately narrow. WebKit still runs every API-driven upload test, the whole of
* 01-auth, 03-feed and 06-export — including the keepsake download, which only WebKit can
* meaningfully verify. If Playwright's WebKit ever gains IndexedDB Blob support, delete this
* helper and the four call sites.
*/
export function skipIfNoIdbBlobs(browserName: string) {
test.skip(
browserName === 'webkit',
"Playwright's Linux WebKit cannot store Blobs in IndexedDB (harness limitation, not an iOS one) — the client upload queue can't be exercised there"
);
}

View File

@@ -26,6 +26,7 @@
* large fixture files. * large fixture files.
*/ */
import { test, expect } from '../../fixtures/test'; import { test, expect } from '../../fixtures/test';
import { skipIfNoIdbBlobs } from '../../helpers/webkit';
import { FeedPage, UploadSheet } from '../../page-objects'; import { FeedPage, UploadSheet } from '../../page-objects';
import { mkdtempSync, copyFileSync, rmSync } from 'node:fs'; import { mkdtempSync, copyFileSync, rmSync } from 'node:fs';
import { join } from 'node:path'; import { join } from 'node:path';
@@ -100,7 +101,9 @@ test.describe('Upload — client queue under a burst', () => {
guest, guest,
signIn, signIn,
db, db,
browserName,
}) => { }) => {
skipIfNoIdbBlobs(browserName);
const g = await guest('BurstSerial'); const g = await guest('BurstSerial');
await signIn(page, g); await signIn(page, g);
await warmUploadChunk(page); await warmUploadChunk(page);
@@ -163,7 +166,9 @@ test.describe('Upload — client queue under a burst', () => {
guest, guest,
signIn, signIn,
db, db,
browserName,
}) => { }) => {
skipIfNoIdbBlobs(browserName);
const g = await guest('BurstResume'); const g = await guest('BurstResume');
await signIn(page, g); await signIn(page, g);
await warmUploadChunk(page); await warmUploadChunk(page);

View File

@@ -4,6 +4,7 @@
* IndexedDB queue resumption after refresh, and SSE `upload-processed`. * IndexedDB queue resumption after refresh, and SSE `upload-processed`.
*/ */
import { test, expect } from '../../fixtures/test'; import { test, expect } from '../../fixtures/test';
import { skipIfNoIdbBlobs } from '../../helpers/webkit';
import { FeedPage, UploadSheet } from '../../page-objects'; import { FeedPage, UploadSheet } from '../../page-objects';
import { SseListener } from '../../helpers/sse-listener'; import { SseListener } from '../../helpers/sse-listener';
import { join } from 'node:path'; import { join } from 'node:path';
@@ -49,7 +50,9 @@ test.describe('Upload — gallery path', () => {
guest, guest,
signIn, signIn,
db, db,
browserName,
}) => { }) => {
skipIfNoIdbBlobs(browserName);
// Previously fixme'd: the UI queue never fired a POST. Root cause was NOT a // Previously fixme'd: the UI queue never fired a POST. Root cause was NOT a
// navigation/blob timing quirk but an IndexedDB upgrade bug — the v1→v2 // navigation/blob timing quirk but an IndexedDB upgrade bug — the v1→v2
// `upgrade` callback opened a *new* transaction, which throws during a // `upgrade` callback opened a *new* transaction, which throws during a

View File

@@ -13,6 +13,7 @@
* queue row, no error text, and it never appeared in the feed. * queue row, no error text, and it never appeared in the feed.
*/ */
import { test, expect } from '../../fixtures/test'; import { test, expect } from '../../fixtures/test';
import { skipIfNoIdbBlobs } from '../../helpers/webkit';
import { FeedPage, UploadSheet } from '../../page-objects'; import { FeedPage, UploadSheet } from '../../page-objects';
import { join } from 'node:path'; import { join } from 'node:path';
@@ -25,7 +26,9 @@ test.describe('Upload — a rejected upload is surfaced', () => {
host, host,
guest, guest,
signIn, signIn,
browserName,
}) => { }) => {
skipIfNoIdbBlobs(browserName);
const g = await guest('RejectedUploader'); const g = await guest('RejectedUploader');
await signIn(page, g); await signIn(page, g);