Skip to content

Commit 3d5ef07

Browse files
committed
test(dashboard): assert seeded analytics dynamically
1 parent 28736f5 commit 3d5ef07

3 files changed

Lines changed: 67 additions & 11 deletions

File tree

apps/dashboard/app/api/test/e2e/clickhouse/route.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,24 @@ export async function POST(request: Request): Promise<Response> {
109109
};
110110
});
111111

112+
const screenViewEvents = events.filter(
113+
(event) => event.event_name === "screen_view"
114+
);
115+
const screenViewsByCountry = screenViewEvents.reduce<Record<string, number>>(
116+
(acc, event) => {
117+
acc[event.country] = (acc[event.country] ?? 0) + 1;
118+
return acc;
119+
},
120+
{}
121+
);
122+
const screenViewsByPath = screenViewEvents.reduce<Record<string, number>>(
123+
(acc, event) => {
124+
acc[event.path] = (acc[event.path] ?? 0) + 1;
125+
return acc;
126+
},
127+
{}
128+
);
129+
112130
const outgoingLinks = sessions
113131
.slice(0, Math.ceil(eventCount / 20))
114132
.map((session) => ({
@@ -138,6 +156,9 @@ export async function POST(request: Request): Promise<Response> {
138156
return Response.json({
139157
events: events.length,
140158
outgoingLinks: outgoingLinks.length,
159+
screenViews: screenViewEvents.length,
160+
screenViewsByCountry,
161+
screenViewsByPath,
141162
seeded: true,
142163
websiteId: body.websiteId,
143164
});

apps/dashboard/test/e2e/fixtures.ts

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import { test as base } from "@playwright/test";
22

3+
interface E2EAnalyticsSeed {
4+
events: number;
5+
outgoingLinks: number;
6+
screenViews: number;
7+
screenViewsByCountry: Record<string, number>;
8+
screenViewsByPath: Record<string, number>;
9+
seeded: true;
10+
websiteId: string;
11+
}
12+
313
interface E2ESession {
14+
analyticsSeed: E2EAnalyticsSeed | null;
415
email: string;
516
name: string;
617
organizationId: string;
@@ -34,9 +45,9 @@ function testScope(testTitle: string): string {
3445
async function seedClickHouse(
3546
request: import("@playwright/test").APIRequestContext,
3647
websiteId: string
37-
): Promise<void> {
48+
): Promise<E2EAnalyticsSeed | null> {
3849
if (process.env.DATABUDDY_E2E_SEED_CLICKHOUSE !== "1") {
39-
return;
50+
return null;
4051
}
4152

4253
const response = await request.post("/api/test/e2e/clickhouse", {
@@ -52,6 +63,8 @@ async function seedClickHouse(
5263
`E2E ClickHouse seed failed with ${response.status()}: ${await response.text()}`
5364
);
5465
}
66+
67+
return (await response.json()) as E2EAnalyticsSeed;
5568
}
5669

5770
export const test = base.extend<E2EFixtures>({
@@ -72,11 +85,14 @@ export const test = base.extend<E2EFixtures>({
7285
`E2E session bootstrap failed with ${response.status()}: ${await response.text()}`
7386
);
7487
}
75-
const session = (await response.json()) as E2ESession;
76-
if (session.websiteId) {
77-
await seedClickHouse(page.context().request, session.websiteId);
78-
}
79-
await use(session);
88+
const session = (await response.json()) as Omit<
89+
E2ESession,
90+
"analyticsSeed"
91+
>;
92+
const analyticsSeed = session.websiteId
93+
? await seedClickHouse(page.context().request, session.websiteId)
94+
: null;
95+
await use({ ...session, analyticsSeed });
8096
},
8197
authenticatedPage: async ({ e2eSession: _session, page }, use) => {
8298
await use(page);

apps/dashboard/test/e2e/specs/regressions/website-analytics.spec.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { expect, test } from "@/test/e2e/fixtures";
22

3+
function formattedCount(value: number): string {
4+
return new Intl.NumberFormat("en-US").format(value);
5+
}
6+
37
test(
48
"renders analytics controls in the website topbar",
59
{ tag: ["@regression", "@core"] },
@@ -32,10 +36,22 @@ test(
3236

3337
await authenticatedPage.goto(`/demo/${e2eSession.websiteId}`);
3438

35-
await expect(authenticatedPage.getByText("187").first()).toBeVisible({
36-
timeout: 20_000,
37-
});
38-
await expect(authenticatedPage.getByText("/pricing").first()).toBeVisible();
39+
expect(e2eSession.analyticsSeed).toBeTruthy();
40+
const seed = e2eSession.analyticsSeed;
41+
if (!seed) {
42+
throw new Error("Expected E2E analytics seed metadata");
43+
}
44+
45+
await expect(
46+
authenticatedPage.getByText(formattedCount(seed.screenViews)).first()
47+
).toBeVisible({ timeout: 20_000 });
48+
const topSeededPath = Object.entries(seed.screenViewsByPath).sort(
49+
([, a], [, b]) => b - a
50+
)[0]?.[0];
51+
expect(topSeededPath).toBeTruthy();
52+
await expect(
53+
authenticatedPage.getByText(topSeededPath ?? "/").first()
54+
).toBeVisible();
3955

4056
const topbar = authenticatedPage.getByRole("toolbar", {
4157
name: "Dashboard top bar",
@@ -50,5 +66,8 @@ test(
5066
const main = authenticatedPage.getByRole("main");
5167
await expect(main.getByText("Country")).toBeVisible();
5268
await expect(main.getByText("US", { exact: true })).toBeVisible();
69+
await expect(
70+
main.getByText(formattedCount(seed.screenViewsByCountry.US ?? 0)).first()
71+
).toBeVisible({ timeout: 20_000 });
5372
}
5473
);

0 commit comments

Comments
 (0)