211 lines
6.5 KiB
TypeScript
211 lines
6.5 KiB
TypeScript
import { test, expect, Page } from "@playwright/test";
|
|
|
|
const getFormLocators = (page: Page) => {
|
|
const form = page.getByTestId("petition-form").first();
|
|
return {
|
|
form,
|
|
anonymousCheckbox: form.locator("#anonymous"),
|
|
nameInput: form.locator('input[placeholder="Your Name"]'),
|
|
emailInput: form.locator('input[type="email"]'),
|
|
commentTextarea: form.locator("textarea"),
|
|
submitButton: form.locator('button[type="submit"]'),
|
|
};
|
|
};
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
const mockSignatures: any[] = [];
|
|
|
|
await page.route("**/sign", async (route) => {
|
|
if (route.request().method() === "POST") {
|
|
const body = JSON.parse(route.request().postData() || "{}");
|
|
const newSignature = {
|
|
id: "fceff5b5-a185-4d42-a539-3a9c7b5edacd",
|
|
createdAt: new Date().toISOString(),
|
|
...body,
|
|
};
|
|
mockSignatures.push(newSignature);
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(newSignature),
|
|
});
|
|
} else if (route.request().method() === "GET") {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(mockSignatures),
|
|
});
|
|
} else {
|
|
await route.continue();
|
|
}
|
|
});
|
|
|
|
await page.goto("/");
|
|
});
|
|
|
|
test("anonymous submission with valid email only", async ({ page }) => {
|
|
const { anonymousCheckbox, emailInput, submitButton } = getFormLocators(page);
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("test@example.com");
|
|
await submitButton.click();
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
await expect(emailInput).toHaveValue("");
|
|
});
|
|
|
|
test("named submission with valid name and email", async ({ page }) => {
|
|
const { nameInput, emailInput, submitButton } = getFormLocators(page);
|
|
await nameInput.fill("John Doe");
|
|
await emailInput.fill("john@example.com");
|
|
await submitButton.click();
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
await expect(emailInput).toHaveValue("");
|
|
await expect(nameInput).toHaveValue("");
|
|
});
|
|
|
|
test("submission with valid comment", async ({ page }) => {
|
|
const { anonymousCheckbox, emailInput, commentTextarea, submitButton } =
|
|
getFormLocators(page);
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("test@example.com");
|
|
await commentTextarea.fill("This carpark is essential for our community");
|
|
await submitButton.click();
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
await expect(commentTextarea).toHaveValue("");
|
|
});
|
|
|
|
test("comment with less than 5 characters shows validation error", async ({
|
|
page,
|
|
}) => {
|
|
const { anonymousCheckbox, emailInput, commentTextarea, submitButton } =
|
|
getFormLocators(page);
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("test@example.com");
|
|
await commentTextarea.fill("Hi");
|
|
await submitButton.click();
|
|
const validationMessage = await commentTextarea.evaluate(
|
|
(el: HTMLTextAreaElement) => el.validationMessage,
|
|
);
|
|
expect(validationMessage).toBeTruthy();
|
|
});
|
|
|
|
test("invalid email shows validation error", async ({ page }) => {
|
|
const { anonymousCheckbox, emailInput, submitButton } = getFormLocators(page);
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("notanemail");
|
|
await submitButton.click();
|
|
const validationMessage = await emailInput.evaluate(
|
|
(el: HTMLInputElement) => el.validationMessage,
|
|
);
|
|
expect(validationMessage).toBeTruthy();
|
|
});
|
|
|
|
test("empty required fields show validation error", async ({ page }) => {
|
|
const { nameInput, submitButton } = getFormLocators(page);
|
|
await submitButton.click();
|
|
const nameValidationMessage = await nameInput.evaluate(
|
|
(el: HTMLInputElement) => el.validationMessage,
|
|
);
|
|
expect(nameValidationMessage).toBeTruthy();
|
|
});
|
|
|
|
test("anonymous checkbox toggles name field visibility", async ({ page }) => {
|
|
const { anonymousCheckbox, nameInput } = getFormLocators(page);
|
|
await expect(nameInput).toBeVisible();
|
|
await anonymousCheckbox.check();
|
|
await expect(nameInput).toBeHidden();
|
|
await anonymousCheckbox.uncheck();
|
|
await expect(nameInput).toBeVisible();
|
|
});
|
|
|
|
test("submit button is disabled while submitting", async ({ page }) => {
|
|
const mockSignatures: any[] = [];
|
|
|
|
await page.route("**/sign", async (route) => {
|
|
if (route.request().method() === "POST") {
|
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
const body = JSON.parse(route.request().postData() || "{}");
|
|
const newSignature = {
|
|
id: `${Date.now()}-${Math.random()}`,
|
|
createdAt: new Date().toISOString(),
|
|
...body,
|
|
};
|
|
mockSignatures.push(newSignature);
|
|
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: "application/json",
|
|
body: JSON.stringify(newSignature),
|
|
});
|
|
}
|
|
});
|
|
|
|
const { anonymousCheckbox, emailInput, submitButton } = getFormLocators(page);
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("test@example.com");
|
|
|
|
await submitButton.click();
|
|
await expect(submitButton).toBeDisabled();
|
|
await expect(submitButton).toHaveText("Submitting...");
|
|
});
|
|
|
|
test("signature counter increases after submissions", async ({ page }) => {
|
|
const signatureCountLocator = page.locator("text=/\\d+ people/");
|
|
|
|
const { anonymousCheckbox, emailInput, submitButton } = getFormLocators(page);
|
|
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("first@example.com");
|
|
await submitButton.click();
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
|
|
await expect(signatureCountLocator).toContainText("1 people");
|
|
|
|
await anonymousCheckbox.check();
|
|
await emailInput.fill("second@example.com");
|
|
await submitButton.click();
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
|
|
await expect(signatureCountLocator).toContainText("2 people");
|
|
});
|
|
|
|
test("submitted petition appears on testimonies page with correct information", async ({
|
|
page,
|
|
}) => {
|
|
const testName = "Jane Smith";
|
|
const testEmail = "jane@example.com";
|
|
const testComment =
|
|
"This carpark closure has significantly impacted my daily routine";
|
|
|
|
const { nameInput, emailInput, commentTextarea, submitButton } =
|
|
getFormLocators(page);
|
|
|
|
await nameInput.fill(testName);
|
|
await emailInput.fill(testEmail);
|
|
await commentTextarea.fill(testComment);
|
|
await submitButton.click();
|
|
|
|
await expect(
|
|
page.getByText("Thank you for signing the petition.").first(),
|
|
).toBeVisible();
|
|
|
|
await page.goto("testimonies");
|
|
|
|
await expect(page.getByText(testName)).toBeVisible();
|
|
await expect(page.getByText(testComment)).toBeVisible();
|
|
|
|
await expect(page.locator("text=/\\d+ Signatures/")).toContainText(
|
|
"1 Signatures",
|
|
);
|
|
});
|