Skip to content

Commit 018a8f4

Browse files
committed
fix: fix e2e tests for mobile
1 parent 1c6436b commit 018a8f4

13 files changed

Lines changed: 169 additions & 38 deletions

File tree

e2e_tests/tests_omni_full/justfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ default:
66
# Install dependencies
77
install:
88
pnpm install
9+
pnpm exec playwright install --with-deps
910

1011
# Run e2e tests
1112
test:

e2e_tests/tests_omni_full/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"version": "0.0.0",
55
"type": "module",
66
"scripts": {
7-
"test:all": "playwright test",
87
"test": "playwright test",
98
"test:mobile": "playwright test --project=mobile-chrome --project=mobile-safari",
109
"test:headed": "playwright test --headed",

e2e_tests/tests_omni_full/playwright.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { defineConfig, devices } from "@playwright/test";
33
export default defineConfig({
44
testDir: ".",
55
testMatch: "*.spec.ts",
6+
timeout: 10000,
67
fullyParallel: false,
78
forbidOnly: !!process.env.CI,
89
workers: 1,

e2e_tests/tests_omni_full/src/chat.spec.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ test.describe("Chat", () => {
2020
"http://localhost:3001",
2121
"",
2222
);
23+
await page
24+
.getByText("How can I help you today?")
25+
.waitFor({ state: "visible", timeout: 20000 });
2326
});
2427

2528
test("should send a message and receive a response", async ({ page }) => {

e2e_tests/tests_omni_full/src/login.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ test.describe("Login", () => {
1212

1313
// The auth guard calls /api/auth/session → unauthenticated
1414
// → redirect to /api/auth/login → NanoIDP authorize endpoint on port 9000
15-
await page.waitForURL(/localhost:9000/, { timeout: 15000 });
15+
await page.waitForURL(/localhost:9000/, { timeout: 10000 });
1616
await expect(page).toHaveURL(/localhost:9000/);
1717
});
1818

e2e_tests/tests_omni_full/src/pages.ts

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
import { expect, type Page } from "@playwright/test";
22

3+
export class General {
4+
constructor(private page: Page) {}
5+
6+
async isMobile(): Promise<boolean> {
7+
const viewport = this.page.viewportSize();
8+
return viewport !== null && viewport.width < 768;
9+
}
10+
}
11+
312
/**
413
* Sets up an LLM provider via the backend API.
514
*
@@ -80,11 +89,11 @@ export class NanoIdpLoginPage {
8089

8190
// Fill username and password (single-step form)
8291
const usernameInput = this.page.locator("#username");
83-
await usernameInput.waitFor({ state: "visible", timeout: 15000 });
92+
await usernameInput.waitFor({ state: "visible", timeout: 5000 });
8493
await usernameInput.fill(username);
8594

8695
const passwordInput = this.page.locator("#password");
87-
await passwordInput.waitFor({ state: "visible", timeout: 15000 });
96+
await passwordInput.waitFor({ state: "visible", timeout: 5000 });
8897
await passwordInput.fill(password);
8998

9099
await this.page.getByRole("button", { name: /authorize/i }).click();
@@ -93,7 +102,7 @@ export class NanoIdpLoginPage {
93102
await this.page.waitForURL(/localhost:4173/, { timeout: 30000 });
94103

95104
// Wait for the Svelte auth guard to finish checking session
96-
await this.page.waitForSelector("header", { timeout: 15000 });
105+
await this.page.waitForSelector("header", { timeout: 5000 });
97106
}
98107
}
99108

@@ -107,9 +116,9 @@ export class ChatPage {
107116
}
108117

109118
async navigateTo(): Promise<void> {
110-
await this.page
111-
.getByRole("button", { name: "Chat", exact: true })
112-
.click();
119+
const sidebar = new Sidebar(this.page);
120+
await sidebar.navigateTo("Chat");
121+
await expect(this.page).toHaveURL("/chat");
113122
}
114123

115124
async selectFirstModel(): Promise<void> {
@@ -132,20 +141,64 @@ export class ChatPage {
132141
const input = this.page.getByRole("textbox", {
133142
name: "Type a message...",
134143
});
135-
await expect(input).toBeEnabled({ timeout: 15000 });
144+
await expect(input).toBeEnabled({ timeout: 5000 });
136145
await input.fill(message);
137146
await this.page.getByRole("button", { name: "Send" }).click();
138147
}
139148

140-
async assertModelButtonVisible(modelName: string): Promise<void> {
141-
await expect(
142-
this.page.getByRole("button", { name: modelName }),
143-
).toBeVisible({ timeout: 10000 });
144-
}
145-
146149
async assertLastResponse(content: string): Promise<void> {
147150
await expect(
148151
this.page.locator(".bg-muted.rounded-2xl").last(),
149-
).toContainText(content, { timeout: 15000 });
152+
).toContainText(content, { timeout: 5000 });
153+
}
154+
}
155+
156+
export class Sidebar {
157+
constructor(private page: Page) {}
158+
159+
async isOpen(): Promise<boolean> {
160+
const general = new General(this.page);
161+
if (await general.isMobile()) {
162+
// Mobile: sidebar renders as a Sheet — only present in DOM when open
163+
return (
164+
(await this.page.locator('[data-mobile="true"]').count()) > 0
165+
);
166+
}
167+
// Desktop: outer sidebar div carries data-state
168+
const state = await this.page
169+
.locator('[data-slot="sidebar"]')
170+
.getAttribute("data-state");
171+
return state === "expanded";
172+
}
173+
174+
async open(): Promise<void> {
175+
if (!(await this.isOpen())) {
176+
await this.page
177+
.getByRole("button", { name: "Toggle navigation", exact: true })
178+
.first()
179+
.click();
180+
}
181+
}
182+
183+
async close(): Promise<void> {
184+
if (await this.isOpen()) {
185+
await this.page
186+
.getByRole("button", { name: "Toggle navigation", exact: true })
187+
.last()
188+
.click();
189+
}
190+
}
191+
192+
async navigateTo(sidebarItem: string): Promise<void> {
193+
const wasOpen = await this.isOpen();
194+
195+
await this.open();
196+
await this.page
197+
.getByRole("button", { name: sidebarItem, exact: true })
198+
.click();
199+
200+
if (!wasOpen) {
201+
await this.close();
202+
}
150203
}
151204
}

e2e_tests/tests_omni_full/src/router.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ test.describe("Router", () => {
1919
}) => {
2020
await page.goto("/missing-route");
2121

22-
// Assert we're still on the unknown route (not redirected)
23-
expect(page.url()).toContain("/missing-route");
22+
// Redirected to fallback route
23+
await page.waitForURL("/chat", { timeout: 5000 });
2424

2525
// Assert the chat component is rendered
2626
await expect(

e2e_tests/tests_omni_light/justfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ default:
66
# Install dependencies
77
install:
88
pnpm install
9+
pnpm exec playwright install --with-deps
910

1011
# Run e2e tests
1112
test:

e2e_tests/tests_omni_light/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
"version": "0.0.0",
55
"type": "module",
66
"scripts": {
7-
"test:all": "playwright test",
87
"test": "playwright test",
98
"test:mobile": "playwright test --project=mobile-chrome --project=mobile-safari",
109
"test:debug": "playwright test --debug",

e2e_tests/tests_omni_light/playwright.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { defineConfig, devices } from "@playwright/test";
33
export default defineConfig({
44
testDir: ".",
55
testMatch: "*.spec.ts",
6-
fullyParallel: true,
6+
timeout: 10000,
7+
fullyParallel: false,
78
forbidOnly: !!process.env.CI,
89
workers: 1,
910
reporter: [

0 commit comments

Comments
 (0)