1
18import { test, expect } from "../fixtures";
19import { createPage } from "../utils/api";
20import { waitForCondition } from "../utils/wait";
21
22const unique = (prefix: string) =>
23 `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
24
25test.describe("Search — Phase 9", () => {
26 test("create page with unique text → /search finds it in < 5s", async ({
27 authPage,
28 api,
29 freshWorkspace,
30 }) => {
31 const ws = await freshWorkspace("Search Space");
32 const token = unique("ZEBRAQUINCE");
33 await createPage(api, ws.id, { title: `${token} Quarterly Review` });
34
35
36 await authPage.goto(`/w/${ws.id}`);
37 await authPage.getByTestId("search-button").click();
38 await expect(authPage.getByTestId("search-dialog")).toBeVisible();
39
40
41 const input = authPage.getByTestId("search-input");
42 const started = Date.now();
43 await input.fill(token);
44 await waitForCondition(
45 authPage,
46 () => authPage.getByTestId("search-result").first().isVisible(),
47 { timeoutMs: 5_000, message: `no search result for ${token} within 5s` },
48 );
49 const elapsedMs = Date.now() - started;
50 expect(elapsedMs, `search took ${elapsedMs}ms (target < 5000ms)`).toBeLessThan(5_000);
51
52 const result = authPage.getByTestId("search-result").first();
53 await expect(result).toContainText(token);
54 });
55
56 test("filter results by type (page vs database)", async ({
57 authPage,
58 api,
59 freshWorkspace,
60 }) => {
61 const ws = await freshWorkspace("Search Filter Space");
62 const token = unique("FILTERME");
63 await createPage(api, ws.id, { title: `${token} Page Doc` });
64
65
66
67
68 const dbRes = await api.post(`/api/v1/workspaces/${ws.id}/pages`, {
69 data: { title: `${token} Data Table`, type: "database" },
70 });
71 expect(dbRes.status()).toBe(201);
72
73 await authPage.goto(`/w/${ws.id}`);
74 await authPage.getByTestId("search-button").click();
75 await authPage.getByTestId("search-input").fill(token);
76 await expect(authPage.getByTestId("search-result").first()).toBeVisible({
77 timeout: 10_000,
78 });
79
80
81 await expect(authPage.getByTestId("search-result-type-page").first()).toBeVisible({
82 timeout: 10_000,
83 });
84 await expect(
85 authPage.getByTestId("search-result-type-database").first(),
86 ).toBeVisible({ timeout: 10_000 });
87
88
89 await authPage.getByTestId("search-filter-type").click();
90 await authPage.getByTestId("search-filter-option-page").click();
91 await expect(authPage.getByTestId("search-result-type-page").first()).toBeVisible();
92 await expect(authPage.getByTestId("search-result-type-database")).toHaveCount(0);
93
94
95 await authPage.getByTestId("search-filter-type").click();
96 await authPage.getByTestId("search-filter-option-database").click();
97 await expect(
98 authPage.getByTestId("search-result-type-database").first(),
99 ).toBeVisible();
100 await expect(authPage.getByTestId("search-result-type-page")).toHaveCount(0);
101 });
102
103 test("recent searches are shown after closing the dialog", async ({
104 authPage,
105 api,
106 freshWorkspace,
107 }) => {
108 const ws = await freshWorkspace("Recent Space");
109 const token = unique("RECENT");
110 await createPage(api, ws.id, { title: `${token} Doc` });
111
112 await authPage.goto(`/w/${ws.id}`);
113
114 await authPage.getByTestId("search-button").click();
115 await authPage.getByTestId("search-input").fill(token);
116 await expect(authPage.getByTestId("search-result").first()).toBeVisible({
117 timeout: 10_000,
118 });
119 await authPage.keyboard.press("Escape");
120
121
122 await authPage.getByTestId("search-button").click();
123 await expect(authPage.getByTestId("search-recent")).toBeVisible({ timeout: 5_000 });
124 const recentItem = authPage.getByTestId("search-recent-item").filter({ hasText: token });
125 await expect(recentItem).toBeVisible();
126
127 await recentItem.click();
128 await expect(authPage.getByTestId("search-result").first()).toBeVisible({
129 timeout: 10_000,
130 });
131 });
132
133 test("suggestions appear while typing", async ({
134 authPage,
135 api,
136 freshWorkspace,
137 }) => {
138 const ws = await freshWorkspace("Suggest Space");
139 const token = unique("SUGGEST");
140 await createPage(api, ws.id, { title: `${token} Alpha Report` });
141 await createPage(api, ws.id, { title: `${token} Beta Report` });
142
143 await authPage.goto(`/w/${ws.id}`);
144 await authPage.getByTestId("search-button").click();
145 const input = authPage.getByTestId("search-input");
146
147
148 await input.pressSequentially(token, { delay: 30 });
149 const suggestions = authPage.getByTestId("search-suggestion");
150 await expect
151 .poll(async () => suggestions.count(), { timeout: 10_000 })
152 .toBeGreaterThanOrEqual(1);
153
154 await expect
155 .poll(async () => suggestions.count(), { timeout: 10_000 })
156 .toBeGreaterThanOrEqual(2);
157 });
158});
159