|
1 | 1 | import { test, expect, type Page } from "@playwright/test"; |
2 | | -import { POSTHOG_TEST_BRAND_ID, signUpBrandedTestUser } from "./helpers/auth"; |
3 | | - |
4 | | -/** |
5 | | - * Navigate to the PostHog TAM Technical Onboarding course detail page. |
6 | | - * |
7 | | - * Strategy: from the dashboard, find any course card and extract the course ID. |
8 | | - * Then navigate directly to the course detail page. If the specific PostHog TAM |
9 | | - * course card is visible, click it. Otherwise, fall back to browsing. |
10 | | - */ |
11 | | -async function navigateToPosthogCourse(page: Page) { |
12 | | - // Dashboard already loaded after sign-up — find any course card |
13 | | - const courseCards = page.locator("a[href^='/browse/']"); |
14 | | - await expect(courseCards.first()).toBeVisible({ timeout: 10_000 }); |
15 | | - |
16 | | - // Look for the PostHog TAM Technical Onboarding card specifically |
17 | | - const tamCard = courseCards.filter({ hasText: "PostHog TAM Technical Onboarding" }); |
18 | | - if (await tamCard.first().isVisible({ timeout: 2_000 }).catch(() => false)) { |
19 | | - await tamCard.first().click(); |
20 | | - return; |
21 | | - } |
22 | | - |
23 | | - // If the specific card isn't on the dashboard, the course might be nested |
24 | | - // inside an academy. Click any course card to get to a browse page, then |
25 | | - // look for the TAM course from there. |
26 | | - const firstHref = await courseCards.first().getAttribute("href"); |
27 | | - const firstCourseId = firstHref?.replace("/browse/", ""); |
28 | | - |
29 | | - // Check if the first course IS the TAM onboarding (the dashboard might |
30 | | - // show it but with a truncated name) |
31 | | - await courseCards.first().click(); |
32 | | - |
33 | | - // If we're on the course detail page for the right course, we're done |
34 | | - const heading = page.getByRole("heading", { level: 1 }); |
35 | | - await expect(heading).toBeVisible({ timeout: 10_000 }); |
36 | | - const headingText = await heading.textContent(); |
| 2 | +import { PrismaClient } from "@prisma/client"; |
| 3 | +import { |
| 4 | + getSupabaseUserIdByEmail, |
| 5 | + POSTHOG_TEST_BRAND_ID, |
| 6 | + signUpBrandedTestUser, |
| 7 | +} from "./helpers/auth"; |
| 8 | + |
| 9 | +const ORG_SLUG = "posthog-tam"; |
| 10 | +const prisma = new PrismaClient(); |
| 11 | + |
| 12 | +async function grantLearnerMembership(email: string) { |
| 13 | + const userId = await getSupabaseUserIdByEmail(email); |
| 14 | + const org = await prisma.organization.findUnique({ |
| 15 | + where: { slug: ORG_SLUG }, |
| 16 | + select: { id: true }, |
| 17 | + }); |
37 | 18 |
|
38 | | - if (headingText?.includes("PostHog TAM Technical Onboarding")) { |
39 | | - return; |
| 19 | + if (!org) { |
| 20 | + throw new Error(`Organization ${ORG_SLUG} not found`); |
40 | 21 | } |
41 | 22 |
|
42 | | - // Not the right course — go back and look at other options |
43 | | - // The TAM course might be accessible from the academy page |
44 | | - const backLink = page.getByText(/Back to (Academy|Academies|Courses)/); |
45 | | - if (await backLink.isVisible({ timeout: 2_000 }).catch(() => false)) { |
46 | | - await backLink.click(); |
47 | | - await page.waitForTimeout(1_000); |
48 | | - } |
| 23 | + await prisma.orgMembership.upsert({ |
| 24 | + where: { orgId_userId: { orgId: org.id, userId } }, |
| 25 | + update: {}, |
| 26 | + create: { |
| 27 | + orgId: org.id, |
| 28 | + userId, |
| 29 | + role: "member", |
| 30 | + }, |
| 31 | + }); |
| 32 | +} |
49 | 33 |
|
50 | | - // Try navigating to browse and looking at all academies |
51 | | - await page.goto("/browse"); |
52 | | - const academyLinks = page.locator("a[href^='/academy/']"); |
53 | | - await expect(academyLinks.first()).toBeVisible({ timeout: 10_000 }); |
54 | | - |
55 | | - // Visit each academy page to find the TAM onboarding course |
56 | | - const linkCount = await academyLinks.count(); |
57 | | - for (let i = 0; i < linkCount; i++) { |
58 | | - const href = await academyLinks.nth(i).getAttribute("href"); |
59 | | - await page.goto(href!); |
60 | | - |
61 | | - const tamCourseCard = page |
62 | | - .locator("a[href^='/browse/']") |
63 | | - .filter({ hasText: /Technical Onboarding/ }); |
64 | | - |
65 | | - if (await tamCourseCard.first().isVisible({ timeout: 3_000 }).catch(() => false)) { |
66 | | - await tamCourseCard.first().click(); |
67 | | - return; |
68 | | - } |
| 34 | +async function navigateToPosthogCourse(page: Page) { |
| 35 | + const org = await prisma.organization.findUnique({ |
| 36 | + where: { slug: ORG_SLUG }, |
| 37 | + select: { |
| 38 | + courses: { |
| 39 | + where: { name: "PostHog TAM Technical Onboarding" }, |
| 40 | + select: { id: true }, |
| 41 | + take: 1, |
| 42 | + }, |
| 43 | + }, |
| 44 | + }); |
| 45 | + |
| 46 | + const courseId = org?.courses[0]?.id; |
| 47 | + if (!courseId) { |
| 48 | + throw new Error("Could not find PostHog TAM Technical Onboarding course"); |
69 | 49 | } |
70 | 50 |
|
71 | | - // Last resort: the course might be directly accessible by looking at all |
72 | | - // course cards across the page |
73 | | - throw new Error("Could not find PostHog TAM Technical Onboarding course"); |
| 51 | + await page.goto(`/browse/${courseId}`); |
74 | 52 | } |
75 | 53 |
|
76 | 54 | test.describe("Course sections display", () => { |
77 | 55 | test.beforeEach(async ({ page }) => { |
78 | | - await signUpBrandedTestUser(page, POSTHOG_TEST_BRAND_ID); |
| 56 | + const email = await signUpBrandedTestUser(page, POSTHOG_TEST_BRAND_ID); |
| 57 | + await grantLearnerMembership(email); |
| 58 | + }); |
| 59 | + |
| 60 | + test.afterAll(async () => { |
| 61 | + await prisma.$disconnect(); |
79 | 62 | }); |
80 | 63 |
|
81 | 64 | test("PostHog course detail page shows section headings", async ({ |
|
0 commit comments