All checks were successful
Build & Deploy Costco Grocery List / build (push) Successful in 1m36s
Build & Deploy Costco Grocery List / verify-images (push) Successful in 2s
Build & Deploy Costco Grocery List / deploy (push) Successful in 8s
Build & Deploy Costco Grocery List / notify (push) Successful in 0s
121 lines
3.1 KiB
TypeScript
121 lines
3.1 KiB
TypeScript
import { expect, type Page } from "@playwright/test";
|
|
|
|
type AuthSeed = {
|
|
token?: string;
|
|
userId?: string;
|
|
role?: string;
|
|
username?: string;
|
|
};
|
|
|
|
type HouseholdSeed = {
|
|
id?: number;
|
|
name?: string;
|
|
role?: string;
|
|
invite_code?: string;
|
|
};
|
|
|
|
type StoreSeed = {
|
|
id?: number;
|
|
name?: string;
|
|
location?: string;
|
|
is_default?: boolean;
|
|
};
|
|
|
|
const defaultConfig = {
|
|
maxFileSizeMB: 20,
|
|
maxImageDimension: 800,
|
|
imageQuality: 85,
|
|
};
|
|
|
|
export function seedAuthStorage(page: Page, seed: AuthSeed = {}) {
|
|
return page.addInitScript((authSeed) => {
|
|
localStorage.setItem("token", authSeed.token || "test-token");
|
|
localStorage.setItem("userId", authSeed.userId || "1");
|
|
localStorage.setItem("role", authSeed.role || "admin");
|
|
localStorage.setItem("username", authSeed.username || "test-user");
|
|
}, seed);
|
|
}
|
|
|
|
export async function mockConfig(page: Page, overrides = {}) {
|
|
await page.route("**/config", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify({ ...defaultConfig, ...overrides }),
|
|
});
|
|
});
|
|
}
|
|
|
|
export async function mockHouseholdAndStoreShell(
|
|
page: Page,
|
|
options: { household?: HouseholdSeed; stores?: StoreSeed[] } = {}
|
|
) {
|
|
const household = {
|
|
id: 1,
|
|
name: "Test Household",
|
|
role: "admin",
|
|
invite_code: "ABCD1234",
|
|
...options.household,
|
|
};
|
|
const stores = options.stores || [
|
|
{ id: 10, name: "Costco", location: "Warehouse", is_default: true },
|
|
];
|
|
|
|
await page.route("**/households", async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify([household]),
|
|
});
|
|
});
|
|
|
|
await page.route(`**/stores/household/${household.id}`, async (route) => {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(stores),
|
|
});
|
|
});
|
|
}
|
|
|
|
export async function confirmSlide(page: Page) {
|
|
const confirmModal = page.locator(".confirm-slide-modal");
|
|
await expect(confirmModal).toBeVisible();
|
|
|
|
const slider = confirmModal.locator(".confirm-slide-handle");
|
|
const track = confirmModal.locator(".confirm-slide-track");
|
|
const sliderBox = await slider.boundingBox();
|
|
const trackBox = await track.boundingBox();
|
|
|
|
if (!sliderBox || !trackBox) {
|
|
throw new Error("Confirm slide control was not measurable");
|
|
}
|
|
|
|
await page.mouse.move(sliderBox.x + sliderBox.width / 2, sliderBox.y + sliderBox.height / 2);
|
|
await page.mouse.down();
|
|
await page.mouse.move(trackBox.x + trackBox.width - 4, sliderBox.y + sliderBox.height / 2, {
|
|
steps: 8,
|
|
});
|
|
await page.mouse.up();
|
|
}
|
|
|
|
export function collectFailedApiRequests(page: Page) {
|
|
const failedRequests: string[] = [];
|
|
|
|
page.on("requestfailed", (request) => {
|
|
const url = request.url();
|
|
if (!url.startsWith("http://localhost:5000")) {
|
|
return;
|
|
}
|
|
|
|
const failure = request.failure()?.errorText || "unknown failure";
|
|
failedRequests.push(`${request.method()} ${url} :: ${failure}`);
|
|
});
|
|
|
|
return failedRequests;
|
|
}
|
|
|
|
export function expectNoFailedApiRequests(failedRequests: string[]) {
|
|
expect(failedRequests).toEqual([]);
|
|
}
|