mirror of
https://github.com/hanzoai/insights-js.git
synced 2026-10-30 18:34:19 +00:00
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)
107 lines
4.2 KiB
TypeScript
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)
|
|
})
|
|
})
|