Files
template-app/test/observe-browser.test.ts
2026-11-14 09:56:45 +00:00

95 lines
4.5 KiB
TypeScript

// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The browser half of observability (plan item AT4.2): `src/client.tsx` starts
// @conusai-sdk/observe only when the server wrote the settings into the document, with the options this
// app chose, and an error boundary reports through the same instance. The SDK is the real one with
// the recording transport of @conusai-sdk/observe-testing, so what is asserted is what would be sent.
import { createTestObserve } from "@conusai-sdk/observe-testing"
import { describe, expect, it, vi } from "vitest"
import {
browserObserveOptions,
observeMeta,
readBrowserSettings,
reportClientError,
startBrowserObserve,
} from "../apps/web/src/observe/browser.js"
/** A document with the meta element the server writes, as far as the module reads one. */
const documentWith = (attributes: Record<string, string> | undefined) => ({
querySelector: (selector: string) =>
attributes && selector === 'meta[name="app-observe"]'
? { getAttribute: (name: string) => attributes[name] ?? null }
: null,
})
describe("the settings the server writes into the document", () => {
it("round-trips through the meta element", () => {
const settings = { release: "2026.10.1", environment: "preview" }
expect(readBrowserSettings(documentWith(observeMeta(settings)) as never)).toEqual(settings)
})
it("reads nothing from a document without the element, or with it off", () => {
expect(readBrowserSettings(documentWith(undefined) as never)).toBeUndefined()
expect(readBrowserSettings(documentWith({ content: "off" }) as never)).toBeUndefined()
})
it("names neither ConusAI nor a build-time variable: the element is the app's own", () => {
expect(JSON.stringify(observeMeta({ release: "r", environment: "e" })).toLowerCase()).not.toContain("conusai")
})
})
describe("starting the browser SDK", () => {
it("starts nothing when the deployment has no observability", () => {
const start = vi.fn()
expect(startBrowserObserve(documentWith(undefined) as never, start)).toBeUndefined()
expect(start).not.toHaveBeenCalled()
})
it("starts opt-in analytics and traces, with no replay before its separate consent", () => {
const start = vi.fn((options) => createTestObserve({ ...options, modules: { errors: false } }))
startBrowserObserve(documentWith(observeMeta({ release: "r-9", environment: "production" })) as never, start)
expect(start).toHaveBeenCalledWith(
expect.objectContaining({ release: "r-9", environment: "production", consent: "opt-in", respectGPC: true }),
)
const options = start.mock.calls[0]?.[0]
expect(options?.modules).toEqual({ traces: true, analytics: true })
expect(options?.modules).not.toHaveProperty("replay")
expect(browserObserveOptions({ release: "r-9", environment: "production" })).toEqual(options)
})
it("sends an error a boundary caught, through the instance the page started", () => {
const instance = createTestObserve({ modules: { errors: false } })
startBrowserObserve(documentWith(observeMeta({ release: "r", environment: "e" })) as never, () => instance)
reportClientError(new Error("the page threw"))
expect(instance.mock.kinds()).toContain("error")
const [item] = instance.mock.items()
expect(JSON.stringify(item)).toContain("the page threw")
})
})
describe("a recorded edge grant without a current choice of this app", () => {
const withCookie = (cookie: string) => ({
...documentWith(observeMeta({ release: "r", environment: "e" })),
cookie,
})
const olderNotice = `app_consent=${encodeURIComponent(
JSON.stringify({ analytics: true, replay: false, at: new Date().toISOString(), notice: "2025-01" }),
)}`
it.each([
["no choice", "_conusai_consent=granted"],
["a malformed choice", "app_consent=%7Bnope; _conusai_consent=granted"],
["a choice under an older notice", `${olderNotice}; _conusai_consent=granted`],
])("is withdrawn on %s, so the edge stops setting its cookies", (_, cookie) => {
const instance = createTestObserve({ consent: "opt-in", modules: { errors: false } })
startBrowserObserve(withCookie(cookie) as never, () => instance, {})
expect(instance.consent.state()).toBe("denied")
})
it("writes nothing for a visitor the edge holds no grant for", () => {
const instance = createTestObserve({ consent: "opt-in", modules: { errors: false } })
startBrowserObserve(withCookie("") as never, () => instance, {})
expect(instance.consent.state()).toBe("pending")
})
})