Skip to content

Commit 83e50d3

Browse files
committed
test: add more tests
1 parent bcd84b5 commit 83e50d3

File tree

6 files changed

+115
-68
lines changed

6 files changed

+115
-68
lines changed

frontend_omni/tests/Caddyfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
:80 {
2+
root * /usr/share/caddy
3+
try_files {path} {path}/ /index.html
4+
file_server
5+
}

frontend_omni/tests/container.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { execSync } from "child_process";
2+
import * as net from "net";
3+
4+
const TEST_PORT = 8088;
5+
6+
async function waitForPort(
7+
port: number,
8+
host: string = "localhost",
9+
timeout: number = 10000,
10+
): Promise<void> {
11+
const startTime = Date.now();
12+
while (Date.now() - startTime < timeout) {
13+
try {
14+
await new Promise<void>((resolve, reject) => {
15+
const socket = net.createConnection({ port, host }, () => {
16+
socket.destroy();
17+
resolve();
18+
});
19+
socket.on("error", () => {
20+
reject();
21+
});
22+
});
23+
return;
24+
} catch {
25+
await new Promise((resolve) => setTimeout(resolve, 500));
26+
}
27+
}
28+
throw new Error(`Port ${port} on ${host} not available after ${timeout}ms`);
29+
}
30+
31+
export async function buildApp() {
32+
console.log("Building the app...");
33+
execSync("pnpm build", { stdio: "inherit" });
34+
}
35+
36+
export async function startContainer() {
37+
console.log(`Starting Caddy container (In dir ${process.cwd()})...`);
38+
execSync(`docker container rm -f caddy-uitest || true`, {
39+
stdio: "ignore",
40+
});
41+
execSync(
42+
`docker run --rm -d --name caddy-uitest -p ${TEST_PORT}:80 -v ${process.cwd()}/dist:/usr/share/caddy -v ${process.cwd()}/tests/Caddyfile:/etc/caddy/Caddyfile caddy`,
43+
{ stdio: "inherit" },
44+
);
45+
46+
await waitForPort(TEST_PORT);
47+
}
48+
49+
export async function stopContainer() {
50+
try {
51+
console.log("Stopping Caddy container...");
52+
execSync("docker container rm -f caddy-uitest || true", {
53+
stdio: "ignore",
54+
});
55+
} catch (error) {
56+
console.warn("Failed to stop Caddy container:", error);
57+
}
58+
}

frontend_omni/tests/features/app_load.feature

Lines changed: 0 additions & 6 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
Feature: App loads successfully
2+
3+
Scenario: User opens the app
4+
When I visit the homepage
5+
Then I should see the page title contains "modAI"
6+
7+
Scenario Outline: User gets redirected to /chat as fallback
8+
When I visit the url path "<url>"
9+
Then the url path should be "/chat"
10+
11+
Examples:
12+
| url |
13+
| / |
14+
| /chat |
15+
| /foo |

frontend_omni/tests/steps.ts

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,42 @@
1-
import { Given, When, Then, After } from "@cucumber/cucumber";
1+
import {
2+
When,
3+
Then,
4+
BeforeAll,
5+
AfterAll,
6+
Before,
7+
After,
8+
} from "@cucumber/cucumber";
29
import { CustomWorld, TEST_PORT } from "./world.ts";
10+
import { buildApp, startContainer, stopContainer } from "./container.ts";
311

4-
Given("the app is running", async function (this: CustomWorld) {
12+
BeforeAll(async () => {
13+
await buildApp();
14+
await startContainer();
15+
});
16+
17+
AfterAll(async () => {
18+
await stopContainer();
19+
});
20+
21+
Before(async function (this: CustomWorld) {
522
await this.init();
623
});
724

25+
After(async function (this: CustomWorld) {
26+
await this.close();
27+
});
28+
829
When("I visit the homepage", async function (this: CustomWorld) {
930
await this.page.goto(`http://localhost:${TEST_PORT}`);
1031
});
1132

33+
When(
34+
"I visit the url path {string}",
35+
async function (this: CustomWorld, path: string) {
36+
await this.page.goto(`http://localhost:${TEST_PORT}${path}`);
37+
},
38+
);
39+
1240
Then(
1341
"I should see the page title contains {string}",
1442
async function (this: CustomWorld, expectedTitle: string) {
@@ -21,6 +49,10 @@ Then(
2149
},
2250
);
2351

24-
After(async function (this: CustomWorld) {
25-
await this.close();
26-
});
52+
Then(
53+
"the url path should be {string}",
54+
async function (this: CustomWorld, expectedPath: string) {
55+
const expectedUrl = `http://localhost:${TEST_PORT}${expectedPath}`;
56+
await this.page.waitForURL(expectedUrl);
57+
},
58+
);

frontend_omni/tests/world.ts

Lines changed: 0 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,21 @@
11
import { setWorldConstructor } from "@cucumber/cucumber";
22
import * as playwright from "playwright";
3-
import { execSync } from "child_process";
4-
import * as net from "net";
53

64
const TEST_PORT = 8088;
75

86
export { TEST_PORT };
97

10-
async function waitForPort(
11-
port: number,
12-
host: string = "localhost",
13-
timeout: number = 30000,
14-
): Promise<void> {
15-
const startTime = Date.now();
16-
while (Date.now() - startTime < timeout) {
17-
try {
18-
await new Promise<void>((resolve, reject) => {
19-
const socket = net.createConnection({ port, host }, () => {
20-
socket.destroy();
21-
resolve();
22-
});
23-
socket.on("error", () => {
24-
reject();
25-
});
26-
});
27-
return;
28-
} catch {
29-
await new Promise((resolve) => setTimeout(resolve, 500));
30-
}
31-
}
32-
throw new Error(`Port ${port} on ${host} not available after ${timeout}ms`);
33-
}
34-
358
export class CustomWorld {
369
browser!: playwright.Browser;
3710
context!: playwright.BrowserContext;
3811
page!: playwright.Page;
3912

4013
async init() {
41-
// Build the app
42-
console.log("Building the app...");
43-
execSync("pnpm build", { stdio: "inherit" });
44-
45-
// Start Caddy container
46-
console.log("Starting Caddy container...");
47-
execSync(`docker container rm -f caddy-uitest || true`, {
48-
stdio: "ignore",
49-
});
50-
execSync(
51-
`docker run --rm -d --name caddy-uitest -p ${TEST_PORT}:80 -v ${process.cwd()}/dist:/usr/share/caddy caddy`,
52-
{ stdio: "inherit" },
53-
);
54-
55-
// Wait for container to start
56-
console.log("Waiting for Caddy to be ready...");
57-
await waitForPort(TEST_PORT);
58-
59-
console.log("Launching browser...");
6014
this.browser = await playwright.chromium.launch({
6115
headless: process.env.HEADED !== "true",
6216
});
6317
this.context = await this.browser.newContext();
6418
this.page = await this.context.newPage();
65-
66-
console.log("Init done");
6719
}
6820

6921
async close() {
@@ -78,15 +30,6 @@ export class CustomWorld {
7830
} catch (error) {
7931
console.warn("Failed to close browser:", error);
8032
}
81-
82-
try {
83-
console.log("Stopping Caddy container...");
84-
execSync("docker container rm -f caddy-uitest || true", {
85-
stdio: "ignore",
86-
});
87-
} catch (error) {
88-
console.warn("Failed to stop Caddy container:", error);
89-
}
9033
}
9134
}
9235

0 commit comments

Comments
 (0)