test(release): complete local action matrix
This commit is contained in:
@@ -34,15 +34,19 @@ function contrastRatio(foreground: Rgba, background: Rgba) {
|
||||
/ (Math.min(foregroundLuminance, backgroundLuminance) + 0.05);
|
||||
}
|
||||
|
||||
async function login(page: Page) {
|
||||
async function loginAs(page: Page, email: string, password: string) {
|
||||
await page.goto("/login");
|
||||
await page.getByLabel("Email").fill("e2e@example.test");
|
||||
await page.getByLabel("Current password").fill("E2ePassword123!");
|
||||
await page.getByLabel("Email").fill(email);
|
||||
await page.getByLabel("Current password").fill(password);
|
||||
await page.getByRole("button", { name: "Sign in", exact: true }).click();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await expect(page.getByRole("heading", { name: "Dashboard", exact: true })).toBeVisible();
|
||||
}
|
||||
|
||||
async function login(page: Page) {
|
||||
await loginAs(page, "e2e@example.test", "E2ePassword123!");
|
||||
}
|
||||
|
||||
async function csrfHeader(page: Page) {
|
||||
const cookie = (await page.context().cookies()).find((value) => value.name === "XSRF-TOKEN");
|
||||
expect(cookie, "login should issue a CSRF cookie").toBeTruthy();
|
||||
@@ -69,8 +73,17 @@ test("public plans stay honest, responsive and keyboard accessible", async ({ pa
|
||||
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
}
|
||||
|
||||
await page.goto("/login");
|
||||
await expect(page.getByRole("heading", { name: "Sign in", exact: true })).toBeVisible();
|
||||
for (const width of [375, 768, 1440]) {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
}
|
||||
}
|
||||
|
||||
await page.goto("/");
|
||||
const freeAction = page.getByRole("button", { name: "Create a Free account" });
|
||||
await freeAction.focus();
|
||||
await page.keyboard.press("Enter");
|
||||
@@ -86,6 +99,46 @@ test("public plans stay honest, responsive and keyboard accessible", async ({ pa
|
||||
test("login establishes an authenticated session", async ({ page }) => {
|
||||
await login(page);
|
||||
await expect(page.getByText("e2e@example.test").first()).toBeVisible();
|
||||
await expect(page.getByTestId("admin-version-badge")).toHaveText("ve2e-verification");
|
||||
await expect(page.getByLabel("Application version e2e-verification, commit e2e1234")).toBeVisible();
|
||||
|
||||
await page.getByRole("button", { name: "Notifications" }).click();
|
||||
await expect(page.getByLabel("Notifications panel")).toBeVisible();
|
||||
await expect(page).toHaveURL(/\/dashboard$/);
|
||||
await page.getByRole("button", { name: "Close" }).click();
|
||||
});
|
||||
|
||||
test("a Free account keeps manual work available while AI actions stay honestly locked", async ({ page }) => {
|
||||
const suffix = Date.now().toString();
|
||||
const email = `free-${suffix}@example.test`;
|
||||
const password = "FreeUserPassword123!";
|
||||
|
||||
await login(page);
|
||||
const headers = await csrfHeader(page);
|
||||
const createUser = await page.request.post(`${apiUrl}/users`, {
|
||||
headers,
|
||||
data: { email, password, displayName: "Free E2E User", roles: [] },
|
||||
});
|
||||
expect(createUser.ok()).toBeTruthy();
|
||||
|
||||
await page.context().clearCookies();
|
||||
await loginAs(page, email, password);
|
||||
await expect(page.getByTestId("admin-version-badge")).toHaveCount(0);
|
||||
|
||||
await page.evaluate(() => window.localStorage.setItem("jobtracker.themeMode", "dark"));
|
||||
await page.setViewportSize({ width: 375, height: 900 });
|
||||
await page.goto("/career");
|
||||
await expect(page.getByText(/Build your Career Profile faster with Pro/)).toBeVisible();
|
||||
await expect(page.getByLabel("Professional headline")).toBeEnabled();
|
||||
await page.getByRole("button", { name: "Dismiss Build your Career Profile faster with Pro." }).click();
|
||||
await expect(page.getByText(/Build your Career Profile faster with Pro/)).toHaveCount(0);
|
||||
|
||||
await page.goto("/settings");
|
||||
await expect(page.getByText(/Free plan includes core job tracking without AI/i)).toBeVisible();
|
||||
await expect(page.getByText(/Pro upgrades are not available in this deployment yet/i)).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "Upgrade to Pro" })).toHaveCount(0);
|
||||
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
});
|
||||
|
||||
test("a saved job can be created through the reviewed UI flow", async ({ page }) => {
|
||||
@@ -233,9 +286,32 @@ test("the dedicated application workspace survives deep links, long data and uns
|
||||
|
||||
test("Career Workspace loads from the authenticated application shell", async ({ page }) => {
|
||||
await login(page);
|
||||
await page.evaluate(() => window.localStorage.setItem("jobtracker.themeMode", "light"));
|
||||
await page.goto("/career");
|
||||
await expect(page.getByRole("heading", { name: "Career Workspace" })).toBeVisible();
|
||||
await expect(page.getByRole("link", { name: "Open CV Builder" })).toHaveAttribute("href", "/career/builder");
|
||||
|
||||
for (const width of [375, 768, 1440]) {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
}
|
||||
|
||||
await page.getByRole("link", { name: "Open CV Builder" }).click();
|
||||
await expect(page).toHaveURL(/\/career\/builder$/);
|
||||
await page.getByRole("button", { name: "New CV" }).first().click();
|
||||
await expect(page).toHaveURL(/\/career\/builder\/\d+$/);
|
||||
await expect(page.getByLabel("CV name")).toBeVisible();
|
||||
|
||||
await page.evaluate(() => window.localStorage.setItem("jobtracker.themeMode", "dark"));
|
||||
await page.reload();
|
||||
await expect(page.locator("html")).toHaveAttribute("data-color-scheme", "dark");
|
||||
for (const width of [375, 768, 1440]) {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
await expect(page.getByLabel("CV name")).toBeVisible();
|
||||
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - document.documentElement.clientWidth);
|
||||
expect(overflow).toBeLessThanOrEqual(1);
|
||||
}
|
||||
});
|
||||
|
||||
test("a public CV renders anonymously and downloads as PDF", async ({ page }) => {
|
||||
|
||||
@@ -31,6 +31,8 @@ export default defineConfig({
|
||||
Auth__AdminEmail: "e2e@example.test",
|
||||
Auth__AdminPassword: "E2ePassword123!",
|
||||
Auth__AllowRegistration: "false",
|
||||
App__Version: "e2e-verification",
|
||||
App__CommitSha: "e2e1234",
|
||||
Cors__Origins__0: appUrl,
|
||||
Data__Root: dataRoot,
|
||||
HttpsRedirection__Enabled: "false",
|
||||
|
||||
Reference in New Issue
Block a user