mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-03 18:23:47 +10:00
fix: finalize v6 migrations and document workflows
This commit is contained in:
@@ -33,7 +33,7 @@ export async function logoutViaUi(page: Page, account: E2EAccount) {
|
||||
.getByRole("button", { name: new RegExp(account.name) })
|
||||
.click();
|
||||
await page.getByRole("menuitem", { name: "Sign out" }).click();
|
||||
await page.goto("/auth/login");
|
||||
await page.waitForURL(/\/auth\/login/);
|
||||
}
|
||||
|
||||
async function registerViaApi(request: APIRequestContext, account: E2EAccount, baseURL: string) {
|
||||
|
||||
@@ -44,3 +44,34 @@ test("retains the current draft when saving during navigation fails", async ({ a
|
||||
await page.goto(url);
|
||||
await expect(page.getByRole("textbox", { name: "Full name", exact: true })).toHaveValue("Keep unsaved draft");
|
||||
});
|
||||
|
||||
test("retains failed letter edits until navigation can save them", async ({ authPage: page }, testInfo) => {
|
||||
const created = await page.request.post("/api/openapi/cover-letters", {
|
||||
data: { name: `Letter ${testInfo.testId}` },
|
||||
});
|
||||
expect(created.ok()).toBe(true);
|
||||
const letter = (await created.json()) as { id: string };
|
||||
await page.goto(`/builder/letter/${letter.id}`);
|
||||
const url = page.url();
|
||||
const letterUpdate = "**/api/rpc/coverLetters/update";
|
||||
let attempts = 0;
|
||||
await page.route(letterUpdate, async (route) => {
|
||||
attempts++;
|
||||
await route.abort("failed");
|
||||
});
|
||||
await page.getByRole("button", { name: "Write it myself", exact: true }).click();
|
||||
const body = page.getByRole("textbox", { name: "Letter body", exact: true });
|
||||
await body.fill("Retain this failed letter draft");
|
||||
await expect(page.getByRole("status").filter({ hasText: "Not saved" })).toBeVisible();
|
||||
await clickDashboardWithoutNavigationWait(page);
|
||||
await expect.poll(() => attempts).toBeGreaterThanOrEqual(2);
|
||||
expect(page.url()).toBe(url);
|
||||
await expect(body).toHaveText("Retain this failed letter draft");
|
||||
await page.unroute(letterUpdate);
|
||||
await clickDashboardWithoutNavigationWait(page);
|
||||
await page.waitForURL(/\/dashboard/);
|
||||
await page.goto(url);
|
||||
await expect(page.getByRole("textbox", { name: "Letter body", exact: true })).toHaveText(
|
||||
"Retain this failed letter draft",
|
||||
);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
test("browser PDF downloads preserve shaped scripts and report unsupported text", async ({
|
||||
authPage: page,
|
||||
}, testInfo) => {
|
||||
test.setTimeout(180_000);
|
||||
const created = await page.request.post("/api/openapi/resumes", {
|
||||
data: { name: `PDF ${testInfo.testId}`, tags: [] },
|
||||
});
|
||||
expect(created.ok()).toBe(true);
|
||||
const id = (await created.json()) as string;
|
||||
const response = await page.request.get(`/api/openapi/resumes/${id}`);
|
||||
expect(response.ok()).toBe(true);
|
||||
const { data } = await response.json();
|
||||
data.picture.hidden = true;
|
||||
data.metadata.layout.pages = [{ fullWidth: true, main: ["summary"], sidebar: [] }];
|
||||
for (const [text, font, locale] of [
|
||||
["שלום עולם ניסיון עבודה", "Noto Sans Hebrew", "he-IL"],
|
||||
["مرحبا بالعالم مهندس برمجيات", "Noto Sans Arabic", "ar-SA"],
|
||||
["नमस्ते दुनिया अनुभव कौशल", "Noto Sans Devanagari", "hi-IN"],
|
||||
["Hello 💻 engineer 🚀 coding 😀", "Noto Sans", "en-US"],
|
||||
] as const) {
|
||||
data.summary.content = `<p>${text}</p>`;
|
||||
data.metadata.page.locale = locale;
|
||||
data.metadata.typography.body.fontFamily = font;
|
||||
data.metadata.typography.heading.fontFamily = font;
|
||||
const updated = await page.request.put(`/api/openapi/resumes/${id}`, { data: { data } });
|
||||
expect(updated.ok()).toBe(true);
|
||||
await page.goto(`/builder/${id}`);
|
||||
const downloaded = page.waitForEvent("download");
|
||||
await page.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const download = await downloaded;
|
||||
expect(await download.failure()).toBeNull();
|
||||
const path = await download.path();
|
||||
if (!path) throw new Error("Browser did not save the PDF");
|
||||
const loading = getDocument({ data: new Uint8Array(await readFile(path)) });
|
||||
try {
|
||||
const pdf = await loading.promise;
|
||||
const content = await (await pdf.getPage(1)).getTextContent();
|
||||
expect(
|
||||
content.items
|
||||
.map((item) => ("str" in item ? item.str : ""))
|
||||
.join("")
|
||||
.replace(/\s+/g, " "),
|
||||
).toContain(text);
|
||||
} finally {
|
||||
await loading.destroy();
|
||||
}
|
||||
}
|
||||
data.summary.content = "<p>Unsupported \u{10FFFF}</p>";
|
||||
expect((await page.request.put(`/api/openapi/resumes/${id}`, { data: { data } })).ok()).toBe(true);
|
||||
await page.goto(`/builder/${id}`);
|
||||
await page.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
await expect(
|
||||
page.getByText(
|
||||
"Some PDF text could not be rendered. Choose a font containing these characters, then retry the export.",
|
||||
),
|
||||
).toBeVisible();
|
||||
const rejected = await page.request.get(`/api/openapi/resumes/${id}/pdf`);
|
||||
expect(rejected.status()).toBe(400);
|
||||
expect(await rejected.text()).toContain("Choose a font containing these characters");
|
||||
});
|
||||
@@ -35,3 +35,22 @@ test("adds an experience item and persists it across reloads", async ({ authPage
|
||||
await expect(page.getByText(company).filter({ visible: true }).first()).toBeVisible();
|
||||
await expect(page.getByText(position).filter({ visible: true }).first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("keeps formatting controls accessible when tabbing from the editor", async ({ authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
await openSidebarSection(page, "Summary");
|
||||
const summary = page.getByRole("textbox", { name: "Summary", exact: true });
|
||||
await summary.fill("Keyboard formatting");
|
||||
await summary.press("ControlOrMeta+A");
|
||||
expect(await summary.evaluate(() => window.getSelection()?.toString())).toBe("Keyboard formatting");
|
||||
await summary.press("Tab");
|
||||
const toolbar = page.getByRole("toolbar", { name: "Formatting" });
|
||||
const bold = toolbar.getByRole("button", { name: "Bold", exact: true });
|
||||
await expect(bold).toBeFocused();
|
||||
const wasBold = (await bold.getAttribute("aria-pressed")) === "true";
|
||||
await bold.press("Enter");
|
||||
await expect(bold).toHaveAttribute("aria-pressed", String(!wasBold));
|
||||
if (wasBold) await expect(summary.locator("strong")).toHaveCount(0);
|
||||
else await expect(summary.locator("strong")).toHaveText("Keyboard formatting");
|
||||
await expect(toolbar).toBeVisible();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user