Files
suaveplan/apps/testbed/src/client/pages/extension-test/extension-test-page.md
2026-05-27 23:29:53 +01:00

2.7 KiB

ExtensionTestPage

(no submodules)

## Purpose

The ExtensionTestPage provides a dedicated landing zone for testing browser extension content scripts. It detects whether an extension has injected a DOM element (id="extension-injected") either at load time or via a MutationObserver watching for subsequent DOM mutations. It is used with the launchWithExtension Playwright fixture from @suaveplan/testing-e2e/extension-fixture.

Features

  • Checks document.getElementById("extension-injected") on mount for immediate detection
  • MutationObserver watches document.body for late-injected extension elements
  • Visual injection target zone (id="extension-mount") as a styled dashed box
  • Detection status shown with ✓ / ○ prefix in the output panel
  • All required data-testid attributes for Playwright E2E testing
  • MutationObserver is disconnected on component unmount to prevent leaks

Usage: Basic Example

import React from "react";
import { ExtensionTestPage } from "./extension-test-page.js";

export function App() {
  return <ExtensionTestPage />;
}

Usage: Advanced Example

In extension Playwright tests, launch with launchWithExtension from @suaveplan/testing-e2e/extension-fixture:

import { launchWithExtension } from "@suaveplan/testing-e2e/extension-fixture";
import { chromium } from "@playwright/test";

const { context, extensionId } = await launchWithExtension({
  chromium,
  extensionPath: "./e2e/fixtures/test-extension",
  userDataDir: "/tmp/pw-user-data",
});

const page = await context.newPage();
await page.goto("http://localhost:3200/extension-test");
await expect(page.locator('[data-testid="output"]')).toContainText("Extension injected");
await context.close();

The test extension should inject <div id="extension-injected">Extension injected content</div> into the page body or extension-mount div.

API Reference

ExtensionTestPage(): React.JSX.Element

No props.

data-testid attributes:

  • page-title — the <h1> heading
  • demo-card — wraps the injection target and detection output
  • extension-mount — the styled dashed box that extensions should target for injection
  • output — displays the detection result (✓ detected or ○ not detected)
  • console-panel — bottom console section with usage instructions

Implementation Notes

The MutationObserver uses { childList: true, subtree: true } to detect any descendant insertions, not just immediate children of body. This ensures detection works whether the extension injects into the mount div, body, or any other ancestor. The observer is disconnected in the cleanup function returned by useEffect. The page is otherwise purely client-side with no server dependencies.