Skip to content

Commit b35278e

Browse files
authored
Merge pull request #54 from kit-data-manager/tests
Add more playwright tests
2 parents 8ab926d + 62e9c24 commit b35278e

File tree

4 files changed

+371
-1
lines changed

4 files changed

+371
-1
lines changed

components/editor/add-entry-dropdown.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export const AddEntryDropdown = memo(function AddEntryDropdown(props: {
2828
<DropdownMenuTrigger asChild>
2929
<Button
3030
variant="link"
31+
id="add-property-dropdown-trigger"
3132
className="flex text items-center text-muted-foreground p-1 pb-0 mb-0 h-[30px]"
3233
>
3334
<Plus className="w-3 h-3 mr-1" />

components/editor/single-property-dropdown.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const SinglePropertyDropdown = memo(function SinglePropertyDropdown({
5757
<DropdownMenuTrigger asChild>
5858
<Button
5959
variant="outline"
60+
id={"single-property-dropdown-trigger"}
6061
className={cn("border-l-0 rounded-l-none px-2", triggerClassName)}
6162
>
6263
<EllipsisVertical className="size-4" />

tests/common.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@ export async function loadTestFolder(page: Page) {
55
await page.getByRole("button", { name: "Import Crate (.zip)" }).click()
66
await page.getByTestId("create-upload-input").setInputFiles("tests/data/TestFolder.zip")
77
}
8+
9+
export async function loadTestCrate(page: Page) {
10+
await page.goto("http://localhost:3000/editor")
11+
await page.getByRole("button", { name: "Import Crate (.zip)" }).click()
12+
await page.getByTestId("create-upload-input").setInputFiles("tests/data/TestCrate.zip")
13+
}

tests/entity-editor.test.ts

Lines changed: 363 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { test, expect } from "@playwright/test"
2-
import { loadTestFolder } from "@/tests/common"
2+
import { loadTestCrate, loadTestFolder } from "@/tests/common"
33

44
test("Edit Properties", async ({ page }) => {
55
await loadTestFolder(page)
@@ -36,3 +36,365 @@ test("Edit Properties", async ({ page }) => {
3636
await expect(page.getByText("There are unsaved changes")).not.toBeVisible()
3737
await expect(page.locator(".bg-info")).not.toBeVisible()
3838
})
39+
40+
test("Edit different Property Types (no links), then save", async ({ page }) => {
41+
await page.goto("http://localhost:3000/editor")
42+
await loadTestCrate(page)
43+
44+
await page.getByRole("textbox").first().dblclick()
45+
await page.getByRole("textbox").first().fill("Crate Root Name")
46+
await expect(page.getByRole("heading")).toContainText("Crate Root Name")
47+
await page.locator('input[type="datetime-local"]').click()
48+
await page.locator('input[type="datetime-local"]').fill("2001-10-23T23:41")
49+
await page.getByRole("textbox").nth(2).click()
50+
await page.getByRole("textbox").nth(2).fill("My Description of the Crate")
51+
await expect(page.locator(".bg-info").first()).toBeVisible()
52+
await expect(page.locator("div:nth-child(2) > .grid > .bg-info")).toBeVisible()
53+
await expect(page.locator("div:nth-child(3) > .grid > .bg-info")).toBeVisible()
54+
await expect(page.getByText("There are unsaved changes")).toBeVisible()
55+
await page.getByRole("switch").first().click()
56+
await expect(page.locator("div:nth-child(5) > .grid > .bg-info")).toBeVisible()
57+
await page.getByRole("switch").first().click()
58+
await expect(page.locator("div:nth-child(5) > .grid > .bg-info")).not.toBeVisible()
59+
await page.getByRole("switch").nth(1).click()
60+
await expect(page.locator("body")).toMatchAriaSnapshot(`
61+
- switch [checked]
62+
- text: "True"
63+
- button
64+
- switch [checked]
65+
- text: "True"
66+
- button
67+
- button "Add another entry"
68+
`)
69+
await page.getByRole("spinbutton").click()
70+
await page.getByRole("spinbutton").fill("22")
71+
await page.getByRole("textbox").nth(3).click()
72+
await page.getByRole("textbox").nth(3).fill("v29.0.2")
73+
await expect(page.locator("div:nth-child(6) > .grid > .bg-info")).toBeVisible()
74+
await expect(page.getByRole("spinbutton")).toHaveValue("22")
75+
await expect(page.getByRole("textbox").nth(3)).toHaveValue("v29.0.2")
76+
await page.getByRole("button", { name: "Save" }).click()
77+
await expect(page.getByRole("textbox").first()).toHaveValue("Crate Root Name")
78+
await expect(page.locator('input[type="datetime-local"]')).toHaveValue("2001-10-23T23:41")
79+
await expect(page.getByRole("textbox").nth(2)).toHaveValue("My Description of the Crate")
80+
await expect(page.getByRole("spinbutton")).toHaveValue("22")
81+
await expect(page.getByRole("textbox").nth(3)).toHaveValue("v29.0.2")
82+
await expect(page.locator("body")).toMatchAriaSnapshot(`
83+
- switch [checked]
84+
- text: "True"
85+
- button
86+
- switch [checked]
87+
- text: "True"
88+
- button
89+
- button "Add another entry"
90+
`)
91+
})
92+
93+
test("Change field type and change back", async ({ page }) => {
94+
await page.goto("http://localhost:3000/editor")
95+
await loadTestCrate(page)
96+
97+
await expect(page.locator("body")).toMatchAriaSnapshot(`
98+
- spinbutton: /\\d+/
99+
- button
100+
- textbox: v25.0.0
101+
- button
102+
- button "Add another entry"
103+
`)
104+
await page
105+
.locator(
106+
"div:nth-child(6) > .grid > .truncate > div > div > #single-property-dropdown-trigger"
107+
)
108+
.first()
109+
.click()
110+
await page.getByRole("menuitem", { name: "Change Type" }).click()
111+
await page.getByRole("menuitem", { name: "Text" }).click()
112+
await expect(page.locator("body")).toMatchAriaSnapshot(`
113+
- textbox: /\\d+/
114+
- button
115+
- textbox: v25.0.0
116+
- button
117+
- button "Add another entry"
118+
`)
119+
await page.getByRole("textbox").nth(3).click()
120+
await page.getByRole("textbox").nth(3).fill("25 und mehr")
121+
await page
122+
.locator(
123+
"div:nth-child(6) > .grid > .truncate > div > div > #single-property-dropdown-trigger"
124+
)
125+
.first()
126+
.click()
127+
await page.getByRole("menuitem", { name: "Change Type" }).click()
128+
await page.getByRole("menuitem", { name: "Number" }).click()
129+
await expect(page.locator("body")).toMatchAriaSnapshot(`
130+
- spinbutton: "0"
131+
- button
132+
- textbox: v25.0.0
133+
- button
134+
- button "Add another entry"
135+
`)
136+
await expect(page.locator(".bg-info")).toBeVisible()
137+
await expect(page.getByText("There are unsaved changes")).toBeVisible()
138+
await page
139+
.locator("div")
140+
.filter({ hasText: /^There are unsaved changesSave$/ })
141+
.getByRole("button")
142+
.nth(1)
143+
.click()
144+
await page.getByRole("menuitem", { name: "Revert Changes ⌘U" }).click()
145+
await expect(page.locator("body")).toMatchAriaSnapshot(`
146+
- spinbutton: 25
147+
- button
148+
- textbox: v25.0.0
149+
- button
150+
- button "Add another entry"
151+
`)
152+
})
153+
154+
test("Change field type and revert", async ({ page }) => {
155+
await page.goto("http://localhost:3000/editor")
156+
await loadTestCrate(page)
157+
158+
await page.getByRole("spinbutton").click()
159+
await page
160+
.locator(
161+
"div:nth-child(6) > .grid > .truncate > div > div > #single-property-dropdown-trigger"
162+
)
163+
.first()
164+
.click()
165+
await page.getByRole("menuitem", { name: "Change Type" }).click()
166+
await page.getByRole("menuitem", { name: "Text" }).click()
167+
await page.getByRole("textbox").nth(3).click()
168+
await page.getByRole("textbox").nth(3).fill("25 und mehr")
169+
await page
170+
.locator("div")
171+
.filter({ hasText: /^There are unsaved changesSave$/ })
172+
.getByRole("button")
173+
.nth(1)
174+
.click()
175+
await page.getByRole("menuitem", { name: "Revert Changes ⌘U" }).click()
176+
await expect(page.locator("body")).toMatchAriaSnapshot(`
177+
- textbox: 25
178+
- button
179+
- textbox: v25.0.0
180+
- button
181+
- button "Add another entry"
182+
`)
183+
})
184+
185+
test("Add Entries of different types and save", async ({ page }) => {
186+
await page.goto("http://localhost:3000/editor")
187+
await loadTestCrate(page)
188+
189+
await page
190+
.locator(
191+
"div:nth-child(6) > .grid > .truncate > div > .mt-\\[-16px\\] > #add-property-dropdown-trigger"
192+
)
193+
.click()
194+
await page.getByRole("menuitem", { name: "Text" }).click()
195+
await expect(page.getByText("Text Number")).not.toBeVisible()
196+
await page.locator("div:nth-child(4) > #add-property-dropdown-trigger").click()
197+
await page.getByRole("menuitem", { name: "Number" }).click()
198+
await page.getByRole("textbox").nth(4).click()
199+
await page.getByRole("textbox").nth(4).fill("Ein Versionstext")
200+
await page.getByRole("spinbutton").nth(1).click()
201+
await page.getByRole("spinbutton").nth(1).fill("33")
202+
await expect(page.locator(".bg-info")).toBeVisible()
203+
await expect(page.getByText("There are unsaved changes")).toBeVisible()
204+
await expect(page.locator("body")).toMatchAriaSnapshot(`
205+
- spinbutton: /\\d+/
206+
- button
207+
- textbox: v25.0.0
208+
- button
209+
- textbox: Ein Versionstext
210+
- button
211+
- spinbutton: /\\d+/
212+
- button
213+
- button "Add another entry"
214+
`)
215+
await page.getByRole("button", { name: "Save" }).click()
216+
await expect(page.locator("body")).toMatchAriaSnapshot(`
217+
- spinbutton: /\\d+/
218+
- button
219+
- textbox: v25.0.0
220+
- button
221+
- textbox: Ein Versionstext
222+
- button
223+
- spinbutton: /\\d+/
224+
- button
225+
- button "Add another entry"
226+
`)
227+
})
228+
229+
test("Add Reference and follow it", async ({ page }) => {
230+
await page.goto("http://localhost:3000/editor")
231+
await loadTestCrate(page)
232+
233+
await page
234+
.locator(
235+
"div:nth-child(4) > .grid > div:nth-child(3) > div > .mt-\\[-16px\\] > #add-property-dropdown-trigger"
236+
)
237+
.click()
238+
await page.getByRole("menuitem", { name: "Reference" }).click()
239+
await page.getByRole("button", { name: "Select" }).click()
240+
await page.getByLabel("Suggestions").getByText("FJSON Result FileFile").click()
241+
await expect(page.locator("body")).toMatchAriaSnapshot(`
242+
- button "F JSON Result File result.json"
243+
- button
244+
- button
245+
- button "F JSON Result File result.json"
246+
- button
247+
- button
248+
- button "Add another entry"
249+
`)
250+
await expect(page.locator(".bg-info")).toBeVisible()
251+
await page.getByRole("button", { name: "Save" }).click()
252+
await expect(page.locator("body")).toMatchAriaSnapshot(`
253+
- button "F JSON Result File result.json"
254+
- button
255+
- button
256+
- button "F JSON Result File result.json"
257+
- button
258+
- button
259+
- button "Add another entry"
260+
`)
261+
await page.getByRole("button", { name: "F JSON Result File result.json" }).nth(1).click()
262+
await expect(page.locator("body")).toMatchAriaSnapshot(`
263+
- heading "File JSON Result File" [level=2]:
264+
- button "File"
265+
- text: Identifier
266+
- paragraph: The unique identifier of the entity
267+
- text: result.json
268+
- button
269+
- text: Type
270+
- paragraph: The type defines which properties can occur on the entity
271+
- text: File Name
272+
- paragraph: The name of the item.
273+
- textbox: JSON Result File
274+
- button
275+
- button "Add another entry"
276+
- text: Content Size
277+
- paragraph: File size in (mega/kilo)bytes.
278+
- textbox: /\\d+/
279+
- button
280+
- button "Add another entry"
281+
- text: Encoding Format
282+
- paragraph:
283+
- text: Media type typically expressed using a MIME format (see
284+
- link "IANA site":
285+
- /url: http://www.iana.org/assignments/media-types/media-types.xhtml
286+
- text: and
287+
- link "MDN reference":
288+
- /url: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
289+
- text: ), e.g. application/zip for a SoftwareApplication binary, audio/mpeg for .mp3 etc.
290+
- paragraph:
291+
- text: In cases where a
292+
- link "CreativeWork":
293+
- /url: https://schema.org/CreativeWork
294+
- text: has several media type representations,
295+
- link "encoding":
296+
- /url: https://schema.org/encoding
297+
- text: can be used to indicate each
298+
- link "MediaObject":
299+
- /url: https://schema.org/MediaObject
300+
- text: alongside particular
301+
- link "encodingFormat":
302+
- /url: https://schema.org/encodingFormat
303+
- text: information.
304+
- paragraph: Unregistered or niche encoding and file formats can be indicated instead via the most appropriate URL, e.g. defining Web page or a Wikipedia/Wikidata entry.
305+
- textbox: application/json
306+
- button
307+
- button "Add another entry"
308+
- button "Add Property"
309+
`)
310+
})
311+
312+
test("Add many properties and test pagination", async ({ page }) => {
313+
await page.goto("http://localhost:3000/editor")
314+
await loadTestCrate(page)
315+
316+
await page
317+
.locator(
318+
"div:nth-child(6) > .grid > .truncate > div > .mt-\\[-16px\\] > #add-property-dropdown-trigger"
319+
)
320+
.click()
321+
await page.getByRole("menuitem", { name: "Text" }).click()
322+
await expect(page.getByText("Text Number")).not.toBeVisible()
323+
await page.locator("div:nth-child(4) > #add-property-dropdown-trigger").click()
324+
await page.getByRole("menuitem", { name: "Text" }).click()
325+
await expect(page.getByText("Text Number")).not.toBeVisible()
326+
await page.locator("div:nth-child(5) > #add-property-dropdown-trigger").click()
327+
await page.getByRole("menuitem", { name: "Text" }).click()
328+
await expect(page.getByText("Text Number")).not.toBeVisible()
329+
await page.locator("div:nth-child(6) > #add-property-dropdown-trigger").click()
330+
await page.getByRole("menuitem", { name: "Text" }).click()
331+
await expect(page.getByText("Text Number")).not.toBeVisible()
332+
await page.locator("div:nth-child(7) > #add-property-dropdown-trigger").click()
333+
await page.getByRole("menuitem", { name: "Text" }).click()
334+
await expect(page.getByText("Text Number")).not.toBeVisible()
335+
await page.locator("div:nth-child(8) > #add-property-dropdown-trigger").click()
336+
await page.getByRole("menuitem", { name: "Text" }).click()
337+
await expect(page.getByText("Text Number")).not.toBeVisible()
338+
await page.locator("div:nth-child(9) > #add-property-dropdown-trigger").click()
339+
await page.getByRole("menuitem", { name: "Text" }).click()
340+
await expect(page.getByText("Text Number")).not.toBeVisible()
341+
await page.locator("div:nth-child(10) > #add-property-dropdown-trigger").click()
342+
await page.getByRole("menuitem", { name: "Text" }).click()
343+
await expect(page.getByText("Text Number")).not.toBeVisible()
344+
await page.locator("div:nth-child(11) > #add-property-dropdown-trigger").click()
345+
await page.getByRole("menuitem", { name: "Text" }).click()
346+
await expect(page.getByText("Text Number")).not.toBeVisible()
347+
await page
348+
.locator("div:nth-child(2) > .mt-\\[-16px\\] > #add-property-dropdown-trigger")
349+
.click()
350+
await page.getByRole("menuitem", { name: "Text" }).click()
351+
await expect(page.getByText("Text Number")).not.toBeVisible()
352+
await expect(page.locator("body")).toMatchAriaSnapshot(`
353+
- textbox
354+
- button
355+
- textbox
356+
- button
357+
- button "Add another entry"
358+
- button
359+
- button "2 / 2"
360+
- button
361+
`)
362+
await page
363+
.locator("div")
364+
.filter({ hasText: /^2 \/ 2$/ })
365+
.getByRole("button")
366+
.first()
367+
.click()
368+
await expect(page.locator("body")).toMatchAriaSnapshot(`
369+
- spinbutton: /\\d+/
370+
- button
371+
- textbox: v25.0.0
372+
- button
373+
- textbox
374+
- button
375+
- textbox
376+
- button
377+
- textbox
378+
- button
379+
- textbox
380+
- button
381+
- textbox
382+
- button
383+
- textbox
384+
- button
385+
- textbox
386+
- button
387+
- textbox
388+
- button
389+
- button "Add another entry"
390+
- button
391+
- button "1 / 2"
392+
- button
393+
`)
394+
await page.getByRole("button", { name: "/ 2" }).click()
395+
await page.getByRole("dialog").getByRole("spinbutton").fill("2")
396+
await page.getByRole("dialog").getByRole("button").click()
397+
await expect(page.getByRole("dialog")).toContainText(
398+
"There are 2 pages with 10 entries per page. In total, there are 12 entries."
399+
)
400+
})

0 commit comments

Comments
 (0)