diff --git a/playwright/session-recording/opting-out.spec.ts b/playwright/session-recording/opting-out.spec.ts index fc70f6c91..63dc7bbd3 100644 --- a/playwright/session-recording/opting-out.spec.ts +++ b/playwright/session-recording/opting-out.spec.ts @@ -1,4 +1,4 @@ -import { expect, test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { expect, test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' import { BrowserContext, Page } from '@playwright/test' import { PostHogConfig } from '../../src/types' @@ -57,10 +57,10 @@ test.describe('Session Recording - opting out', () => { await startWith({ opt_out_capturing_by_default: true }, page, context) await page.waitingForNetworkCausedBy(['**/recorder.js*'], async () => { - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.opt_in_capturing() - ph?.startSessionRecording() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.opt_in_capturing() + ph.startSessionRecording() }) }) @@ -78,9 +78,9 @@ test.describe('Session Recording - opting out', () => { await page.waitingForNetworkCausedBy(['**/recorder.js*'], async () => { await page.resetCapturedEvents() - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.startSessionRecording() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.startSessionRecording() }) }) diff --git a/playwright/session-recording/session-recording-array-full.spec.ts b/playwright/session-recording/session-recording-array-full.spec.ts index a40cc2bb6..32d544dbe 100644 --- a/playwright/session-recording/session-recording-array-full.spec.ts +++ b/playwright/session-recording/session-recording-array-full.spec.ts @@ -1,4 +1,4 @@ -import { expect, test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { expect, test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' const startOptions = { @@ -23,9 +23,9 @@ test.describe('session recording in array.full.js', () => { await page.locator('[data-cy-input]').fill('hello posthog!') }) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.capture('test_registered_property') + await page.evaluate(async () => { + const ph = await page.posthog() + ph.capture('test_registered_property') }) await page.expectCapturedEventsToBe(['$pageview', '$snapshot', 'test_registered_property']) diff --git a/playwright/session-recording/session-recording-ingestion-controls.spec.ts b/playwright/session-recording/session-recording-ingestion-controls.spec.ts index a2d251c3f..dbbf1581c 100644 --- a/playwright/session-recording/session-recording-ingestion-controls.spec.ts +++ b/playwright/session-recording/session-recording-ingestion-controls.spec.ts @@ -1,4 +1,4 @@ -import { test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' import { assertThatRecordingStarted, pollUntilEventCaptured } from '../utils/event-capture-utils' @@ -30,19 +30,19 @@ test.describe('Session recording - multiple ingestion controls', () => { test('respects sampling when overriding linked flag', async ({ page }) => { await page.waitingForNetworkCausedBy(['**/recorder.js*'], async () => { - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.opt_in_capturing() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.opt_in_capturing() // this won't start recording because of the linked flag and sample rate - ph?.startSessionRecording() + ph.startSessionRecording() }) }) await page.expectCapturedEventsToBe(['$opt_in', '$pageview']) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.startSessionRecording({ linked_flag: true }) + await page.evaluate(async () => { + const ph = await page.posthog() + ph.startSessionRecording({ linked_flag: true }) }) await page.locator('[data-cy-input]').type('hello posthog!') // there's nothing to wait for... so, just wait a bit @@ -51,10 +51,10 @@ test.describe('Session recording - multiple ingestion controls', () => { await page.expectCapturedEventsToBe(['$opt_in', '$pageview']) await page.resetCapturedEvents() - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog + await page.evaluate(async () => { + const ph = await page.posthog() // override all controls - ph?.startSessionRecording(true) + ph.startSessionRecording(true) }) await page.locator('[data-cy-input]').type('hello posthog!') await pollUntilEventCaptured(page, '$snapshot') diff --git a/playwright/session-recording/session-recording-linked-flags.spec.ts b/playwright/session-recording/session-recording-linked-flags.spec.ts index 31fbbb844..7ecfa7061 100644 --- a/playwright/session-recording/session-recording-linked-flags.spec.ts +++ b/playwright/session-recording/session-recording-linked-flags.spec.ts @@ -1,4 +1,4 @@ -import { test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' import { assertThatRecordingStarted, pollUntilEventCaptured } from '../utils/event-capture-utils' @@ -28,20 +28,20 @@ test.describe('Session recording - linked flags', () => { test('can opt in and override linked flag', async ({ page }) => { await page.waitingForNetworkCausedBy(['**/recorder.js*'], async () => { - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.opt_in_capturing() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.opt_in_capturing() // starting does not begin recording because of the linked flag - ph?.startSessionRecording() + ph.startSessionRecording() }) }) await page.expectCapturedEventsToBe(['$opt_in', '$pageview']) await page.resetCapturedEvents() - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.startSessionRecording({ linked_flag: true }) + await page.evaluate(async () => { + const ph = await page.posthog() + ph.startSessionRecording({ linked_flag: true }) }) await page.locator('[data-cy-input]').type('hello posthog!') await pollUntilEventCaptured(page, '$snapshot') diff --git a/playwright/session-recording/session-recording-sampling.spec.ts b/playwright/session-recording/session-recording-sampling.spec.ts index 9d4237f22..3fcf7dd85 100644 --- a/playwright/session-recording/session-recording-sampling.spec.ts +++ b/playwright/session-recording/session-recording-sampling.spec.ts @@ -1,4 +1,4 @@ -import { expect, test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { expect, test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' const startOptions = { @@ -44,10 +44,10 @@ test.describe('Session recording - sampling', () => { }) test('can override sampling when starting session recording', async ({ page, context }) => { - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.startSessionRecording({ sampling: true }) - ph?.capture('test_registered_property') + await page.evaluate(async () => { + const ph = await page.posthog() + ph.startSessionRecording({ sampling: true }) + ph.capture('test_registered_property') }) await page.expectCapturedEventsToBe(['test_registered_property']) expect((await page.capturedEvents())[0]['properties']['$session_recording_start_reason']).toEqual( diff --git a/playwright/session-recording/session-recording.spec.ts b/playwright/session-recording/session-recording.spec.ts index 454186248..0ecc030fb 100644 --- a/playwright/session-recording/session-recording.spec.ts +++ b/playwright/session-recording/session-recording.spec.ts @@ -1,4 +1,4 @@ -import { expect, test, WindowWithPostHog } from '../utils/posthog-playwright-test-base' +import { expect, test } from '../utils/posthog-playwright-test-base' import { start } from '../utils/setup' import { Page } from '@playwright/test' import { isUndefined } from '../../src/utils/type-utils' @@ -74,30 +74,30 @@ test.describe('Session recording - array.js', () => { }) test('captures session events', async ({ page }) => { - const startingSessionId = await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - return ph?.get_session_id() + const startingSessionId = await page.evaluate(async () => { + const ph = await page.posthog() + return ph.get_session_id() }) await ensureActivitySendsSnapshots(page, ['$remote_config_received', '$session_options', '$posthog_config']) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.stopSessionRecording() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.stopSessionRecording() }) await ensureRecordingIsStopped(page) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.startSessionRecording() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.startSessionRecording() }) await ensureActivitySendsSnapshots(page, ['$session_options', '$posthog_config']) // the session id is not rotated by stopping and starting the recording - const finishingSessionId = await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - return ph?.get_session_id() + const finishingSessionId = await page.evaluate(async () => { + const ph = await page.posthog() + return ph.get_session_id() }) expect(startingSessionId).toEqual(finishingSessionId) }) @@ -139,9 +139,9 @@ test.describe('Session recording - array.js', () => { await page.locator('[data-cy-input]').fill('hello posthog!') }) - const firstSessionId = await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - return ph?.get_session_id() + const firstSessionId = await page.evaluate(async () => { + const ph = await page.posthog() + return ph.get_session_id() }) const capturedEvents = await page.capturedEvents() expect(new Set(capturedEvents.map((c) => c['properties']['$session_id']))).toEqual(new Set([firstSessionId])) @@ -167,9 +167,9 @@ test.describe('Session recording - array.js', () => { expect(capturedAfterActivity.map((x) => x.event)).toEqual(['$snapshot']) expect(capturedAfterActivity[0]['properties']['$session_id']).toEqual(firstSessionId) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.capture('some_custom_event') + await page.evaluate(async () => { + const ph = await page.posthog() + ph.capture('some_custom_event') }) await page.expectCapturedEventsToBe(['$snapshot', 'some_custom_event']) const capturedAfterReload = await page.capturedEvents() @@ -180,18 +180,18 @@ test.describe('Session recording - array.js', () => { test('starts a new recording after calling reset', async ({ page }) => { await page.resetCapturedEvents() - const startingSessionId = await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - return ph?.get_session_id() + const startingSessionId = await page.evaluate(async () => { + const ph = await page.posthog() + return ph.get_session_id() }) expect(startingSessionId).not.toBeNull() await ensureActivitySendsSnapshots(page, ['$remote_config_received', '$session_options', '$posthog_config']) await page.resetCapturedEvents() - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.reset() + await page.evaluate(async () => { + const ph = await page.posthog() + ph.reset() }) await page.waitingForNetworkCausedBy(['**/ses/*'], async () => { @@ -211,9 +211,9 @@ test.describe('Session recording - array.js', () => { await page.locator('[data-cy-input]').fill('hello posthog!') }) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.capture('test_registered_property') + await page.evaluate(async () => { + const ph = await page.posthog() + ph.capture('test_registered_property') }) await page.expectCapturedEventsToBe(['$snapshot', 'test_registered_property']) @@ -225,11 +225,11 @@ test.describe('Session recording - array.js', () => { expect(capturedEvents[1]['properties']['$session_recording_start_reason']).toEqual('recording_initialized') await page.resetCapturedEvents() - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - const activityTs = ph?.sessionManager?.['_sessionActivityTimestamp'] - const startTs = ph?.sessionManager?.['_sessionStartTimestamp'] - const timeout = ph?.sessionManager?.['_sessionTimeoutMs'] + await page.evaluate(async () => { + const ph = await page.posthog() + const activityTs = ph.sessionManager?.['_sessionActivityTimestamp'] + const startTs = ph.sessionManager?.['_sessionStartTimestamp'] + const timeout = ph.sessionManager?.['_sessionTimeoutMs'] // move the session values back, // so that the next event appears to be greater than timeout since those values @@ -244,9 +244,9 @@ test.describe('Session recording - array.js', () => { await page.locator('[data-cy-input]').type('hello posthog!') }) - await page.evaluate(() => { - const ph = (window as WindowWithPostHog).posthog - ph?.capture('test_registered_property') + await page.evaluate(async () => { + const ph = await page.posthog() + ph.capture('test_registered_property') }) await page.expectCapturedEventsToBe(['$snapshot', 'test_registered_property']) diff --git a/playwright/utils/posthog-playwright-test-base.ts b/playwright/utils/posthog-playwright-test-base.ts index bd96e95f4..b6c3bd69f 100644 --- a/playwright/utils/posthog-playwright-test-base.ts +++ b/playwright/utils/posthog-playwright-test-base.ts @@ -33,12 +33,22 @@ declare module '@playwright/test' { waitingForNetworkCausedBy: (urlPatterns: (string | RegExp)[], action: () => Promise) => Promise expectCapturedEventsToBe(expectedEvents: string[]): Promise + + posthog(): Promise } } export const test = base.extend<{ mockStaticAssets: void; page: Page }>({ page: async ({ page }, use) => { - // Add custom methods to the page object + page.posthog = async function () { + const currentPosthog = await this.evaluate(() => { + return (window as WindowWithPostHog).posthog + }) + if (!currentPosthog) { + throw new Error('PostHog not found on the page') + } + return currentPosthog + } page.resetCapturedEvents = async function () { await this.evaluate(() => { ;(window as WindowWithPostHog).capturedEvents = []