Skip to content

Development

Project structure

src/
  core/               ← Shared logic: types, constants, framework presets,
  │                      DOM utilities, session management, context,
  │                      and 11 tracking modules (scroll, links, tabs, etc.)
  standalone/         ← Script-tag distribution. Adds event queue,
  │                      batching, HTTP/Supabase/OTLP transport.
  instrumentation/    ← npm OTel instrumentation. DocsInstrumentation
                         extends InstrumentationBase from @opentelemetry/
                         instrumentation.

The src/standalone/ entry produces dist/do11y.js and dist/do11y.min.js (IIFE for script tags). The src/instrumentation/ entry produces dist/instrumentation/index.js (ESM for bundlers).

Build

bash
npm run build              # Build all outputs
npm run build:standalone   # Build only the standalone IIFE
npm run build:instrumentation  # Build only the ESM instrumentation

Tests

The test suite is organized in layers, each catching a different class of failure:

What brokeWhich test catches itSpeedCredentials
Tracking module logic bugUnit tests (core + tracking)< 1sNone
Transport queuing / flush / retryTransport unit tests< 1sNone
Framework CSS class rename (drift)Selector snapshot fixtures< 1sNone
Real-world CSS drift on productionSelector snapshot live-sites (~30s)~30sNone (TEST_LIVE=1)
Standalone file doesn't load/exportExport tests (HTTP/OTLP)~5sNone
Instrumentation emits all 11 event typesExport tests (instrumentation-otel)< 1sNone
Supabase export brokenExport smoke test~3sSUPABASE_*
Built bundle emits all event types in real browserIntegration tests (fixture-based)~30sNone
SQL query correctnesstest-queries.ts~10sSUPABASE_*

Quick start

Copy tests/.env.example to tests/.env and add your test Supabase credentials. Create SUPABASE_ACCESS_TOKEN at Account tokens, or run supabase login to store a token locally.

All tests use Vitest. Run them from the tests/ directory:

bash
cd tests
npm i
npx puppeteer browsers install chrome
npm test

Test suites

CommandWhat runsCredentials
npm testAll unit + selector + export + integration suitesNone
npm run test:unitCore + tracking + transport unit testsNone
npm run test:selectorsFramework selector fixture testsNone
npm run test:exportHTTP, OTLP, instrumentation-otel export testsNone
npm run test:integrationAll framework fixtures, Puppeteer, mock HTTP transportNone
npm run test:supabaseSupabase smoke testSUPABASE_URL, SUPABASE_KEY
npm run test:live-selectorsLive-site CSS drift checkNone (but network)
npm run test:allAll suites, verbose outputVaries

Instrumentation coverage

Each event type is tested with representative DOM interactions:

Event typeUnit testInstr. export testStandalone E2E
page_view
link_click
scroll_depth
search_opened
code_copied
expand_collapse
toc_click
feedback
page_exit
section_visible
tab_switch

section_visible and tab_switch are not tested in the Puppeteer-based standalone E2E because they require IntersectionObserver and specific DOM structures that are hard to trigger reliably across all framework fixtures. Unit tests and the instrumentation export test cover them.

Create release

  1. Bump the version in package.json and src/core/constants.ts.

  2. Build, verify, and run tests:

    bash
    npm run all
  3. Commit and push to main.

  4. Tag and release:

    bash
    git tag v0.1.0
    git push origin v0.1.0
    gh release create v0.1.0

    Alternatively, create the release at github.com/manototh/do11y/releases/new.

  5. Publish to npm:

    bash
    npm login
    npm publish --access public
    npm logout

Released under the MIT License.