diff --git a/frontend/src/routes/signup.tsx b/frontend/src/routes/signup.tsx
index 1a27e3b..b021e73 100644
--- a/frontend/src/routes/signup.tsx
+++ b/frontend/src/routes/signup.tsx
@@ -87,7 +87,7 @@ function SignUp() {
@@ -102,6 +102,7 @@ function SignUp() {
{
+ await page.getByPlaceholder("Full Name").fill(full_name)
+ await page.getByPlaceholder("Email").fill(email)
+ await page.getByPlaceholder("Password", { exact: true }).fill(password)
+ await page.getByPlaceholder("Repeat Password").fill(confirm_password)
+}
+
+const verifyInput = async (
+ page: Page,
+ placeholder: string,
+ options?: OptionsType,
+) => {
+ const input = page.getByPlaceholder(placeholder, options)
+ await expect(input).toBeVisible()
+ await expect(input).toHaveText("")
+ await expect(input).toBeEditable()
+}
+
+test("Inputs are visible, empty and editable", async ({ page }) => {
+ await page.goto("/signup")
+
+ await verifyInput(page, "Full Name")
+ await verifyInput(page, "Email")
+ await verifyInput(page, "Password", { exact: true })
+ await verifyInput(page, "Repeat Password")
+})
+
+test("Sign Up button is visible", async ({ page }) => {
+ await page.goto("/signup")
+
+ await expect(page.getByRole("button", { name: "Sign Up" })).toBeVisible()
+})
+
+test("Log In link is visible", async ({ page }) => {
+ await page.goto("/signup")
+
+ await expect(page.getByRole("link", { name: "Log In" })).toBeVisible()
+})
+
+test("Sign up with valid name, email, and password", async ({ page }) => {
+ const full_name = "Test User"
+ const email = randomEmail()
+ const password = "changethis"
+
+ await page.goto("/signup")
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+})
+
+test("Sign up with invalid email", async ({ page }) => {
+ await page.goto("/signup")
+
+ await fillForm(
+ page,
+ "Playwright Test",
+ "invalid-email",
+ "changethis",
+ "changethis",
+ )
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(page.getByText("Invalid email address")).toBeVisible()
+})
+
+test("Sign up with existing email", async ({ page }) => {
+ const full_name = "Test User"
+ const email = randomEmail()
+ const password = "changethis"
+
+ // Sign up with an email
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ // Sign up again with the same email
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await page
+ .getByText("The user with this email already exists in the system")
+ .click()
+})
+
+test("Sign up with weak password", async ({ page }) => {
+ const full_name = "Test User"
+ const email = randomEmail()
+ const password = "weak"
+
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(
+ page.getByText("Password must be at least 8 characters"),
+ ).toBeVisible()
+})
+
+test("Sign up with mismatched passwords", async ({ page }) => {
+ const full_name = "Test User"
+ const email = randomEmail()
+ const password = "changethis"
+ const password2 = "changethat"
+
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password2)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(page.getByText("Passwords do not match")).toBeVisible()
+})
+
+test("Sign up with missing full name", async ({ page }) => {
+ const full_name = ""
+ const email = randomEmail()
+ const password = "changethis"
+
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(page.getByText("Full Name is required")).toBeVisible()
+})
+
+test("Sign up with missing email", async ({ page }) => {
+ const full_name = "Test User"
+ const email = ""
+ const password = "changethis"
+
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(page.getByText("Email is required")).toBeVisible()
+})
+
+test("Sign up with missing password", async ({ page }) => {
+ const full_name = ""
+ const email = randomEmail()
+ const password = ""
+
+ await page.goto("/signup")
+
+ await fillForm(page, full_name, email, password, password)
+ await page.getByRole("button", { name: "Sign Up" }).click()
+
+ await expect(page.getByText("Password is required")).toBeVisible()
+})
diff --git a/frontend/tests/utils/random.ts b/frontend/tests/utils/random.ts
new file mode 100644
index 0000000..bd2b43b
--- /dev/null
+++ b/frontend/tests/utils/random.ts
@@ -0,0 +1,11 @@
+export const randomEmail = () =>
+ `test_${Math.random().toString(36).substring(7)}@example.com`
+
+export const randomTeamName = () =>
+ `Team ${Math.random().toString(36).substring(7)}`
+
+export const slugify = (text: string) =>
+ text
+ .toLowerCase()
+ .replace(/\s+/g, "-")
+ .replace(/[^\w-]+/g, "")