← full-stack-fastapi-template  /  frontend/tests/items.spec.ts

1
import { expect, test } from "@playwright/test"
2
import { createUser } from "./utils/privateApi"
3
import {
4
  randomEmail,
5
  randomItemDescription,
6
  randomItemTitle,
7
  randomPassword,
8
} from "./utils/random"
9
import { logInUser } from "./utils/user"
10
11
test("Items page is accessible and shows correct title", async ({ page }) => {
12
  await page.goto("/items")
13
  await expect(page.getByRole("heading", { name: "Items" })).toBeVisible()
14
  await expect(page.getByText("Create and manage your items")).toBeVisible()
15
})
16
17
test("Add Item button is visible", async ({ page }) => {
18
  await page.goto("/items")
19
  await expect(page.getByRole("button", { name: "Add Item" })).toBeVisible()
20
})
21
22
test.describe("Items management", () => {
23
  test.use({ storageState: { cookies: [], origins: [] } })
24
  let email: string
25
  const password = randomPassword()
26
27
  test.beforeAll(async () => {
28
    email = randomEmail()
29
    await createUser({ email, password })
30
  })
31
32
  test.beforeEach(async ({ page }) => {
33
    await logInUser(page, email, password)
34
    await page.goto("/items")
35
  })
36
37
  test("Create a new item successfully", async ({ page }) => {
38
    const title = randomItemTitle()
39
    const description = randomItemDescription()
40
41
    await page.getByRole("button", { name: "Add Item" }).click()
42
    await page.getByLabel("Title").fill(title)
43
    await page.getByLabel("Description").fill(description)
44
    await page.getByRole("button", { name: "Save" }).click()
45
46
    await expect(page.getByText("Item created successfully")).toBeVisible()
47
    await expect(page.getByText(title)).toBeVisible()
48
  })
49
50
  test("Create item with only required fields", async ({ page }) => {
51
    const title = randomItemTitle()
52
53
    await page.getByRole("button", { name: "Add Item" }).click()
54
    await page.getByLabel("Title").fill(title)
55
    await page.getByRole("button", { name: "Save" }).click()
56
57
    await expect(page.getByText("Item created successfully")).toBeVisible()
58
    await expect(page.getByText(title)).toBeVisible()
59
  })
60
61
  test("Cancel item creation", async ({ page }) => {
62
    await page.getByRole("button", { name: "Add Item" }).click()
63
    await page.getByLabel("Title").fill("Test Item")
64
    await page.getByRole("button", { name: "Cancel" }).click()
65
66
    await expect(page.getByRole("dialog")).not.toBeVisible()
67
  })
68
69
  test("Title is required", async ({ page }) => {
70
    await page.getByRole("button", { name: "Add Item" }).click()
71
    await page.getByLabel("Title").fill("")
72
    await page.getByLabel("Title").blur()
73
74
    await expect(page.getByText("Title is required")).toBeVisible()
75
  })
76
77
  test.describe("Edit and Delete", () => {
78
    let itemTitle: string
79
80
    test.beforeEach(async ({ page }) => {
81
      itemTitle = randomItemTitle()
82
83
      await page.getByRole("button", { name: "Add Item" }).click()
84
      await page.getByLabel("Title").fill(itemTitle)
85
      await page.getByRole("button", { name: "Save" }).click()
86
      await expect(page.getByText("Item created successfully")).toBeVisible()
87
      await expect(page.getByRole("dialog")).not.toBeVisible()
88
    })
89
90
    test("Edit an item successfully", async ({ page }) => {
91
      const itemRow = page.getByRole("row").filter({ hasText: itemTitle })
92
      await itemRow.getByRole("button").last().click()
93
      await page.getByRole("menuitem", { name: "Edit Item" }).click()
94
95
      const updatedTitle = randomItemTitle()
96
      await page.getByLabel("Title").fill(updatedTitle)
97
      await page.getByRole("button", { name: "Save" }).click()
98
99
      await expect(page.getByText("Item updated successfully")).toBeVisible()
100
      await expect(page.getByText(updatedTitle)).toBeVisible()
101
    })
102
103
    test("Delete an item successfully", async ({ page }) => {
104
      const itemRow = page.getByRole("row").filter({ hasText: itemTitle })
105
      await itemRow.getByRole("button").last().click()
106
      await page.getByRole("menuitem", { name: "Delete Item" }).click()
107
108
      await page.getByRole("button", { name: "Delete" }).click()
109
110
      await expect(
111
        page.getByText("The item was deleted successfully"),
112
      ).toBeVisible()
113
      await expect(page.getByText(itemTitle)).not.toBeVisible()
114
    })
115
  })
116
})
117
118
test.describe("Items empty state", () => {
119
  test.use({ storageState: { cookies: [], origins: [] } })
120
121
  test("Shows empty state message when no items exist", async ({ page }) => {
122
    const email = randomEmail()
123
    const password = randomPassword()
124
    await createUser({ email, password })
125
    await logInUser(page, email, password)
126
127
    await page.goto("/items")
128
129
    await expect(page.getByText("You don't have any items yet")).toBeVisible()
130
    await expect(page.getByText("Add a new item to get started")).toBeVisible()
131
  })
132
})
133