diff --git a/web-app/playwright.config.ts b/web-app/playwright.config.ts index 5b9ccdb..1ff761a 100644 --- a/web-app/playwright.config.ts +++ b/web-app/playwright.config.ts @@ -3,7 +3,10 @@ import { type PlaywrightTestConfig } from "@playwright/test"; const config: PlaywrightTestConfig = { webServer: { command: "npm run build && npm run preview", - port: 4173 + url: "http://localhost:4173" + }, + use: { + baseURL: "http://localhost:4173" }, testDir: "tests", testMatch: /(.+\.)?(test|spec)\.ts/ diff --git a/web-app/tests/account.spec.ts b/web-app/tests/account.spec.ts index 34a0cb9..32f0474 100644 --- a/web-app/tests/account.spec.ts +++ b/web-app/tests/account.spec.ts @@ -1,68 +1,53 @@ -import { test, expect } from "@playwright/test"; +import { test as base, expect, type Page } from "@playwright/test"; +import { randomBytes } from "node:crypto"; + +const username = randomBytes(8).toString("hex"); +const password = "T3stuser??!!"; + +const test = base.extend<{ authenticatedPage: Page }>({ + authenticatedPage: async ({ page }, use) => { + await page.goto("/login"); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + await use(page); + } +}); test("Register", async ({ page }) => { - await page.goto("/"); - await page.getByRole("link", { name: "Register" }).click(); + await page.goto("/register"); await page.getByLabel("Username:").click(); - await page.getByLabel("Username:").fill("archtika-test"); + await page.getByLabel("Username:").fill(username); await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); + await page.getByLabel("Password:").fill(password); await page.getByRole("button", { name: "Submit" }).click(); await expect(page.getByText("Successfully registered, you")).toBeVisible(); }); test("Login", async ({ page }) => { - await page.goto("/"); - await page.getByRole("link", { name: "Login" }).click(); + await page.goto("/login"); await page.getByLabel("Username:").click(); - await page.getByLabel("Username:").fill("archtika-test"); + await page.getByLabel("Username:").fill(username); await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); + await page.getByLabel("Password:").fill(password); await page.getByRole("button", { name: "Submit" }).click(); await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible(); }); -test("Logout", async ({ page }) => { - await page.goto("/"); - await page.getByRole("link", { name: "Login" }).click(); - await page.getByLabel("Username:").click(); - await page.getByLabel("Username:").fill("archtika-test"); - await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); - await page.getByRole("button", { name: "Submit" }).click(); - await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible(); +test("Logout", async ({ authenticatedPage: page }) => { await page.getByRole("link", { name: "Account" }).click(); await page.getByRole("button", { name: "Logout" }).click(); await expect(page.getByRole("heading", { name: "Login" })).toBeVisible(); }); -test("Delete account", async ({ page }) => { - await page.goto("/"); - await page.getByRole("link", { name: "Login" }).click(); - await page.getByLabel("Username:").click(); - await page.getByLabel("Username:").fill("archtika-test"); - await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); - await page.getByRole("button", { name: "Submit" }).click(); - await expect(page.getByRole("heading", { name: "Dashboard" })).toBeVisible(); +test("Delete account", async ({ authenticatedPage: page }) => { await page.getByRole("link", { name: "Account" }).click(); await page.getByRole("button", { name: "Delete account" }).click(); await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); + await page.getByLabel("Password:").fill(password); await page .locator("#delete-account-modal") .getByRole("button", { name: "Delete account" }) .click(); await expect(page.getByRole("heading", { name: "Login" })).toBeVisible(); }); - -test("Register after account deletion", async ({ page }) => { - await page.goto("/"); - await page.getByRole("link", { name: "Register" }).click(); - await page.getByLabel("Username:").click(); - await page.getByLabel("Username:").fill("archtika-test"); - await page.getByLabel("Password:").click(); - await page.getByLabel("Password:").fill("T3stuser??!!"); - await page.getByRole("button", { name: "Submit" }).click(); - await expect(page.getByText("Successfully registered, you")).toBeVisible(); -}); diff --git a/web-app/tests/sample-files/archtika-logo-512x512.png b/web-app/tests/sample-files/archtika-logo-512x512.png new file mode 100644 index 0000000..5684dab Binary files /dev/null and b/web-app/tests/sample-files/archtika-logo-512x512.png differ diff --git a/web-app/tests/website.spec.ts b/web-app/tests/website.spec.ts new file mode 100644 index 0000000..db23d80 --- /dev/null +++ b/web-app/tests/website.spec.ts @@ -0,0 +1,205 @@ +import { test as base, expect, type Page } from "@playwright/test"; +import { fileURLToPath } from "node:url"; +import { dirname, join } from "node:path"; +import { randomBytes } from "node:crypto"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +const username = randomBytes(8).toString("hex"); +const collabUsername = randomBytes(8).toString("hex"); +const password = "T3stuser??!!"; + +const test = base.extend<{ authenticatedPage: Page }>({ + authenticatedPage: async ({ page }, use) => { + await page.goto("/login"); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + await use(page); + } +}); + +test("Register", async ({ page }) => { + await page.goto("/register"); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(username); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); + + await page.getByLabel("Username:").click(); + await page.getByLabel("Username:").fill(collabUsername); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page.getByRole("button", { name: "Submit" }).click(); +}); + +test("Create websites", async ({ authenticatedPage: page }) => { + await page.getByRole("button", { name: "Create website" }).click(); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Blog"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByRole("link", { name: "All websites" })).toBeVisible(); + await expect(page.getByText("Search & Sort & Filter")).toBeVisible(); + await expect(page.getByText("Blog Type: Blog Created at:")).toBeVisible(); + + await page.getByRole("button", { name: "Create website" }).click(); + await page.getByLabel("Type: BlogDocs").selectOption("Docs"); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Documentation"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByRole("link", { name: "All websites" })).toBeVisible(); + await expect(page.getByText("Search & Sort & Filter")).toBeVisible(); + await expect(page.getByText("Documentation Type: Docs")).toBeVisible(); +}); + +test.describe("Update website", () => { + test("Update websites", async ({ authenticatedPage: page }) => { + await page.getByRole("button", { name: "Update" }).nth(1).click(); + await page.getByRole("textbox", { name: "Title" }).click(); + await page.getByRole("textbox", { name: "Title" }).fill("Blog updated"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByRole("link", { name: "Blog updated" })).toBeVisible(); + + await page.getByRole("button", { name: "Update" }).first().click(); + await page.getByRole("textbox", { name: "Title" }).click(); + await page.getByRole("textbox", { name: "Title" }).fill("Documentation updated"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByRole("link", { name: "Documentation updated" })).toBeVisible(); + }); + + test.describe("Update settings", () => { + test("Global", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByLabel("Light accent color:").click(); + await page.getByLabel("Light accent color:").fill("#3975a2"); + await page.getByLabel("Dark accent color:").click(); + await page.getByLabel("Dark accent color:").fill("#41473e"); + await page.locator("#global").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated global")).toBeVisible(); + await page.getByLabel("Favicon:").click(); + await page + .getByLabel("Favicon:") + .setInputFiles(join(__dirname, "sample-files", "archtika-logo-512x512.png")); + await page.locator("#global").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated global")).toBeVisible(); + }); + + test("Header", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByLabel("Logo text:").click(); + await page.getByLabel("Logo text:").fill("archtika Blog updated"); + await page.locator("#header").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated header")).toBeVisible(); + await page.getByLabel("Logo type: TextImage").selectOption("image"); + await page.getByLabel("Logo image:").click(); + await page + .getByLabel("Logo image:") + .setInputFiles(join(__dirname, "sample-files", "archtika-logo-512x512.png")); + await page.locator("#header").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated header")).toBeVisible(); + }); + + test("Home", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByLabel("Main content:").click(); + await page.getByLabel("Main content:").press("Control+a"); + await page.getByLabel("Main content:").fill("## Some new content comes here"); + await expect(page.getByRole("link", { name: "Some new content comes here" })).toBeVisible(); + await page.locator("#home").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated home")).toBeVisible(); + }); + + test("Footer", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByLabel("Additional text:").click(); + await page + .getByLabel("Additional text:") + .fill( + "archtika is a free, open, modern, performant and lightweight CMS updated content comes here" + ); + await page.locator("#footer").getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated footer")).toBeVisible(); + }); + }); + + test.describe("Articles", () => { + test("Create article", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("button", { name: "Create article" }).click(); + await page.getByLabel("Title:").click(); + await page.getByLabel("Title:").fill("Test article"); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByRole("link", { name: "All articles" })).toBeVisible(); + await expect(page.getByText("Search & Filter")).toBeVisible(); + await expect(page.getByText("Test article Edit Delete")).toBeVisible(); + }); + + test("Update article", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("link", { name: "Edit" }).click(); + await page.getByLabel("Description:").click(); + await page.getByLabel("Description:").fill("Sample article description"); + await page.getByLabel("Author:").click(); + await page.getByLabel("Author:").fill("John Doe"); + await page.getByLabel("Main content:").click(); + await page + .getByLabel("Main content:") + .fill( + "## Section\n\n### Subsection\n\n## Second section\n\n### Second subsection\n\n#### Sub Sub section" + ); + await expect( + page.getByText("Table of contents SectionSubsectionSecond sectionSecond subsectionSub Sub") + ).toBeVisible(); + await expect( + page.getByRole("heading", { name: "Section", exact: true }).getByRole("link") + ).toBeVisible(); + await page.getByRole("button", { name: "Submit" }).click(); + await expect(page.getByText("Successfully updated article")).toBeVisible(); + }); + + test("Delete article", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Blog" }).click(); + await page.getByRole("link", { name: "Articles" }).click(); + await page.getByRole("button", { name: "Delete" }).click(); + await page.getByRole("button", { name: "Delete article" }).click(); + await expect(page.getByText("Successfully deleted article")).toBeVisible(); + }); + }); + + test.describe("Collaborators", () => { + test("Add collaborator", async ({ authenticatedPage: page }) => {}); + + test("Update collaborator", async ({ authenticatedPage: page }) => {}); + + test("Delete collaborator", async ({ authenticatedPage: page }) => {}); + }); +}); + +test("Delete websites", async ({ authenticatedPage: page }) => { + await page.getByRole("button", { name: "Delete" }).nth(1).click(); + await page.getByRole("button", { name: "Delete website" }).click(); + await expect(page.getByText("Successfully deleted website")).toBeVisible(); + + await page.getByRole("button", { name: "Delete" }).click(); + await page.getByRole("button", { name: "Delete website" }).click(); + await expect(page.getByText("Successfully deleted website")).toBeVisible(); + + await expect(page.getByRole("link", { name: "All websites" })).toBeHidden(); +}); + +test("Delete account", async ({ authenticatedPage: page }) => { + await page.getByRole("link", { name: "Account" }).click(); + await page.getByRole("button", { name: "Delete account" }).click(); + await page.getByLabel("Password:").click(); + await page.getByLabel("Password:").fill(password); + await page + .locator("#delete-account-modal") + .getByRole("button", { name: "Delete account" }) + .click(); + await expect(page.getByRole("heading", { name: "Login" })).toBeVisible(); +});