Files
zeekay e43ab1afe7 chore: rename all PostHog references to Insights/Hanzo
Bulk rename across 989 files:
- Package names: posthog-js → @hanzo/insights, posthog-node → @hanzo/insights-node, etc.
- Repository URLs: posthog/posthog-js → hanzoai/insights-js
- Brand names: PostHog → Insights
- File renames: 259 reference JSON files, source files, workflow files
- Directory rename: eslint-plugin-posthog-js → eslint-plugin-insights

Remaining: 8 refs to @posthog/rrweb-* (real npm deps, need fork+publish)
2026-03-06 01:41:12 -08:00

107 lines
4.2 KiB
TypeScript

import { expect, test } from './utils/insights-playwright-test-base'
import { gotoPage } from './utils/setup'
const configResponse = {
featureFlags: {},
featureFlagPayloads: {},
sessionRecording: {
endpoint: '/ses/',
},
}
test.describe('SSR hydration compatibility', () => {
test('does not cause hydration errors when scripts are loaded', async ({ page, context }) => {
void context.route(/\/array\/[^/]+\/config(\?|$)/, (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(configResponse),
})
})
await context.route('**/flags/*', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(configResponse),
})
})
await context.route('**/static/recorder.js*', (route) => {
route.fulfill({
status: 200,
contentType: 'application/javascript',
body: 'console.log("recorder loaded"); window.__InsightsExtensions__ = window.__InsightsExtensions__ || {}; window.__InsightsExtensions__.rrweb = {};',
})
})
await gotoPage(page, '/playground/hydration/index.html')
await page.waitForFunction(() => (window as any).testComplete === true, { timeout: 10000 })
const domMutated = await page.evaluate(() => (window as any).domMutated)
const newScriptsAdded = await page.evaluate(() => (window as any).newScriptsAdded)
const hydrationErrors: string[] = await page.evaluate(() => (window as any).hydrationErrors)
expect(newScriptsAdded).toBe(true)
expect(domMutated).toBe(false)
expect(hydrationErrors).toEqual([])
})
test('appends scripts to head, leaving body untouched for SSR hydration', async ({ page, context }) => {
void context.route(/\/array\/[^/]+\/config(\?|$)/, (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(configResponse),
})
})
await context.route('**/flags/*', (route) => {
route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify(configResponse),
})
})
await context.route('**/static/recorder.js*', (route) => {
route.fulfill({
status: 200,
contentType: 'application/javascript',
body: `
console.log("recorder loaded");
window.__InsightsExtensions__ = window.__InsightsExtensions__ || {};
window.__InsightsExtensions__.rrweb = {};
window.__InsightsExtensions__.rrwebPlugins = { getRecordConsolePlugin: function() { return {}; } };
`,
})
})
await gotoPage(page, '/playground/hydration/index.html')
await page.waitForFunction(() => (window as any).testComplete === true, { timeout: 10000 })
const bodyScripts = await page.evaluate(() => {
const scripts = Array.from(document.querySelectorAll('body > script')) as HTMLScriptElement[]
return scripts.map((s) => ({
id: s.id || null,
src: s.src || null,
isInsightsScript: s.src?.includes('insights') || s.src?.includes('recorder') || false,
}))
})
const headScripts = await page.evaluate(() => {
const scripts = Array.from(document.querySelectorAll('head > script')) as HTMLScriptElement[]
return scripts.map((s) => ({
src: s.src || null,
isInsightsScript: s.src?.includes('insights') || s.src?.includes('recorder') || false,
}))
})
const insightsScriptsInBody = bodyScripts.filter((s) => s.isInsightsScript)
const insightsScriptsInHead = headScripts.filter((s) => s.isInsightsScript)
expect(insightsScriptsInBody).toEqual([])
expect(insightsScriptsInHead.length).toBeGreaterThan(0)
})
})