mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-10-03 02:04:31 +10:00
test(e2e): drive the share and export sheet
The sharing specs use Share → Link (public switch, visitor downloads, the password switch and the public address from Open public page), and the export specs pick a format in the Download tab. share-history covers renaming the address with the old one redirecting, and naming, previewing and restoring versions.
This commit is contained in:
@@ -64,10 +64,27 @@ export async function openSidebarSection(page: Page, title: string) {
|
||||
await expect(row).toHaveAttribute("aria-expanded", "true");
|
||||
}
|
||||
|
||||
/** Opens the Download dialog with every format from the ▾ next to Download PDF. */
|
||||
/** Opens Share & export on its Download tab, from the ▾ next to Download PDF. */
|
||||
export async function openDownloadDialog(page: Page) {
|
||||
await page.getByRole("button", { name: "More download formats", exact: true }).click();
|
||||
await expect(page.getByRole("dialog", { name: "Download" })).toBeVisible();
|
||||
const sheet = page.getByRole("dialog", { name: "Share & export" });
|
||||
await expect(sheet.getByRole("tab", { name: "Download", exact: true })).toHaveAttribute("aria-selected", "true");
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/** Turns the public link on in Share → Link and returns the public address. */
|
||||
export async function makeResumePublic(page: Page) {
|
||||
await openSidebarSection(page, "Sharing");
|
||||
const sheet = page.getByRole("dialog", { name: "Share & export" });
|
||||
await sheet.getByRole("switch", { name: "Public link" }).click();
|
||||
return getPublicUrl(page);
|
||||
}
|
||||
|
||||
/** The public address, from Share → Link's "Open public page" (it fills in once the session has loaded). */
|
||||
export async function getPublicUrl(page: Page) {
|
||||
const link = page.getByRole("dialog", { name: "Share & export" }).getByRole("link", { name: "Open public page" });
|
||||
await expect(link).toHaveAttribute("href", /\/e2e_/);
|
||||
return (await link.getAttribute("href")) as string;
|
||||
}
|
||||
|
||||
export async function openResumeCardMenu(page: Page, resumeName: string, { reload = true } = {}) {
|
||||
|
||||
@@ -61,12 +61,9 @@ async function seedHyphenationResume(page: Page) {
|
||||
}
|
||||
|
||||
async function downloadPdfText(page: Page, testInfo: TestInfo, name: string) {
|
||||
await openDownloadDialog(page);
|
||||
const sheet = await openDownloadDialog(page);
|
||||
const pending = page.waitForEvent("download");
|
||||
await page
|
||||
.getByRole("dialog", { name: "Download" })
|
||||
.getByRole("button", { name: "Download PDF", exact: true })
|
||||
.click();
|
||||
await sheet.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const download = await pending;
|
||||
const path = testInfo.outputPath(`${name}.pdf`);
|
||||
await download.saveAs(path);
|
||||
|
||||
@@ -5,9 +5,10 @@ import { expect, test } from "../fixtures/test";
|
||||
test("exports and imports a resume JSON backup", async ({ authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
|
||||
await openDownloadDialog(page);
|
||||
const sheet = await openDownloadDialog(page);
|
||||
await sheet.getByRole("radio", { name: /^JSON/ }).click();
|
||||
const downloadPromise = page.waitForEvent("download");
|
||||
await page.getByRole("button", { name: "Download JSON" }).click();
|
||||
await sheet.getByRole("button", { name: "Download JSON" }).click();
|
||||
const download = await downloadPromise;
|
||||
expect(download.suggestedFilename()).toMatch(/\.json$/);
|
||||
|
||||
|
||||
@@ -360,12 +360,9 @@ test.describe("offline font diagnostic", () => {
|
||||
let rasterEvidenceStatus = "not-attempted";
|
||||
try {
|
||||
await page.goto(fixture.builderURL);
|
||||
await openDownloadDialog(page);
|
||||
const sheet = await openDownloadDialog(page);
|
||||
const downloadPromise = page.waitForEvent("download", { timeout: 20_000 });
|
||||
await page
|
||||
.getByRole("dialog", { name: "Download" })
|
||||
.getByRole("button", { name: "Download PDF", exact: true })
|
||||
.click();
|
||||
await sheet.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const download = await downloadPromise;
|
||||
downloadStatus = "received";
|
||||
const path = testInfo.outputPath("offline-font-browser-download.pdf");
|
||||
|
||||
@@ -4,7 +4,6 @@ import { createRequire } from "node:module";
|
||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
||||
import { Pool } from "pg";
|
||||
import { defaultResumeData } from "@reactive-resume/schema/resume/default";
|
||||
import { generateFilename } from "@reactive-resume/utils/file";
|
||||
import { createSampleResumeFromDashboard, openDownloadDialog } from "../fixtures/resume";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
@@ -544,8 +543,7 @@ async function runGeometryMatrix(page: Page, testInfo: TestInfo, scenarios: Geom
|
||||
dedicatedDatabaseUrl();
|
||||
await page.setViewportSize({ width: 1920, height: 1000 });
|
||||
await installPreviewCapture(page);
|
||||
const resumeName = await createSampleResumeFromDashboard(page, testInfo);
|
||||
const expectedExportFilename = generateFilename(resumeName, "pdf");
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
const resumeId = new URL(page.url()).pathname.match(/^\/builder\/([^/]+)/)?.[1];
|
||||
if (!resumeId) throw new Error("Missing synthetic geometry resume id.");
|
||||
|
||||
@@ -582,17 +580,11 @@ async function runGeometryMatrix(page: Page, testInfo: TestInfo, scenarios: Geom
|
||||
persistedFixture.revision,
|
||||
);
|
||||
const pending = page.waitForEvent("download");
|
||||
await openDownloadDialog(page);
|
||||
const downloadDialog = page.getByRole("dialog", { name: "Download" });
|
||||
await expect(downloadDialog.getByRole("tab", { name: "Resume", exact: true })).toHaveAttribute(
|
||||
"aria-selected",
|
||||
"true",
|
||||
);
|
||||
await downloadDialog.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const downloadSheet = await openDownloadDialog(page);
|
||||
await downloadSheet.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const download = await pending;
|
||||
expect(download.suggestedFilename(), `${scenarioName(scenario)} zoom ${zoom} export target`).toBe(
|
||||
expectedExportFilename,
|
||||
);
|
||||
// The default file name is "First-Last-Resume"; this test only checks it's the PDF.
|
||||
expect(download.suggestedFilename(), `${scenarioName(scenario)} zoom ${zoom} export target`).toMatch(/\.pdf$/);
|
||||
const downloadPath = testInfo.outputPath(`${scenarioName(scenario)}.zoom-${zoom}.pdf`);
|
||||
await download.saveAs(downloadPath);
|
||||
const downloadBytes = new Uint8Array(await readFile(downloadPath));
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
import { createSampleResumeFromDashboard, openSidebarSection } from "../fixtures/resume";
|
||||
import {
|
||||
createSampleResumeFromDashboard,
|
||||
getPublicUrl,
|
||||
makeResumePublic,
|
||||
openSidebarSection,
|
||||
} from "../fixtures/resume";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
test("persists public download-button visibility", async ({ browser, authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
await openSidebarSection(page, "Sharing");
|
||||
await page.getByRole("switch", { name: /Allow Public Access/ }).click();
|
||||
const downloadPreference = page.getByRole("switch", { name: "Show Download Buttons" });
|
||||
await makeResumePublic(page);
|
||||
const downloadPreference = page.getByRole("switch", { name: "Visitors can download the PDF" });
|
||||
await expect(downloadPreference).toBeChecked();
|
||||
await downloadPreference.click();
|
||||
await expect(downloadPreference).not.toBeChecked();
|
||||
await page.reload();
|
||||
await openSidebarSection(page, "Sharing");
|
||||
await expect(downloadPreference).not.toBeChecked();
|
||||
// The address fills in once the session has loaded after the reload.
|
||||
await expect(page.locator("#sharing-url")).toHaveValue(/\/e2e_/);
|
||||
const publicUrl = await page.locator("#sharing-url").inputValue();
|
||||
const publicUrl = await getPublicUrl(page);
|
||||
|
||||
const anonymous = await browser.newPage();
|
||||
try {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { createSampleResumeFromDashboard, openSidebarSection } from "../fixtures/resume";
|
||||
import { createSampleResumeFromDashboard, makeResumePublic } from "../fixtures/resume";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
test("counts a visitor's PDF download without counting the preview", async ({ browser, authPage: page }, testInfo) => {
|
||||
@@ -11,13 +11,7 @@ test("counts a visitor's PDF download without counting the preview", async ({ br
|
||||
expect(response.ok()).toBe(true);
|
||||
return response.json();
|
||||
};
|
||||
await openSidebarSection(page, "Sharing");
|
||||
|
||||
await page.getByRole("switch", { name: /Allow Public Access/ }).click();
|
||||
const sharingUrl = page.locator("#sharing-url");
|
||||
await expect(sharingUrl).toHaveValue(/\/e2e_/);
|
||||
const publicUrl = await sharingUrl.inputValue();
|
||||
expect(publicUrl).toMatch(/\/e2e_/);
|
||||
const publicUrl = await makeResumePublic(page);
|
||||
|
||||
const anonymous = await browser.newPage();
|
||||
try {
|
||||
|
||||
@@ -100,12 +100,9 @@ async function showSection(page: Page, title: string) {
|
||||
}
|
||||
|
||||
async function downloadPdfText(page: Page, testInfo: TestInfo, name: string) {
|
||||
await openDownloadDialog(page);
|
||||
const sheet = await openDownloadDialog(page);
|
||||
const pending = page.waitForEvent("download");
|
||||
await page
|
||||
.getByRole("dialog", { name: "Download" })
|
||||
.getByRole("button", { name: "Download PDF", exact: true })
|
||||
.click();
|
||||
await sheet.getByRole("button", { name: "Download PDF", exact: true }).click();
|
||||
const download = await pending;
|
||||
const path = testInfo.outputPath(`${name}.pdf`);
|
||||
await download.saveAs(path);
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { createSampleResumeFromDashboard, getPublicUrl, makeResumePublic } from "../fixtures/resume";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
test("renames the public address and keeps the old one redirecting", async ({ browser, authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
const oldUrl = await makeResumePublic(page);
|
||||
const sheet = page.getByRole("dialog", { name: "Share & export" });
|
||||
const address = sheet.getByRole("textbox", { name: "Address" });
|
||||
|
||||
await address.fill("not_valid!");
|
||||
await expect(sheet.getByText("Use lowercase letters, numbers and single dashes.")).toBeVisible();
|
||||
|
||||
await address.fill("renamed-address");
|
||||
await expect(sheet.getByText(/^Live at .*\/renamed-address$/)).toBeVisible();
|
||||
expect(await getPublicUrl(page)).toMatch(/\/renamed-address$/);
|
||||
|
||||
const visitor = await browser.newPage();
|
||||
try {
|
||||
await visitor.goto(oldUrl);
|
||||
await visitor.waitForURL(/\/renamed-address$/);
|
||||
await expect(visitor.getByRole("heading", { level: 1 })).toBeVisible();
|
||||
} finally {
|
||||
await visitor.close();
|
||||
}
|
||||
});
|
||||
|
||||
test("names a version, previews an older one read-only and restores it", async ({ authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
await page.getByRole("button", { name: "History", exact: true }).click();
|
||||
const sheet = page.getByRole("dialog", { name: "Share & export" });
|
||||
const versions = sheet.getByRole("list", { name: "Versions" });
|
||||
// A new document's history starts with where it came from.
|
||||
await expect(versions.getByRole("button", { name: /^Created/ })).toBeVisible();
|
||||
|
||||
await sheet.getByRole("textbox", { name: "Name this version" }).fill("Sent to Lumen");
|
||||
await sheet.getByRole("button", { name: "Save", exact: true }).click();
|
||||
await expect(versions.getByRole("button", { name: /^Sent to Lumen/ })).toBeVisible();
|
||||
|
||||
await versions.getByRole("button", { name: /^Created/ }).click();
|
||||
// The sheet announces it; the page (outside the modal sheet) shows the same banner above the version.
|
||||
await expect(sheet.getByRole("status").filter({ hasText: /Viewing .* · Created · read-only/ })).toBeVisible();
|
||||
await expect(page.getByText(/^Viewing .* · Created · read-only$/).first()).toBeVisible();
|
||||
|
||||
await sheet.getByRole("button", { name: "Restore this version" }).click();
|
||||
await expect(versions.getByRole("button", { name: /^Before restore/ })).toBeVisible();
|
||||
await expect(versions.getByRole("button", { name: /^Now/ })).toHaveAttribute("aria-pressed", "true");
|
||||
});
|
||||
@@ -1,17 +1,13 @@
|
||||
import { createSampleResumeFromDashboard, openSidebarSection } from "../fixtures/resume";
|
||||
import { createSampleResumeFromDashboard, makeResumePublic } from "../fixtures/resume";
|
||||
import { expect, test } from "../fixtures/test";
|
||||
|
||||
test("password-protects a public resume and unlocks it as a visitor", async ({ browser, authPage: page }, testInfo) => {
|
||||
await createSampleResumeFromDashboard(page, testInfo);
|
||||
await openSidebarSection(page, "Sharing");
|
||||
|
||||
await page.getByRole("switch", { name: /Allow Public Access/ }).click();
|
||||
const sharingUrl = page.locator("#sharing-url");
|
||||
await expect(sharingUrl).toHaveValue(/\/e2e_/);
|
||||
const publicUrl = await sharingUrl.inputValue();
|
||||
const publicUrl = await makeResumePublic(page);
|
||||
|
||||
const password = "e2e-secret-42";
|
||||
await page.getByRole("button", { name: "Set Password" }).click();
|
||||
const requirePassword = page.getByRole("switch", { name: "Require a password" });
|
||||
await requirePassword.click();
|
||||
const dialog = page.getByRole("dialog", { name: "Protect your resume with a password" });
|
||||
await dialog.getByLabel("Password", { exact: true }).fill(password);
|
||||
await dialog.getByLabel("Confirm Password", { exact: true }).fill("different-password");
|
||||
@@ -19,7 +15,7 @@ test("password-protects a public resume and unlocks it as a visitor", async ({ b
|
||||
await expect(dialog.getByRole("alert")).toHaveText("Passwords do not match.");
|
||||
await dialog.getByLabel("Confirm Password", { exact: true }).fill(password);
|
||||
await dialog.getByRole("button", { name: "Set Password" }).click();
|
||||
await expect(page.getByRole("button", { name: "Remove Password" })).toBeVisible();
|
||||
await expect(requirePassword).toBeChecked();
|
||||
|
||||
const anonymous = await browser.newPage();
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user