mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-16 19:33:11 +02:00
Fix intermittently failing Playwright tests in main (#6541)
# Description of Changes [#6474](https://github.com/Stirling-Tools/Stirling-PDF/pull/6474) updated the IndexedDB schema number to v9, but a couple of Playwright tests were explicitly creating a DB in v4 schema, which then caused inconsistently failing tests because the DB upgrade process is asynchronous and sometimes was too slow to upgrade, causing the test to get into an invalid state. Also fixes the screenshots directory exclusion since the frontend folder was restructured.
This commit is contained in:
+1
-1
@@ -279,4 +279,4 @@ docs/type3/signatures/
|
|||||||
*.playwright-mcp.png
|
*.playwright-mcp.png
|
||||||
|
|
||||||
# Local screenshot artifacts from *-screenshots.spec.ts
|
# Local screenshot artifacts from *-screenshots.spec.ts
|
||||||
frontend/screenshots/
|
frontend/editor/screenshots/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { test, expect } from "@app/tests/helpers/stub-test-base";
|
import { test, expect } from "@app/tests/helpers/stub-test-base";
|
||||||
import type { Page, Route } from "@playwright/test";
|
import type { Page, Route } from "@playwright/test";
|
||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
|
import { DATABASE_CONFIGS } from "@app/services/indexedDBManager";
|
||||||
|
|
||||||
/** Screenshot review of /files surfaces; dumps PNGs to screenshots/files-page. */
|
/** Screenshot review of /files surfaces; dumps PNGs to screenshots/files-page. */
|
||||||
|
|
||||||
@@ -34,62 +35,69 @@ async function seedFiles(page: Page, files: SeedFile[]): Promise<void> {
|
|||||||
await page.route("**/api/v1/storage/files", (route: Route) =>
|
await page.route("**/api/v1/storage/files", (route: Route) =>
|
||||||
route.fulfill({ json: serverFiles }),
|
route.fulfill({ json: serverFiles }),
|
||||||
);
|
);
|
||||||
await page.addInitScript((records) => {
|
await page.addInitScript(
|
||||||
const open = window.indexedDB.open("stirling-pdf-files", 4);
|
({ records, dbVersion }) => {
|
||||||
open.onupgradeneeded = (event) => {
|
const open = window.indexedDB.open("stirling-pdf-files", dbVersion);
|
||||||
const db = (event.target as IDBOpenDBRequest).result;
|
open.onupgradeneeded = (event) => {
|
||||||
// Create both `files` and `folders` stores on this DB.
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
if (!db.objectStoreNames.contains("files")) {
|
// Create both `files` and `folders` stores on this DB.
|
||||||
const store = db.createObjectStore("files", { keyPath: "id" });
|
if (!db.objectStoreNames.contains("files")) {
|
||||||
store.createIndex("name", "name", { unique: false });
|
const store = db.createObjectStore("files", { keyPath: "id" });
|
||||||
store.createIndex("folderId", "folderId", { unique: false });
|
store.createIndex("name", "name", { unique: false });
|
||||||
store.createIndex("originalFileId", "originalFileId", {
|
store.createIndex("folderId", "folderId", { unique: false });
|
||||||
unique: false,
|
store.createIndex("originalFileId", "originalFileId", {
|
||||||
});
|
unique: false,
|
||||||
}
|
});
|
||||||
if (!db.objectStoreNames.contains("folders")) {
|
}
|
||||||
const fStore = db.createObjectStore("folders", { keyPath: "id" });
|
if (!db.objectStoreNames.contains("folders")) {
|
||||||
fStore.createIndex("parentFolderId", "parentFolderId", {
|
const fStore = db.createObjectStore("folders", { keyPath: "id" });
|
||||||
unique: false,
|
fStore.createIndex("parentFolderId", "parentFolderId", {
|
||||||
});
|
unique: false,
|
||||||
fStore.createIndex("name", "name", { unique: false });
|
});
|
||||||
}
|
fStore.createIndex("name", "name", { unique: false });
|
||||||
};
|
}
|
||||||
open.onsuccess = () => {
|
};
|
||||||
const db = open.result;
|
open.onsuccess = () => {
|
||||||
const tx = db.transaction("files", "readwrite");
|
const db = open.result;
|
||||||
const store = tx.objectStore("files");
|
// Yield the connection if the app ever needs to upgrade, and drop it
|
||||||
const now = Date.now();
|
// once the writes commit, so the seed never blocks the app's open.
|
||||||
for (const f of records) {
|
db.onversionchange = () => db.close();
|
||||||
store.put({
|
const tx = db.transaction("files", "readwrite");
|
||||||
id: f.id,
|
const store = tx.objectStore("files");
|
||||||
fileId: f.id,
|
const now = Date.now();
|
||||||
quickKey: f.id,
|
for (const f of records) {
|
||||||
name: f.name,
|
store.put({
|
||||||
type: "application/pdf",
|
id: f.id,
|
||||||
size: 1024,
|
fileId: f.id,
|
||||||
lastModified: now,
|
quickKey: f.id,
|
||||||
createdAt: now,
|
name: f.name,
|
||||||
data: new ArrayBuffer(8),
|
type: "application/pdf",
|
||||||
thumbnail: null,
|
size: 1024,
|
||||||
isLeaf: true,
|
lastModified: now,
|
||||||
versionNumber: 1,
|
createdAt: now,
|
||||||
originalFileId: f.id,
|
data: new ArrayBuffer(8),
|
||||||
parentFileId: null,
|
thumbnail: null,
|
||||||
toolHistory: [],
|
isLeaf: true,
|
||||||
folderId: f.folderId ?? null,
|
versionNumber: 1,
|
||||||
remoteStorageId: f.remoteStorageId,
|
originalFileId: f.id,
|
||||||
remoteStorageUpdatedAt: f.remoteStorageId ? now : null,
|
parentFileId: null,
|
||||||
remoteOwnerUsername: f.remoteStorageId ? "testuser" : null,
|
toolHistory: [],
|
||||||
remoteOwnedByCurrentUser: f.remoteStorageId ? true : null,
|
folderId: f.folderId ?? null,
|
||||||
remoteAccessRole: f.remoteStorageId ? "owner" : null,
|
remoteStorageId: f.remoteStorageId,
|
||||||
remoteSharedViaLink: false,
|
remoteStorageUpdatedAt: f.remoteStorageId ? now : null,
|
||||||
remoteHasShareLinks: false,
|
remoteOwnerUsername: f.remoteStorageId ? "testuser" : null,
|
||||||
remoteShareToken: null,
|
remoteOwnedByCurrentUser: f.remoteStorageId ? true : null,
|
||||||
});
|
remoteAccessRole: f.remoteStorageId ? "owner" : null,
|
||||||
}
|
remoteSharedViaLink: false,
|
||||||
};
|
remoteHasShareLinks: false,
|
||||||
}, files);
|
remoteShareToken: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tx.oncomplete = () => db.close();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ records: files, dbVersion: DATABASE_CONFIGS.FILES.version },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stubStorageApis(
|
async function stubStorageApis(
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { test, expect } from "@app/tests/helpers/stub-test-base";
|
import { test, expect } from "@app/tests/helpers/stub-test-base";
|
||||||
import type { Page, Route } from "@playwright/test";
|
import type { Page, Route } from "@playwright/test";
|
||||||
|
import { DATABASE_CONFIGS } from "@app/services/indexedDBManager";
|
||||||
|
|
||||||
/** Stubbed coverage for the /files page UI invariants. */
|
/** Stubbed coverage for the /files page UI invariants. */
|
||||||
|
|
||||||
@@ -34,63 +35,70 @@ async function seedFiles(page: Page, files: SeedFile[]): Promise<void> {
|
|||||||
await page.route("**/api/v1/storage/files", (route: Route) =>
|
await page.route("**/api/v1/storage/files", (route: Route) =>
|
||||||
route.fulfill({ json: serverFiles }),
|
route.fulfill({ json: serverFiles }),
|
||||||
);
|
);
|
||||||
await page.addInitScript((records) => {
|
await page.addInitScript(
|
||||||
const open = window.indexedDB.open("stirling-pdf-files", 4);
|
({ records, dbVersion }) => {
|
||||||
open.onupgradeneeded = (event) => {
|
const open = window.indexedDB.open("stirling-pdf-files", dbVersion);
|
||||||
const db = (event.target as IDBOpenDBRequest).result;
|
open.onupgradeneeded = (event) => {
|
||||||
// Create both `files` and `folders` stores on this DB.
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
if (!db.objectStoreNames.contains("files")) {
|
// Create both `files` and `folders` stores on this DB.
|
||||||
const store = db.createObjectStore("files", { keyPath: "id" });
|
if (!db.objectStoreNames.contains("files")) {
|
||||||
store.createIndex("name", "name", { unique: false });
|
const store = db.createObjectStore("files", { keyPath: "id" });
|
||||||
store.createIndex("folderId", "folderId", { unique: false });
|
store.createIndex("name", "name", { unique: false });
|
||||||
store.createIndex("originalFileId", "originalFileId", {
|
store.createIndex("folderId", "folderId", { unique: false });
|
||||||
unique: false,
|
store.createIndex("originalFileId", "originalFileId", {
|
||||||
});
|
unique: false,
|
||||||
}
|
});
|
||||||
if (!db.objectStoreNames.contains("folders")) {
|
}
|
||||||
const fStore = db.createObjectStore("folders", { keyPath: "id" });
|
if (!db.objectStoreNames.contains("folders")) {
|
||||||
fStore.createIndex("parentFolderId", "parentFolderId", {
|
const fStore = db.createObjectStore("folders", { keyPath: "id" });
|
||||||
unique: false,
|
fStore.createIndex("parentFolderId", "parentFolderId", {
|
||||||
});
|
unique: false,
|
||||||
fStore.createIndex("name", "name", { unique: false });
|
});
|
||||||
}
|
fStore.createIndex("name", "name", { unique: false });
|
||||||
};
|
}
|
||||||
open.onsuccess = () => {
|
};
|
||||||
const db = open.result;
|
open.onsuccess = () => {
|
||||||
const tx = db.transaction("files", "readwrite");
|
const db = open.result;
|
||||||
const store = tx.objectStore("files");
|
// Yield the connection if the app ever needs to upgrade, and drop it
|
||||||
const now = Date.now();
|
// once the writes commit, so the seed never blocks the app's open.
|
||||||
for (const f of records) {
|
db.onversionchange = () => db.close();
|
||||||
store.put({
|
const tx = db.transaction("files", "readwrite");
|
||||||
id: f.id,
|
const store = tx.objectStore("files");
|
||||||
fileId: f.id,
|
const now = Date.now();
|
||||||
quickKey: f.id,
|
for (const f of records) {
|
||||||
name: f.name,
|
store.put({
|
||||||
type: "application/pdf",
|
id: f.id,
|
||||||
size: 1024,
|
fileId: f.id,
|
||||||
lastModified: now,
|
quickKey: f.id,
|
||||||
createdAt: now,
|
name: f.name,
|
||||||
// Placeholder; opening would need real bytes.
|
type: "application/pdf",
|
||||||
data: new ArrayBuffer(8),
|
size: 1024,
|
||||||
thumbnail: null,
|
lastModified: now,
|
||||||
isLeaf: true,
|
createdAt: now,
|
||||||
versionNumber: f.versionNumber ?? 1,
|
// Placeholder; opening would need real bytes.
|
||||||
originalFileId: f.id,
|
data: new ArrayBuffer(8),
|
||||||
parentFileId: null,
|
thumbnail: null,
|
||||||
toolHistory: f.toolHistory ?? [],
|
isLeaf: true,
|
||||||
folderId: null,
|
versionNumber: f.versionNumber ?? 1,
|
||||||
remoteStorageId: f.remoteStorageId,
|
originalFileId: f.id,
|
||||||
remoteStorageUpdatedAt: f.remoteStorageId ? now : null,
|
parentFileId: null,
|
||||||
remoteOwnerUsername: f.remoteStorageId ? "testuser" : null,
|
toolHistory: f.toolHistory ?? [],
|
||||||
remoteOwnedByCurrentUser: f.remoteStorageId ? true : null,
|
folderId: null,
|
||||||
remoteAccessRole: f.remoteStorageId ? "owner" : null,
|
remoteStorageId: f.remoteStorageId,
|
||||||
remoteSharedViaLink: false,
|
remoteStorageUpdatedAt: f.remoteStorageId ? now : null,
|
||||||
remoteHasShareLinks: false,
|
remoteOwnerUsername: f.remoteStorageId ? "testuser" : null,
|
||||||
remoteShareToken: null,
|
remoteOwnedByCurrentUser: f.remoteStorageId ? true : null,
|
||||||
});
|
remoteAccessRole: f.remoteStorageId ? "owner" : null,
|
||||||
}
|
remoteSharedViaLink: false,
|
||||||
};
|
remoteHasShareLinks: false,
|
||||||
}, files);
|
remoteShareToken: null,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
tx.oncomplete = () => db.close();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
{ records: files, dbVersion: DATABASE_CONFIGS.FILES.version },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stub the storage + config endpoints hit on mount. */
|
/** Stub the storage + config endpoints hit on mount. */
|
||||||
|
|||||||
Reference in New Issue
Block a user