view design_system/test/catalog_test.js @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents 667156fcd3e3
children
line wrap: on
line source

const assert = require('node:assert/strict');
const http = require('node:http');
const net = require('node:net');
const path = require('node:path');
const { spawn } = require('node:child_process');

const RUNFILES = process.env.JS_BINARY__RUNFILES;
const WORKSPACE = process.env.JS_BINARY__WORKSPACE;
const runfilesWorkspace = path.join(RUNFILES, WORKSPACE);
const playwrightPath = path.join(
  runfilesWorkspace,
  'hg-web/e2e/node_modules/playwright-core',
);
const { chromium } = require(playwrightPath);

function findFreePort() {
  return new Promise((resolve, reject) => {
    const server = net.createServer();
    server.once('error', reject);
    server.listen(0, '127.0.0.1', () => {
      const address = server.address();
      server.close(error => {
        if (error) reject(error);
        else resolve(String(address.port));
      });
    });
  });
}

async function stopProcess(child) {
  if (!child || child.exitCode !== null) return;
  child.kill('SIGTERM');
  await new Promise(resolve => {
    const timer = setTimeout(() => {
      if (child.exitCode === null) child.kill('SIGKILL');
    }, 3000);
    child.once('exit', () => {
      clearTimeout(timer);
      resolve();
    });
  });
}

async function waitForServer(server, baseUrl, logs) {
  const deadline = Date.now() + 15000;
  while (Date.now() < deadline) {
    if (server.exitCode !== null) {
      throw new Error(`Server exited with ${server.exitCode}\n${logs.join('')}`);
    }
    try {
      const response = await fetch(baseUrl);
      if (response.ok) return;
    } catch {
      // Keep waiting.
    }
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  throw new Error(`Server startup timed out\n${logs.join('')}`);
}

function requestRawPath(port, requestPath) {
  return new Promise((resolve, reject) => {
    const request = http.request({
      host: '127.0.0.1',
      port,
      method: 'GET',
      path: requestPath,
      agent: false,
    }, response => {
      response.resume();
      response.on('end', () => resolve(response.statusCode));
    });
    request.on('error', reject);
    request.end();
  });
}

(async () => {
  assert.ok(RUNFILES);
  assert.ok(WORKSPACE);
  const serverBinary = path.join(
    runfilesWorkspace,
    'design_system/design_system_server',
  );
  const chromiumPath = path.resolve(process.env.CHROMIUM_PATH);
  const port = await findFreePort();
  const baseUrl = `http://127.0.0.1:${port}`;
  const logs = [];
  let server;
  let browser;

  try {
    const invalidServer = spawn(serverBinary, [], {
      cwd: runfilesWorkspace,
      env: {
        ...process.env,
        DESIGN_SYSTEM_PORT: 'not-a-port',
      },
      stdio: ['ignore', 'pipe', 'pipe'],
    });
    const invalidExit = await new Promise(resolve => {
      invalidServer.once('exit', (code, signal) => resolve({ code, signal }));
    });
    assert.equal(invalidExit.code, 1);
    assert.equal(invalidExit.signal, null);

    server = spawn(serverBinary, [], {
      cwd: runfilesWorkspace,
      env: {
        ...process.env,
        DESIGN_SYSTEM_PORT: port,
      },
      stdio: ['ignore', 'pipe', 'pipe'],
    });
    server.stdout.on('data', chunk => logs.push(chunk.toString()));
    server.stderr.on('data', chunk => logs.push(chunk.toString()));
    await waitForServer(server, baseUrl, logs);
    assert.equal(await requestRawPath(port, '/../../MODULE.bazel'), 400);

    for (const route of [
      '/',
      '/tokens',
      '/icons',
      '/components',
      '/components/button',
      '/components/card',
      '/components/alert',
      '/components/field',
      '/components/notifications',
      '/components/stack',
    ]) {
      const response = await fetch(`${baseUrl}${route}`);
      assert.equal(response.status, 200, route);
      assert.match(
        response.headers.get('content-type') || '',
        /^text\/html/,
      );
    }
    for (const asset of [
      '/styles/tokens.css',
      '/styles/reference.css',
      '/styles/semantic.css',
      '/styles/density.css',
      '/styles/themes.css',
      '/styles/components.css',
      '/styles/elements.css',
      '/components/index.js',
      '/components/icon.js',
      '/catalog.js',
      '/catalog.js',
    ]) {
      const response = await fetch(`${baseUrl}${asset}`);
      assert.equal(response.status, 200, asset);
      assert.ok((await response.text()).length > 100, asset);
    }

    browser = await chromium.launch({
      executablePath: chromiumPath,
      headless: true,
      args: ['--no-sandbox'],
    });
    const context = await browser.newContext({ colorScheme: 'light' });
    const page = await context.newPage();
    const errors = [];
    const devtools = await context.newCDPSession(page);
    await devtools.send('Runtime.enable');
    devtools.on('Runtime.exceptionThrown', event => {
      const exception = event.exceptionDetails;
      errors.push(
        `${exception.text}: ${exception.exception?.description || ''} ` +
        `${exception.url || ''}:${exception.lineNumber + 1}`,
      );
    });
    page.on('pageerror', error => errors.push(error.stack || error.message));
    page.on('console', message => {
      if (message.type() === 'error') {
        const location = message.location();
        errors.push(
          `${message.text()} ${location.url || ''}:${location.lineNumber + 1}`,
        );
      }
    });
    page.on('response', response => {
      if (response.status() >= 400) {
        errors.push(`${response.status()} ${response.url()}`);
      }
    });

    await page.goto(`${baseUrl}/components/button`, {
      waitUntil: 'networkidle',
    });
    try {
      await page.waitForFunction(
        () => customElements.get('zen-button') &&
          customElements.get('zen-story'),
        undefined,
        { timeout: 5000 },
      );
    } catch (error) {
      throw new Error(`${error.message}\n${errors.join('\n')}`);
    }
    const catalogState = await page.evaluate(async () => {
      const links = [
        ...document.querySelectorAll(
          '.catalog-nav[aria-label="Components"] a',
        ),
      ];
      const elements = [...new Set(
        links.map(link => link.dataset.zenElement).filter(Boolean),
      )];
      const statuses = await Promise.all(
        links.map(async link => (await fetch(link.href)).status),
      );
      return {
        cards: document.querySelectorAll('.component-grid > a').length,
        elements,
        links: links.length,
        missing: elements.filter(name => !customElements.get(name)),
        routes: links.map(link => new URL(link.href).pathname),
        statuses,
      };
    });
    assert.equal(catalogState.cards, 70);
    assert.equal(catalogState.links, 70);
    assert.equal(catalogState.elements.length, 69);
    assert.deepEqual(catalogState.missing, []);
    assert.deepEqual(
      [...new Set(catalogState.statuses)],
      [200],
    );
    const primitiveOwnership = await page.evaluate(() => {
      const buttonOwners = [
        'zen-alert',
        'zen-attachment',
        'zen-button',
        'zen-button-group',
        'zen-calendar',
        'zen-carousel',
        'zen-combobox',
        'zen-command',
        'zen-context-menu',
        'zen-data-table',
        'zen-date-picker',
        'zen-dropdown-menu',
        'zen-input-group',
        'zen-menubar',
        'zen-message-scroller',
        'zen-navigation-menu',
        'zen-notifications',
        'zen-sidebar',
        'zen-tabs',
        'zen-toggle',
        'zen-toggle-group',
      ].join(',');
      const controlOwners = [
        'zen-calendar',
        'zen-checkbox',
        'zen-combobox',
        'zen-command',
        'zen-date-picker',
        'zen-field',
        'zen-form',
        'zen-input',
        'zen-input-group',
        'zen-input-otp',
        'zen-native-select',
        'zen-radio-group',
        'zen-select',
        'zen-slider',
        'zen-switch',
        'zen-textarea',
      ].join(',');
      return {
        buttons: [...document.querySelectorAll('button')].filter(button =>
          !button.closest(buttonOwners) &&
          !button.matches('zen-story > header > button')
        ).map(button => button.outerHTML),
        controls: [
          ...document.querySelectorAll('input, select, textarea'),
        ].filter(control => !control.closest(controlOwners))
          .map(control => control.outerHTML),
      };
    });
    assert.deepEqual(primitiveOwnership, {
      buttons: [],
      controls: [],
    });
    const brokenCatalogPages = await page.evaluate(routes => {
      const failures = [];
      const buttonOwners = [
        'zen-alert',
        'zen-attachment',
        'zen-button',
        'zen-button-group',
        'zen-calendar',
        'zen-carousel',
        'zen-combobox',
        'zen-command',
        'zen-context-menu',
        'zen-data-table',
        'zen-date-picker',
        'zen-dropdown-menu',
        'zen-input-group',
        'zen-menubar',
        'zen-message-scroller',
        'zen-navigation-menu',
        'zen-notifications',
        'zen-sidebar',
        'zen-tabs',
        'zen-toggle',
        'zen-toggle-group',
      ].join(',');
      for (const route of ['/', '/tokens', '/icons', '/components', ...routes]) {
        history.replaceState({}, '', route);
        window.dispatchEvent(new PopStateEvent('popstate'));
        const visible = [
          ...document.querySelectorAll('[data-catalog-page]:not([hidden])'),
        ];
        const expected = route === '/' || route === '/components'
          ? 'overview'
          : route.slice(route.lastIndexOf('/') + 1);
        if (visible.length !== 1 ||
            visible[0].dataset.catalogPage !== expected ||
            !visible[0].querySelector('h1')?.textContent.trim()) {
          failures.push(route);
          continue;
        }
        if (route.startsWith('/components/')) {
          const story = visible[0].querySelector('zen-story');
          const canvas = story?.querySelector('.story-canvas');
          const source = story?.querySelector('pre code');
          if (!story || !canvas?.children.length ||
              !source?.textContent.trim()) {
            failures.push(`${route}:empty-story`);
          }
          const unownedButtons = [...canvas?.querySelectorAll('button') || []]
            .filter(button => !button.closest(buttonOwners));
          if (unownedButtons.length) {
            failures.push(`${route}:unowned-button`);
          }
        }
      }
      history.replaceState({}, '', '/components/button');
      window.dispatchEvent(new PopStateEvent('popstate'));
      return failures;
    }, catalogState.routes);
    assert.deepEqual(brokenCatalogPages, []);
    await page.keyboard.press('/');
    assert.equal(
      await page.locator('#componentSearch').evaluate(
        input => document.activeElement === input,
      ),
      true,
    );
    await page.locator('#componentSearch').fill('date');
    assert.equal(
      await page.locator(
        '.catalog-nav[aria-label="Components"] a:not([hidden])',
      ).count(),
      2,
    );
    assert.equal(
      await page.locator('.component-grid > a:not([hidden])').count(),
      2,
    );
    assert.match(
      await page.locator('#componentSearchStatus').textContent(),
      /^2 components found$/,
    );
    await page.locator('#componentSearch').press('Escape');
    assert.equal(await page.locator('#componentSearch').inputValue(), '');
    assert.equal(
      await page.locator(
        '.catalog-nav[aria-label="Components"] a:not([hidden])',
      ).count(),
      70,
    );
    await page.locator('#componentSearch').fill('stack');
    assert.equal(
      await page.locator(
        '.catalog-nav[aria-label="Components"] a[href="/components/stack"]',
      ).getAttribute('hidden'),
      null,
    );
    assert.equal(
      await page.locator(
        '.component-grid > a[href="/components/stack"]',
      ).getAttribute('hidden'),
      null,
    );
    await page.locator('#componentSearch').press('Escape');
    assert.equal(
      await page.locator('[data-catalog-page="button"]').isVisible(),
      true,
    );
    assert.equal(
      await page.locator('.catalog-sidebar a[href="/components/button"]').getAttribute('aria-current'),
      'page',
    );
    assert.match(
      await page.locator('zen-story pre').first().textContent(),
      /<zen-button>/,
    );
    const plainPresentation = await page.evaluate(() => {
      const style = document.createElement('style');
      style.textContent = `
        .application-button {
          padding: 7px;
          border: 3px solid currentColor;
          box-shadow: none;
          background: transparent;
        }
        .application-input {
          appearance: auto;
          padding: 9px;
          border: 4px solid currentColor;
          background: transparent;
        }
      `;
      document.head.append(style);
      const buttonHost = document.createElement('zen-button');
      buttonHost.setAttribute('appearance', 'plain');
      buttonHost.setAttribute('loading', '');
      const button = document.createElement('button');
      button.className = 'application-button';
      button.textContent = 'Plain';
      buttonHost.append(button);

      const card = document.createElement('zen-card');
      card.setAttribute('appearance', 'plain');
      const article = document.createElement('article');
      card.append(article);

      const field = document.createElement('zen-field');
      field.setAttribute('appearance', 'plain');
      const label = document.createElement('label');
      label.textContent = 'Plain field';
      const input = document.createElement('input');
      field.append(label, input);
      const inputHost = document.createElement('zen-input');
      inputHost.setAttribute('appearance', 'plain');
      inputHost.setAttribute('size', 'lg');
      const applicationInput = document.createElement('input');
      applicationInput.className = 'application-input';
      inputHost.append(applicationInput);
      document.body.append(buttonHost, card, field, inputHost);

      const buttonStyle = getComputedStyle(button);
      const cardStyle = getComputedStyle(article);
      return {
        buttonBackground: buttonStyle.backgroundColor,
        buttonBorder: buttonStyle.borderTopWidth,
        buttonPadding: buttonStyle.paddingTop,
        buttonShadow: buttonStyle.boxShadow,
        buttonOpacity: buttonStyle.opacity,
        buttonSpinner: getComputedStyle(button, '::before').content,
        cardBackground: cardStyle.backgroundColor,
        cardBorder: cardStyle.borderTopWidth,
        cardShadow: cardStyle.boxShadow,
        fieldDisplay: getComputedStyle(field).display,
        inputAppearance: getComputedStyle(input).appearance,
        plainInputAppearance: getComputedStyle(applicationInput).appearance,
        plainInputBorder: getComputedStyle(applicationInput).borderTopWidth,
        plainInputPadding: getComputedStyle(applicationInput).paddingTop,
        labelFor: label.htmlFor,
        inputId: input.id,
      };
    });
    assert.deepEqual(plainPresentation, {
      buttonBackground: 'rgba(0, 0, 0, 0)',
      buttonBorder: '3px',
      buttonPadding: '7px',
      buttonShadow: 'none',
      buttonOpacity: '1',
      buttonSpinner: 'none',
      cardBackground: 'rgba(0, 0, 0, 0)',
      cardBorder: '0px',
      cardShadow: 'none',
      fieldDisplay: 'contents',
      inputAppearance: 'auto',
      plainInputAppearance: 'auto',
      plainInputBorder: '4px',
      plainInputPadding: '9px',
      labelFor: plainPresentation.inputId,
      inputId: plainPresentation.inputId,
    });
    const buttonScale = await page.locator(
      '[data-catalog-page="button"] zen-button[size] > button',
    ).evaluateAll(buttons => buttons.map(button => {
      const host = button.parentElement;
      const style = getComputedStyle(button);
      const hostStyle = getComputedStyle(host);
      return {
        fontSize: Number.parseFloat(style.fontSize),
        height: button.getBoundingClientRect().height,
        paddingInline: Number.parseFloat(style.paddingInlineStart),
        size: host.getAttribute('size'),
        variableHeight: Number.parseFloat(
          hostStyle.getPropertyValue('--zenbu-control-height'),
        ) * Number.parseFloat(getComputedStyle(document.documentElement).fontSize),
      };
    }));
    assert.deepEqual(
      buttonScale.map(item => item.size),
      ['xs', 'sm', 'md', 'lg', 'xl'],
    );
    for (let index = 1; index < buttonScale.length; index++) {
      assert.ok(buttonScale[index].height > buttonScale[index - 1].height);
      assert.ok(
        buttonScale[index].paddingInline >
          buttonScale[index - 1].paddingInline,
      );
      assert.ok(
        buttonScale[index].fontSize > buttonScale[index - 1].fontSize,
      );
    }
    for (const item of buttonScale) {
      assert.ok(
        Math.abs(item.height - item.variableHeight) < 1,
        JSON.stringify(buttonScale),
      );
    }
    const compactScale = await page.evaluate(() => {
      document.documentElement.dataset.zenDensity = 'compact';
      return [...document.querySelectorAll(
        '[data-catalog-page="button"] zen-button[size] > button',
      )]
        .map(button => button.getBoundingClientRect().height);
    });
    assert.equal(compactScale.length, buttonScale.length);
    for (let index = 0; index < compactScale.length; index++) {
      assert.ok(compactScale[index] < buttonScale[index].height);
    }
    await page.evaluate(() => {
      delete document.documentElement.dataset.zenDensity;
    });

    await page.emulateMedia({ reducedMotion: 'reduce' });
    assert.equal(
      await page.evaluate(() =>
        getComputedStyle(document.documentElement)
          .getPropertyValue('--zenbu-sys-motion-duration-state')
          .trim()
      ),
      '1ms',
    );
    await page.emulateMedia({ reducedMotion: 'no-preference' });

    assert.equal(
      await page.locator('zen-button[loading]:not([appearance="plain"])').getAttribute('inert'),
      null,
    );
    assert.equal(
      await page.locator('zen-button[loading]:not([appearance="plain"]) button').getAttribute('aria-disabled'),
      'true',
    );
    assert.equal(
      await page.locator('zen-button[loading]:not([appearance="plain"]) button').getAttribute('aria-busy'),
      'true',
    );
    await page.evaluate(() => {
      window.__loadingClicks = 0;
      document.querySelector('zen-button[loading]:not([appearance="plain"]) button')
        .addEventListener('click', () => window.__loadingClicks++);
    });
    await page.locator('zen-button[loading]:not([appearance="plain"]) button').evaluate(
      button => button.click(),
    );
    assert.equal(await page.evaluate(() => window.__loadingClicks), 0);
    await page.locator('zen-button[loading]:not([appearance="plain"]) button').focus();
    assert.equal(
      await page.locator('zen-button[loading]:not([appearance="plain"]) button').evaluate(
        button => document.activeElement === button,
      ),
      true,
    );
    await page.keyboard.press('Tab');
    assert.equal(
      await page.locator('zen-button[loading]:not([appearance="plain"]) button').evaluate(
        button => document.activeElement === button,
      ),
      false,
    );
    const nativeDisabledPreserved = await page.evaluate(async () => {
      const wrapper = document.createElement('zen-button');
      const button = document.createElement('button');
      button.disabled = true;
      button.textContent = 'Native disabled';
      wrapper.append(button);
      document.body.append(wrapper);
      await customElements.whenDefined('zen-button');
      wrapper.setAttribute('disabled', '');
      wrapper.removeAttribute('disabled');
      return button.disabled;
    });
    assert.equal(nativeDisabledPreserved, true);
    const replacementButtonState = await page.evaluate(async () => {
      const wrapper = document.createElement('zen-button');
      wrapper.setAttribute('disabled', '');
      const first = document.createElement('button');
      first.textContent = 'First';
      wrapper.append(first);
      document.body.append(wrapper);
      await new Promise(resolve => setTimeout(resolve));
      const second = document.createElement('button');
      second.textContent = 'Second';
      wrapper.replaceChildren(second);
      await new Promise(resolve => setTimeout(resolve));
      return {
        firstDisabled: first.disabled,
        secondAriaDisabled: second.getAttribute('aria-disabled'),
        wrapperInert: wrapper.hasAttribute('inert'),
      };
    });
    assert.equal(replacementButtonState.firstDisabled, false);
    assert.equal(replacementButtonState.secondAriaDisabled, 'true');
    assert.equal(replacementButtonState.wrapperInert, false);
    const modifiedClickAllowed = await page.evaluate(() => {
      const link = document.querySelector(
        '.catalog-sidebar a[href="/components/card"]',
      );
      return link.dispatchEvent(new MouseEvent('click', {
        bubbles: true,
        cancelable: true,
        button: 0,
        ctrlKey: true,
      }));
    });
    assert.equal(modifiedClickAllowed, true);

    await page.goto(`${baseUrl}/icons`, { waitUntil: 'networkidle' });
    const iconCount = await page.locator('#iconGrid figure').count();
    assert.ok(iconCount >= 30);
    assert.equal(
      await page.locator('#iconGrid figure zen-icon > svg').count(),
      iconCount,
    );
    const iconFallback = await page.evaluate(() => {
      const icon = document.createElement('zen-icon');
      icon.setAttribute('name', 'not-a-real-icon');
      icon.setAttribute('label', 'Missing icon fallback');
      document.body.append(icon);
      return {
        fallback: icon.dataset.zenIcon,
        hidden: icon.getAttribute('aria-hidden'),
        label: icon.getAttribute('aria-label'),
        role: icon.getAttribute('role'),
      };
    });
    assert.deepEqual(iconFallback, {
      fallback: 'alert',
      hidden: null,
      label: 'Missing icon fallback',
      role: 'img',
    });

    await page.goto(`${baseUrl}/components/link`, {
      waitUntil: 'networkidle',
    });
    const linkPrimitive = page.locator('zen-link[effect="paw"]').first();
    assert.equal(
      await linkPrimitive.locator(
        ':scope > a > zen-icon[name="paw"][data-zen-link-decoration]',
      ).count(),
      1,
    );
    const pawMotion = await linkPrimitive.locator('zen-icon').evaluate(icon => {
      const style = getComputedStyle(icon);
      const keyframes = icon.getAnimations().some(animation =>
        animation.animationName === 'zen-paw-step'
      );
      return {
        animationDuration: style.animationDuration,
        color: style.color,
        keyframes,
      };
    });
    assert.notEqual(pawMotion.animationDuration, '0s');
    assert.notEqual(pawMotion.color, 'rgba(0, 0, 0, 0)');
    assert.equal(pawMotion.keyframes, true);
    await page.emulateMedia({ reducedMotion: 'reduce' });
    assert.equal(
      await linkPrimitive.locator('zen-icon').evaluate(
        icon => getComputedStyle(icon).animationName,
      ),
      'none',
    );
    await page.emulateMedia({ reducedMotion: 'no-preference' });

    await page.goto(`${baseUrl}/components/text`, {
      waitUntil: 'networkidle',
    });
    const textScale = await page.locator('zen-text[size] > p').evaluateAll(
      texts => texts.map(text => Number.parseFloat(
        getComputedStyle(text).fontSize,
      )),
    );
    assert.equal(textScale.length, 5);
    for (let index = 1; index < textScale.length; index++) {
      assert.ok(textScale[index] > textScale[index - 1]);
    }

    await page.goto(`${baseUrl}/components/heading`, {
      waitUntil: 'networkidle',
    });
    const headingScale = await page.locator(
      'zen-heading[size] > h3',
    ).evaluateAll(headings => headings.map(heading => ({
      fontSize: Number.parseFloat(getComputedStyle(heading).fontSize),
      weight: Number(getComputedStyle(heading).fontWeight),
    })));
    assert.equal(headingScale.length, 5);
    assert.ok(headingScale.every(heading => heading.weight >= 700));
    for (let index = 1; index < headingScale.length; index++) {
      assert.ok(
        headingScale[index].fontSize > headingScale[index - 1].fontSize,
      );
    }

    await page.goto(`${baseUrl}/components/box`, {
      waitUntil: 'networkidle',
    });
    const boxScale = await page.locator('zen-box[padding]').evaluateAll(
      boxes => boxes.map(box => Number.parseFloat(
        getComputedStyle(box).paddingTop,
      )),
    );
    assert.equal(boxScale.length, 5);
    for (let index = 1; index < boxScale.length; index++) {
      assert.ok(boxScale[index] > boxScale[index - 1]);
    }

    await page.goto(`${baseUrl}/components/skeleton`, {
      waitUntil: 'networkidle',
    });
    assert.equal(
      await page.locator('zen-skeleton[width="60%"]').evaluate(
        skeleton => skeleton.style.getPropertyValue(
          '--zenbu-skeleton-width',
        ),
      ),
      '60%',
    );

    await page.goto(`${baseUrl}/tokens`, { waitUntil: 'networkidle' });
    const colorTokenState = await page.evaluate(() => {
      const root = document.documentElement;
      const value = name => getComputedStyle(root)
        .getPropertyValue(`--zen-color-${name}`)
        .trim();
      const systemValue = name => getComputedStyle(root)
        .getPropertyValue(`--zenbu-sys-${name}`)
        .trim();
      const families = [
        'neutral',
        'red',
        'orange',
        'amber',
        'green',
        'teal',
        'blue',
        'violet',
        'rose',
        'brown',
      ];
      const steps = [
        '50',
        '100',
        '200',
        '300',
        '400',
        '500',
        '600',
        '700',
        '800',
        '900',
        '950',
      ];
      const rampsComplete = families.every(family =>
        steps.every(step => value(`${family}-${step}`))
      );
      const data = Array.from(
        { length: 10 },
        (_, index) => value(`data-${index + 1}`),
      );
      const materials = [
        'paper',
        'washi',
        'linen',
        'sumi',
        'brick',
        'persimmon',
        'ochre',
        'moss',
        'patina',
        'indigo',
        'plum',
        'clay',
        'wood',
      ].map(value);
      const lightMuted = systemValue('color-surface-subtle');
      root.dataset.zenTheme = 'dark';
      const darkMuted = systemValue('color-surface-subtle');
      const darkData = Array.from(
        { length: 10 },
        (_, index) => value(`data-${index + 1}`),
      );
      const themes = ['paper', 'ink', 'playful', 'cyberpunk'].map(theme => {
        root.dataset.zenTheme = theme;
        const channels = value => value.match(/\d+(?:\.\d+)?/g)
          .slice(0, 3)
          .map(Number);
        const luminance = value => {
          const converted = channels(value).map(channel => {
            const normalized = channel / 255;
            return normalized <= 0.04045
              ? normalized / 12.92
              : ((normalized + 0.055) / 1.055) ** 2.4;
          });
          return converted[0] * 0.2126 +
            converted[1] * 0.7152 +
            converted[2] * 0.0722;
        };
        const contrasts = [
          'info',
          'success',
          'warning',
          'danger',
        ].map(tone => {
          const probe = document.createElement('span');
          probe.style.background =
            `var(--zenbu-sys-color-${tone}-background)`;
          probe.style.color =
            `var(--zenbu-sys-color-${tone}-foreground)`;
          document.body.append(probe);
          const probeStyle = getComputedStyle(probe);
          const foreground = luminance(probeStyle.color);
          const background = luminance(probeStyle.backgroundColor);
          const contrast = (Math.max(foreground, background) + 0.05) /
            (Math.min(foreground, background) + 0.05);
          probe.remove();
          return contrast;
        });
        return {
          canvas: systemValue('color-surface-page'),
          contrast: Math.min(...contrasts),
          font: getComputedStyle(root)
            .getPropertyValue('--zenbu-sys-font-family-ui')
            .trim(),
          name: theme,
          radius: getComputedStyle(root)
            .getPropertyValue('--zenbu-sys-radius-container')
            .trim(),
        };
      });
      delete root.dataset.zenTheme;
      return {
        darkData,
        darkMuted,
        data,
        lightMuted,
        materials,
        rampsComplete,
        themes,
      };
    });
    assert.equal(colorTokenState.rampsComplete, true);
    assert.equal(new Set(colorTokenState.materials).size, 13);
    assert.equal(new Set(colorTokenState.data).size, 10);
    assert.equal(new Set(colorTokenState.darkData).size, 10);
    assert.notDeepEqual(colorTokenState.data, colorTokenState.darkData);
    assert.equal(
      new Set(colorTokenState.themes.map(theme => theme.canvas)).size,
      4,
    );
    assert.notEqual(
      colorTokenState.themes.find(theme => theme.name === 'paper').radius,
      colorTokenState.themes.find(theme => theme.name === 'playful').radius,
    );
    assert.ok(
      colorTokenState.themes.every(theme => theme.contrast >= 4.5),
      JSON.stringify(colorTokenState.themes),
    );
    assert.notEqual(
      colorTokenState.lightMuted,
      colorTokenState.darkMuted,
    );
    assert.equal(await page.locator('.palette-grid > div').count(), 13);
    assert.equal(await page.locator('.data-palette > span').count(), 10);
    await page.evaluate(() => {
      document.documentElement.dataset.zenTheme = 'playful';
    });
    await page.emulateMedia({ forcedColors: 'active' });
    assert.equal(
      await page.evaluate(() =>
        getComputedStyle(document.documentElement)
          .getPropertyValue('--zenbu-sys-color-surface-page')
          .trim()
          .toLowerCase()
      ),
      'canvas',
    );
    await page.emulateMedia({ forcedColors: 'none' });
    await page.evaluate(() => {
      delete document.documentElement.dataset.zenTheme;
    });

    await page.goto(`${baseUrl}/components/field`, {
      waitUntil: 'networkidle',
    });
    const fieldWiring = await page.locator('zen-field').first().evaluate(field => {
      const label = field.querySelector('label');
      const input = field.querySelector('input');
      const help = field.querySelector('small');
      input.checkValidity();
      return {
        describedBy: input.getAttribute('aria-describedby'),
        helpId: help.id,
        inputId: input.id,
        invalid: field.hasAttribute('data-invalid'),
        labelFor: label.htmlFor,
      };
    });
    assert.ok(fieldWiring.inputId);
    assert.equal(fieldWiring.labelFor, fieldWiring.inputId);
    assert.equal(fieldWiring.describedBy, fieldWiring.helpId);
    assert.equal(fieldWiring.invalid, true);
    await page.locator('zen-field input').first().focus();
    assert.equal(
      await page.locator('zen-field input').first().evaluate(
        input => getComputedStyle(input).outlineStyle,
      ),
      'none',
    );
    const replacementField = await page.locator('zen-field').first().evaluate(
      async field => {
        const label = field.querySelector('label');
        const oldInput = field.querySelector('input');
        const blocker = document.createElement('div');
        blocker.id = 'zen-field-3';
        document.body.append(blocker);
        const nextInput = document.createElement('input');
        nextInput.required = true;
        oldInput.replaceWith(nextInput);
        await new Promise(resolve => setTimeout(resolve));
        oldInput.dispatchEvent(new Event('invalid'));
        const help = field.querySelector('small');
        nextInput.id = 'replacement-email';
        help.id = 'replacement-help';
        await new Promise(resolve => setTimeout(resolve));
        return {
          describedBy: nextInput.getAttribute('aria-describedby'),
          helpId: help.id,
          labelFor: label.htmlFor,
          nextId: nextInput.id,
          blockerId: blocker.id,
        };
      },
    );
    assert.ok(replacementField.nextId);
    assert.notEqual(replacementField.nextId, replacementField.blockerId);
    assert.equal(replacementField.labelFor, replacementField.nextId);
    assert.equal(replacementField.describedBy, replacementField.helpId);

    await page.goto(`${baseUrl}/components/alert`, {
      waitUntil: 'networkidle',
    });
    await page.evaluate(() => {
      window.__dismissed = 0;
      document.addEventListener('zen-dismiss', () => {
        window.__dismissed++;
      });
    });
    const dismissible = page.locator('zen-alert[dismissible]');
    assert.equal(await dismissible.getAttribute('role'), 'alert');
    await dismissible.locator('[data-zen-dismiss]').click();
    assert.equal(await dismissible.count(), 0);
    assert.equal(await page.evaluate(() => window.__dismissed), 1);
    const authoredDismissState = await page.evaluate(async () => {
      const alert = document.createElement('zen-alert');
      alert.setAttribute('dismissible', '');
      const message = document.createElement('p');
      message.textContent = 'Authored dismiss control';
      const dismiss = document.createElement('button');
      dismiss.dataset.zenDismiss = '';
      alert.append(message, dismiss);
      document.body.append(alert);
      await new Promise(resolve => setTimeout(resolve));
      let events = 0;
      alert.addEventListener('zen-dismiss', () => events++);
      alert.removeAttribute('dismissible');
      dismiss.click();
      return {
        connected: alert.isConnected,
        events,
      };
    });
    assert.equal(authoredDismissState.connected, true);
    assert.equal(authoredDismissState.events, 0);

    await page.goto(`${baseUrl}/components/accordion`, {
      waitUntil: 'networkidle',
    });
    const accordion = page.locator('zen-accordion').first();
    const disclosureIcon = accordion.locator(
      'summary > zen-icon[data-zen-disclosure-icon]',
    ).nth(1);
    const collapsedDisclosure = await disclosureIcon.evaluate(icon => {
      const style = getComputedStyle(icon);
      return {
        duration: style.transitionDuration,
        transform: style.transform,
      };
    });
    assert.notEqual(collapsedDisclosure.duration, '0s');
    await accordion.locator('summary').nth(1).click();
    await page.waitForTimeout(250);
    assert.notEqual(
      await disclosureIcon.evaluate(icon => getComputedStyle(icon).transform),
      collapsedDisclosure.transform,
    );
    assert.equal(
      await accordion.locator('details').first().getAttribute('open'),
      null,
    );
    assert.equal(
      await accordion.locator('details').nth(1).getAttribute('open'),
      '',
    );
    await accordion.locator('summary').nth(1).press('ArrowUp');
    assert.equal(
      await accordion.locator('summary').first().evaluate(
        summary => document.activeElement === summary,
      ),
      true,
    );

    await page.goto(`${baseUrl}/components/aspect-ratio`, {
      waitUntil: 'networkidle',
    });
    const aspectColors = await page.locator('.demo-media').evaluate(media => {
      const style = getComputedStyle(media);
      const probe = document.createElement('span');
      probe.style.background = 'var(--zenbu-sys-color-surface-subtle)';
      document.body.append(probe);
      const token = getComputedStyle(probe).backgroundColor;
      probe.remove();
      return {
        background: style.backgroundColor,
        image: style.backgroundImage,
        token,
      };
    });
    assert.equal(aspectColors.image, 'none');
    assert.equal(aspectColors.background, aspectColors.token);

    await page.goto(`${baseUrl}/components/tabs`, {
      waitUntil: 'networkidle',
    });
    await page.evaluate(() => {
      window.__tabValue = null;
      document.querySelector('zen-tabs').addEventListener(
        'zen-change',
        event => {
          window.__tabValue = event.detail.value;
        },
      );
    });
    await page.locator('zen-tabs [role="tab"]').nth(1).click();
    assert.equal(
      await page.locator('zen-tabs [role="tab"]').nth(1)
        .getAttribute('aria-selected'),
      'true',
    );
    assert.equal(
      await page.locator('zen-tabs [role="tabpanel"]').nth(1)
        .getAttribute('hidden'),
      null,
    );
    assert.equal(await page.evaluate(() => window.__tabValue), 'history');

    await page.goto(`${baseUrl}/components/dialog`, {
      waitUntil: 'networkidle',
    });
    await page.locator('zen-dialog [data-zen-trigger]').click();
    assert.equal(await page.locator('zen-dialog dialog').getAttribute('open'), '');
    await page.locator('zen-dialog [data-zen-close]').click();
    assert.equal(await page.locator('zen-dialog dialog').getAttribute('open'), null);
    const dynamicOverlays = await page.evaluate(async () => {
      const ownAction = button => {
        const owner = document.createElement('zen-button');
        owner.setAttribute('size', 'md');
        owner.append(button);
        return owner;
      };
      const dialogHost = document.createElement('zen-dialog');
      const popoverHost = document.createElement('zen-popover');
      const tooltipHost = document.createElement('zen-tooltip');
      const menuHost = document.createElement('zen-dropdown-menu');
      document.body.append(dialogHost, popoverHost, tooltipHost, menuHost);

      const dialogTrigger = document.createElement('button');
      dialogTrigger.type = 'button';
      dialogTrigger.dataset.zenTrigger = '';
      const dialog = document.createElement('dialog');
      dialogHost.append(ownAction(dialogTrigger), dialog);

      const popoverTrigger = document.createElement('button');
      popoverTrigger.type = 'button';
      popoverTrigger.dataset.zenTrigger = '';
      const popover = document.createElement('div');
      popover.dataset.zenContent = '';
      popoverHost.append(ownAction(popoverTrigger), popover);

      const tooltipTrigger = document.createElement('button');
      tooltipTrigger.type = 'button';
      tooltipTrigger.dataset.zenTrigger = '';
      const tooltip = document.createElement('span');
      tooltip.dataset.zenContent = '';
      tooltipHost.append(ownAction(tooltipTrigger), tooltip);

      const menuTrigger = document.createElement('button');
      menuTrigger.type = 'button';
      menuTrigger.dataset.zenTrigger = '';
      const menu = document.createElement('div');
      menu.setAttribute('role', 'menu');
      const item = document.createElement('button');
      item.type = 'button';
      item.setAttribute('role', 'menuitem');
      menu.append(item);
      menuHost.append(menuTrigger, menu);

      await new Promise(resolve => setTimeout(resolve));
      dialogTrigger.click();
      const dialogOpen = dialog.open;
      dialog.close();
      popoverTrigger.click();
      menuTrigger.click();
      tooltipTrigger.focus();
      await new Promise(resolve => setTimeout(resolve, 375));
      return {
        dialogControlled: Boolean(dialogTrigger.getAttribute('aria-controls')),
        dialogOpen,
        menuOpen: !menu.hidden,
        popoverExpanded: popoverTrigger.getAttribute('aria-expanded'),
        tooltipOpen: !tooltip.hidden,
      };
    });
    assert.deepEqual(dynamicOverlays, {
      dialogControlled: true,
      dialogOpen: true,
      menuOpen: true,
      popoverExpanded: 'true',
      tooltipOpen: true,
    });

    await page.goto(`${baseUrl}/components/dropdown-menu`, {
      waitUntil: 'networkidle',
    });
    const dropdownTrigger = page.locator(
      'zen-dropdown-menu [data-zen-trigger]',
    );
    await dropdownTrigger.click();
    assert.equal(
      await page.locator('zen-dropdown-menu [role="menu"]')
        .getAttribute('hidden'),
      null,
    );
    await page.keyboard.press('Escape');
    assert.equal(
      await page.locator('zen-dropdown-menu [role="menu"]')
        .getAttribute('hidden'),
      '',
    );
    assert.equal(
      await dropdownTrigger.evaluate(
        trigger => document.activeElement === trigger,
      ),
      true,
    );
    await dropdownTrigger.click();
    await page.locator('zen-dropdown-menu [role="menuitem"]').first().click();
    assert.equal(
      await dropdownTrigger.evaluate(
        trigger => document.activeElement === trigger,
      ),
      true,
    );

    await page.goto(`${baseUrl}/components/combobox`, {
      waitUntil: 'networkidle',
    });
    const comboboxInput = page.locator('zen-combobox input');
    await comboboxInput.fill('seo');
    assert.equal(
      await page.locator('zen-combobox [role="option"]:not([hidden])').count(),
      1,
    );
    await comboboxInput.press('ArrowDown');
    await comboboxInput.press('Enter');
    assert.equal(await comboboxInput.inputValue(), 'seobeo');
    assert.equal(
      await page.locator('zen-combobox [role="listbox"]')
        .getAttribute('hidden'),
      '',
    );

    await page.goto(`${baseUrl}/components/date-picker`, {
      waitUntil: 'networkidle',
    });
    const dateInput = page.locator('zen-date-picker input[type="date"]');
    assert.equal(await dateInput.getAttribute('aria-hidden'), 'true');
    assert.equal(
      await dateInput.evaluate(input => getComputedStyle(input).position),
      'absolute',
    );
    await page.evaluate(() => {
      window.__dateValue = null;
      document.querySelector('zen-date-picker').addEventListener(
        'zen-change',
        event => {
          window.__dateValue = event.detail.value;
        },
      );
    });
    const dateTrigger = page.locator(
      'zen-date-picker [data-zen-date-trigger]',
    );
    await dateTrigger.click();
    assert.equal(
      await page.locator('zen-date-picker [data-zen-calendar-panel]')
        .getAttribute('hidden'),
      null,
    );
    assert.equal(
      await page.locator(
        'zen-date-picker [data-zen-calendar-day]',
      ).count(),
      42,
    );
    const chosenDate = await page.locator(
      'zen-date-picker [data-zen-calendar-day]:not([data-outside]):not(:disabled)',
    ).nth(14).getAttribute('data-zen-calendar-day');
    await page.locator(
      `zen-date-picker [data-zen-calendar-day="${chosenDate}"]`,
    ).click();
    assert.equal(await dateInput.inputValue(), chosenDate);
    assert.equal(await page.evaluate(() => window.__dateValue), chosenDate);
    assert.equal(await dateTrigger.getAttribute('aria-expanded'), 'false');
    const triggerName = await dateTrigger.evaluate(trigger =>
      (trigger.getAttribute('aria-labelledby') || '')
        .split(/\s+/)
        .map(id => document.getElementById(id)?.textContent || '')
        .join(' ')
    );
    assert.match(triggerName, /Deploy on/);
    assert.equal(
      await page.locator('zen-date-picker > label').getAttribute('for'),
      await dateTrigger.getAttribute('id'),
    );
    const minimumDate = `${chosenDate.slice(0, 8)}10`;
    await dateInput.evaluate((input, minimum) => {
      input.min = minimum;
    }, minimumDate);
    await page.waitForTimeout(0);
    await dateTrigger.click();
    const focusedBoundary = page.locator(
      `zen-date-picker [data-zen-calendar-day="${chosenDate}"]`,
    );
    await focusedBoundary.press('PageUp');
    assert.equal(
      await page.evaluate(() =>
        document.activeElement?.dataset.zenCalendarDay
      ),
      minimumDate,
    );
    assert.equal(
      await page.locator(
        'zen-date-picker [data-zen-calendar-day][tabindex="0"]:not(:disabled)',
      ).count(),
      1,
    );
    await page.keyboard.press('Escape');
    await dateInput.evaluate(input => {
      input.disabled = true;
    });
    await page.waitForTimeout(0);
    assert.equal(await dateTrigger.isDisabled(), true);
    await dateInput.evaluate(input => {
      input.disabled = false;
      input.readOnly = true;
    });
    await page.waitForTimeout(0);
    assert.equal(await dateTrigger.isDisabled(), true);
    await dateInput.evaluate(input => {
      input.readOnly = false;
      input.required = true;
      input.value = '';
      input.dispatchEvent(new Event('input', { bubbles: true }));
      input.reportValidity();
    });
    await page.waitForTimeout(0);
    assert.equal(await dateTrigger.getAttribute('aria-invalid'), 'true');
    assert.equal(
      await dateTrigger.evaluate(
        trigger => document.activeElement === trigger,
      ),
      true,
    );
    assert.equal(
      await page.locator('zen-date-picker').getAttribute('data-invalid'),
      '',
    );
    await dateInput.evaluate((input, value) => {
      input.value = value;
      input.dispatchEvent(new Event('input', { bubbles: true }));
    }, chosenDate);
    assert.equal(await dateTrigger.getAttribute('aria-invalid'), 'false');
    const earlyYear = await page.evaluate(async () => {
      const calendar = document.createElement('zen-calendar');
      const input = document.createElement('input');
      input.type = 'date';
      input.value = '0001-01-01';
      input.setAttribute('aria-label', 'Early date');
      calendar.append(input);
      document.body.append(calendar);
      await new Promise(resolve => setTimeout(resolve));
      return {
        selected: calendar.querySelector(
          '[data-zen-calendar-day][aria-selected="true"]',
        )?.dataset.zenCalendarDay,
        value: input.value,
      };
    });
    assert.deepEqual(earlyYear, {
      selected: '0001-01-01',
      value: '0001-01-01',
    });
    const resetDateState = await page.evaluate(async () => {
      const label = document.createElement('span');
      label.id = 'reset-date-label';
      label.textContent = 'Reset date';
      const form = document.createElement('form');
      const picker = document.createElement('zen-date-picker');
      const input = document.createElement('input');
      input.type = 'date';
      input.defaultValue = '2026-08-04';
      input.setAttribute('aria-labelledby', label.id);
      picker.append(input);
      form.append(picker);
      document.body.append(label, form);
      await new Promise(resolve => setTimeout(resolve));
      input.value = '2026-08-12';
      input.dispatchEvent(new Event('input', { bubbles: true }));
      form.reset();
      await new Promise(resolve => setTimeout(resolve));
      const trigger = picker.querySelector('[data-zen-date-trigger]');
      return {
        labelledBy: trigger.getAttribute('aria-labelledby'),
        selected: picker.querySelector(
          '[data-zen-calendar-day][aria-selected="true"]',
        )?.dataset.zenCalendarDay,
        value: input.value,
      };
    });
    assert.match(resetDateState.labelledBy, /^reset-date-label /);
    assert.deepEqual(
      {
        selected: resetDateState.selected,
        value: resetDateState.value,
      },
      {
        selected: '2026-08-04',
        value: '2026-08-04',
      },
    );

    await page.goto(`${baseUrl}/components/input-otp`, {
      waitUntil: 'networkidle',
    });
    await page.evaluate(() => {
      window.__otpValue = null;
      document.querySelector('zen-input-otp').addEventListener(
        'zen-complete',
        event => {
          window.__otpValue = event.detail.value;
        },
      );
    });
    await page.locator('zen-input-otp input').evaluate(input => {
      input.value = '12a3456';
      input.dispatchEvent(new Event('input', { bubbles: true }));
    });
    assert.equal(await page.locator('zen-input-otp input').inputValue(), '123456');
    assert.equal(
      await page.locator('zen-input-otp [data-zen-otp-slots] > span').count(),
      6,
    );
    const otp = page.locator('zen-input-otp');
    await otp.evaluate(host => host.setAttribute('size', 'xs'));
    const compactOtpSize = await otp.locator(
      '[data-zen-otp-slots] > span',
    ).first().evaluate(slot => slot.getBoundingClientRect().width);
    await otp.evaluate(host => host.setAttribute('size', 'xl'));
    const largeOtpSize = await otp.locator(
      '[data-zen-otp-slots] > span',
    ).first().evaluate(slot => slot.getBoundingClientRect().width);
    assert.ok(largeOtpSize > compactOtpSize);
    assert.equal(await page.evaluate(() => window.__otpValue), '123456');

    await page.goto(`${baseUrl}/components/data-table`, {
      waitUntil: 'networkidle',
    });
    await page.locator('zen-data-table [data-zen-sort="commits"]').click();
    assert.equal(
      await page.locator('zen-data-table th').nth(1).getAttribute('aria-sort'),
      'ascending',
    );
    assert.equal(
      await page.locator('zen-data-table tbody tr').first().locator(
        '[data-key="commits"]',
      ).textContent(),
      '12',
    );

    await page.goto(`${baseUrl}/components/carousel`, {
      waitUntil: 'networkidle',
    });
    await page.evaluate(() => {
      window.__carouselIndex = null;
      document.querySelector('zen-carousel').addEventListener(
        'zen-change',
        event => {
          window.__carouselIndex = event.detail.index;
        },
      );
    });
    await page.locator('zen-carousel [data-zen-next]').click();
    assert.equal(await page.evaluate(() => window.__carouselIndex), 1);
    assert.equal(
      await page.locator('zen-carousel [data-zen-prev]').isDisabled(),
      false,
    );

    await page.goto(`${baseUrl}/components/resizable`, {
      waitUntil: 'networkidle',
    });
    const resizeHandle = page.locator('zen-resizable [data-zen-handle]');
    const initialPercent = Number(
      await resizeHandle.getAttribute('aria-valuenow'),
    );
    await resizeHandle.focus();
    await resizeHandle.press('ArrowRight');
    assert.ok(
      Number(await resizeHandle.getAttribute('aria-valuenow')) > initialPercent,
    );

    await page.goto(`${baseUrl}/components/switch`, {
      waitUntil: 'networkidle',
    });
    const switchInput = page.locator('zen-switch input');
    assert.equal(await switchInput.getAttribute('role'), 'switch');
    assert.equal(await switchInput.getAttribute('aria-checked'), 'true');
    await switchInput.uncheck();
    assert.equal(await switchInput.getAttribute('aria-checked'), 'false');

    await page.goto(`${baseUrl}/components/checkbox`, {
      waitUntil: 'networkidle',
    });
    assert.equal(
      await page.locator('zen-checkbox input').evaluate(
        input => getComputedStyle(input).appearance,
      ),
      'none',
    );
    await page.goto(`${baseUrl}/components/native-select`, {
      waitUntil: 'networkidle',
    });
    assert.equal(
      await page.locator('zen-native-select select').evaluate(
        select => getComputedStyle(select).appearance,
      ),
      'none',
    );
    assert.equal(
      await page.locator(
        'zen-native-select > zen-icon[data-zen-select-icon]',
      ).count(),
      1,
    );
    await page.goto(`${baseUrl}/components/slider`, {
      waitUntil: 'networkidle',
    });
    assert.equal(
      await page.locator('zen-slider input').evaluate(
        input => getComputedStyle(input).appearance,
      ),
      'none',
    );

    await page.goto(`${baseUrl}/components/toggle-group`, {
      waitUntil: 'networkidle',
    });
    await page.locator('zen-toggle-group button[value="right"]').click();
    assert.equal(
      await page.locator('zen-toggle-group button[value="right"]')
        .getAttribute('aria-pressed'),
      'true',
    );
    assert.equal(
      await page.locator('zen-toggle-group').getAttribute('value'),
      'right',
    );

    await page.goto(`${baseUrl}/components/sidebar`, {
      waitUntil: 'networkidle',
    });
    const sidebarTrigger = page.locator(
      'zen-sidebar [data-zen-sidebar-trigger]',
    );
    const sidebarPanel = page.locator(
      'zen-sidebar [data-zen-sidebar-panel]',
    );
    assert.equal(await sidebarTrigger.getAttribute('aria-expanded'), 'true');
    assert.equal(await sidebarPanel.getAttribute('hidden'), null);
    await sidebarTrigger.click();
    assert.equal(await sidebarTrigger.getAttribute('aria-expanded'), 'false');
    assert.equal(await sidebarPanel.getAttribute('hidden'), '');

    await page.goto(`${baseUrl}/components/notifications`, {
      waitUntil: 'networkidle',
    });
    const notificationScope = page.locator('zen-notifications').first();
    const notificationPosition = await notificationScope.locator(
      '[data-zen-notification-stack]',
    ).evaluate(stack => {
      const style = getComputedStyle(stack);
      return {
        bottom: style.bottom,
        position: style.position,
        right: style.right,
      };
    });
    assert.equal(notificationPosition.position, 'fixed');
    assert.notEqual(notificationPosition.bottom, 'auto');
    assert.notEqual(notificationPosition.right, 'auto');

    const dedupe = await notificationScope.evaluate(scope => {
      const source = scope.querySelector('[data-notification-demo]');
      const send = detail => source.dispatchEvent(
        new CustomEvent('zen-notify', {
          bubbles: true,
          composed: false,
          detail,
        }),
      );
      send({
        version: 1,
        id: 'dedupe',
        tone: 'info',
        message: 'First announcement',
        announcement: 'polite',
        persistent: true,
      });
      send({
        version: 1,
        id: 'dedupe',
        tone: 'success',
        message: 'Updated without duplication',
        announcement: 'polite',
        persistent: true,
      });
      send({ version: 99, id: 'invalid' });
      return {
        size: scope.size,
        visible: scope.visibleCount,
      };
    });
    assert.deepEqual(dedupe, { size: 1, visible: 1 });
    assert.equal(
      await notificationScope.locator('article').count(),
      1,
    );
    assert.match(
      await notificationScope.locator('article').textContent(),
      /Updated without duplication/,
    );
    await page.waitForFunction(() =>
      document.querySelector(
        'zen-notifications [data-zen-live="polite"]',
      )?.textContent === 'First announcement'
    );

    const bounded = await notificationScope.evaluate(scope => {
      let accepted = 0;
      for (let index = 0; index < 25; index++) {
        if (scope.notify({
          version: 1,
          id: `bounded-${index}`,
          tone: 'info',
          message: `Bounded ${index}`,
          announcement: 'none',
          durationMs: 120000,
        })) accepted++;
      }
      return {
        accepted,
        size: scope.size,
        visible: scope.visibleCount,
      };
    });
    assert.deepEqual(bounded, { accepted: 25, size: 23, visible: 3 });
    assert.equal(
      await notificationScope.locator('article').count(),
      3,
    );
    await page.waitForFunction(() =>
      [...document.querySelectorAll(
        'zen-notifications article',
      )].some(article => article.dataset.depth === '2')
    );
    const collapsedStack = await notificationScope.locator(
      '[data-zen-notification-stack]',
    ).evaluate(stack => {
      const articles = [...stack.querySelectorAll('article')];
      return {
        depths: articles.map(article => article.dataset.depth),
        height: stack.getBoundingClientRect().height,
        positions: articles.map(article =>
          getComputedStyle(article).position
        ),
        transforms: articles.map(article =>
          getComputedStyle(article).transform
        ),
      };
    });
    assert.deepEqual(collapsedStack.depths, ['2', '1', '0']);
    assert.deepEqual(
      collapsedStack.positions,
      ['absolute', 'absolute', 'absolute'],
    );
    await notificationScope.locator('article').last().hover();
    await page.waitForTimeout(300);
    const expandedStack = await notificationScope.locator(
      '[data-zen-notification-stack]',
    ).evaluate(stack => ({
      height: stack.getBoundingClientRect().height,
      rects: [...stack.querySelectorAll('article')].map(article => {
        const bounds = article.getBoundingClientRect();
        return {
          bottom: bounds.bottom,
          left: bounds.left,
          right: bounds.right,
          top: bounds.top,
        };
      }),
      tops: [...stack.querySelectorAll('article')].map(
        article => Math.round(article.getBoundingClientRect().top),
      ),
      transforms: [...stack.querySelectorAll('article')].map(
        article => getComputedStyle(article).transform,
      ),
    }));
    assert.ok(expandedStack.height > collapsedStack.height);
    assert.equal(new Set(expandedStack.tops).size, 3);
    const expandedGaps = [
      expandedStack.rects[1].top - expandedStack.rects[0].bottom,
      expandedStack.rects[2].top - expandedStack.rects[1].bottom,
    ];
    for (const gap of expandedGaps) {
      assert.ok(gap >= 10 && gap <= 14, JSON.stringify(expandedGaps));
    }
    assert.notDeepEqual(
      expandedStack.transforms,
      collapsedStack.transforms,
    );
    const gapX =
      (expandedStack.rects[0].left + expandedStack.rects[0].right) / 2;
    const gapY =
      (expandedStack.rects[0].bottom + expandedStack.rects[1].top) / 2;
    await page.mouse.move(gapX, gapY);
    await page.waitForTimeout(100);
    const gapState = await notificationScope.locator(
      '[data-zen-notification-stack]',
    ).evaluate(stack => ({
      height: stack.getBoundingClientRect().height,
      hovered: stack.matches(':hover'),
    }));
    assert.equal(gapState.hovered, true);
    assert.ok(gapState.height >= expandedStack.height - 1);
    await page.mouse.move(0, 0);

    const actionScope = await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      scope.id = 'action-scope';
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      window.__notificationAction = null;
      scope.addEventListener('zen-notification-action', event => {
        window.__notificationAction = event.detail;
      });
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'action',
          tone: 'error',
          message: 'Action required',
          announcement: 'assertive',
          persistent: true,
          action: {
            token: 'opaque-secret-token',
            label: 'Retry',
          },
        },
      }));
      return scope.id;
    });
    assert.equal(
      await page.locator(`#${actionScope}`).evaluate(
        scope => scope.records,
      ),
      undefined,
    );
    const actionArticle = page.locator(
      `#${actionScope} [data-zen-notification-id="action"]`,
    );
    assert.doesNotMatch(
      await actionArticle.evaluate(article => article.outerHTML),
      /opaque-secret-token/,
    );
    await actionArticle.locator('.zen-notification-action').focus();
    await page.locator(`#${actionScope}`).evaluate(scope => {
      const source = scope.querySelector('button');
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'action-neighbor',
          tone: 'info',
          message: 'Neighbor',
          announcement: 'none',
          persistent: true,
        },
      }));
    });
    assert.equal(
      await actionArticle.locator('.zen-notification-action').evaluate(
        action => document.activeElement === action,
      ),
      true,
    );
    await actionArticle.locator('.zen-notification-action').click();
    assert.deepEqual(
      await page.evaluate(() => window.__notificationAction),
      {
        version: 1,
        id: 'action',
        token: 'opaque-secret-token',
      },
    );
    await page.locator(`#${actionScope}`).evaluate(scope => {
      const source = scope.querySelector('button');
      source.dispatchEvent(new CustomEvent(
        'zen-dismiss-notification',
        {
          bubbles: true,
          composed: false,
          detail: { version: 1, id: 'action' },
        },
      ));
    });
    await actionArticle.waitFor({ state: 'detached' });

    await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      scope.id = 'announcement-scope';
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      window.__announcements = [];
      const region = scope.querySelector('[data-zen-live="polite"]');
      new MutationObserver(() => {
        if (region.textContent) {
          window.__announcements.push(region.textContent);
        }
      }).observe(region, { childList: true });
      for (let index = 0; index < 3; index++) {
        source.dispatchEvent(new CustomEvent('zen-notify', {
          bubbles: true,
          composed: false,
          detail: {
            version: 1,
            id: `announcement-${index}`,
            tone: 'info',
            message: `Announcement ${index}`,
            announcement: 'polite',
            persistent: true,
          },
        }));
      }
    });
    await page.waitForFunction(() =>
      window.__announcements?.length === 3
    );
    assert.deepEqual(
      await page.evaluate(() => window.__announcements),
      ['Announcement 0', 'Announcement 1', 'Announcement 2'],
    );

    const composedRejected = await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: true,
        detail: {
          version: 1,
          id: 'composed',
          tone: 'info',
          message: 'Must be rejected',
          announcement: 'none',
          persistent: true,
        },
      }));
      return scope.size;
    });
    assert.equal(composedRejected, 0);

    await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      scope.id = 'focus-timer-scope';
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'focus-timer',
          tone: 'warning',
          message: 'Focus timer',
          announcement: 'none',
          durationMs: 300,
          action: { token: 'focus-token', label: 'Keep focused' },
        },
      }));
    });
    const focusTimer = page.locator(
      '#focus-timer-scope [data-zen-notification-id="focus-timer"]',
    );
    await focusTimer.locator('.zen-notification-action').focus();
    await page.locator('#focus-timer-scope').evaluate(scope => {
      const source = scope.querySelector(':scope > button');
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'focus-neighbor',
          tone: 'info',
          message: 'Focus neighbor',
          announcement: 'none',
          persistent: true,
        },
      }));
    });
    await page.waitForTimeout(500);
    assert.equal(await focusTimer.count(), 1);
    assert.equal(
      await focusTimer.locator('.zen-notification-action').evaluate(
        action => document.activeElement === action,
      ),
      true,
    );
    await page.mouse.move(0, 0);
    await page.locator('#catalogMain').focus();
    await page.waitForFunction(() =>
      !document.querySelector(
        '#focus-timer-scope [data-zen-notification-id="focus-timer"]',
      )
    );

    await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      scope.id = 'timer-scope';
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'timer',
          tone: 'info',
          message: 'Paused timer',
          announcement: 'none',
          durationMs: 300,
        },
      }));
    });
    const timerArticle = page.locator('#timer-scope article');
    await timerArticle.hover();
    await page.waitForTimeout(500);
    assert.equal(await timerArticle.count(), 1);
    await page.mouse.move(0, 0);
    await page.waitForFunction(() =>
      !document.querySelector('#timer-scope article')
    );

    await page.evaluate(() => {
      const scope = document.createElement('zen-notifications');
      scope.id = 'hidden-timer-scope';
      const source = document.createElement('button');
      scope.append(source);
      document.body.append(scope);
      source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'hidden-timer',
          tone: 'info',
          message: 'Hidden timer',
          announcement: 'none',
          durationMs: 300,
        },
      }));
      Object.defineProperty(document, 'hidden', {
        configurable: true,
        value: true,
      });
      document.dispatchEvent(new Event('visibilitychange'));
    });
    await page.waitForTimeout(500);
    assert.equal(
      await page.locator('#hidden-timer-scope article').count(),
      1,
    );
    await page.evaluate(() => {
      Object.defineProperty(document, 'hidden', {
        configurable: true,
        value: false,
      });
      document.dispatchEvent(new Event('visibilitychange'));
    });
    await page.waitForFunction(() =>
      !document.querySelector('#hidden-timer-scope article')
    );

    const isolated = await page.evaluate(() => {
      const makeScope = id => {
        const scope = document.createElement('zen-notifications');
        scope.id = id;
        const source = document.createElement('button');
        scope.append(source);
        document.body.append(scope);
        return { scope, source };
      };
      const first = makeScope('scope-one');
      const second = makeScope('scope-two');
      first.source.dispatchEvent(new CustomEvent('zen-notify', {
        bubbles: true,
        composed: false,
        detail: {
          version: 1,
          id: 'isolated',
          tone: 'success',
          message: 'Only first scope',
          announcement: 'none',
          persistent: true,
        },
      }));
      return [first.scope.size, second.scope.size];
    });
    assert.deepEqual(isolated, [1, 0]);

    const lightCanvas = await page.evaluate(() =>
      getComputedStyle(document.documentElement)
        .getPropertyValue('--zenbu-sys-color-surface-page')
        .trim()
    );
    await page.locator('#themeToggle').click();
    const darkCanvas = await page.evaluate(() =>
      getComputedStyle(document.documentElement)
        .getPropertyValue('--zenbu-sys-color-surface-page')
        .trim()
    );
    assert.notEqual(lightCanvas, darkCanvas);
    assert.equal(
      await page.evaluate(() => localStorage.getItem('zen-theme')),
      'dark',
    );

    assert.deepEqual(errors, []);
    await context.close();

    const darkContext = await browser.newContext({ colorScheme: 'dark' });
    const darkPage = await darkContext.newPage();
    await darkPage.goto(baseUrl, { waitUntil: 'networkidle' });
    assert.equal(
      await darkPage.locator('#themeToggle').getAttribute('aria-pressed'),
      'true',
    );
    const systemDarkCanvas = await darkPage.evaluate(() =>
      getComputedStyle(document.documentElement)
        .getPropertyValue('--zenbu-sys-color-surface-page')
        .trim()
    );
    await darkPage.locator('#themeToggle').click();
    const explicitLightCanvas = await darkPage.evaluate(() =>
      getComputedStyle(document.documentElement)
        .getPropertyValue('--zenbu-sys-color-surface-page')
        .trim()
    );
    assert.notEqual(systemDarkCanvas, explicitLightCanvas);
    await darkContext.close();

    const mobileContext = await browser.newContext({
      colorScheme: 'light',
      viewport: { width: 390, height: 844 },
    });
    const mobilePage = await mobileContext.newPage();
    const mobileErrors = [];
    mobilePage.on('pageerror', error => {
      mobileErrors.push(error.stack || error.message);
    });
    mobilePage.on('console', message => {
      if (message.type() === 'error') mobileErrors.push(message.text());
    });
    await mobilePage.goto(baseUrl, { waitUntil: 'networkidle' });
    await mobilePage.waitForFunction(() =>
      customElements.get('zen-date-picker') &&
      document.querySelectorAll(
        '.catalog-nav[aria-label="Components"] a',
      ).length === 70
    );
    const mobileFailures = await mobilePage.evaluate(() => {
      const routes = [
        '/',
        '/tokens',
        '/icons',
        ...[...document.querySelectorAll(
          '.catalog-nav[aria-label="Components"] a',
        )].map(link => new URL(link.href).pathname),
      ];
      const failures = [];
      for (const route of routes) {
        history.replaceState({}, '', route);
        window.dispatchEvent(new PopStateEvent('popstate'));
        const page = document.querySelector(
          '[data-catalog-page]:not([hidden])',
        );
        if (!page ||
            document.documentElement.scrollWidth > innerWidth + 1 ||
            page.getBoundingClientRect().right > innerWidth + 1) {
          failures.push(route);
        }
      }
      return failures;
    });
    assert.deepEqual(mobileFailures, []);
    await mobilePage.goto(`${baseUrl}/components/date-picker`, {
      waitUntil: 'networkidle',
    });
    await mobilePage.locator(
      'zen-date-picker [data-zen-date-trigger]',
    ).click();
    const mobileCalendarBounds = await mobilePage.locator(
      'zen-date-picker [data-zen-calendar-panel]',
    ).evaluate(panel => {
      const bounds = panel.getBoundingClientRect();
      return {
        bottom: bounds.bottom,
        left: bounds.left,
        right: bounds.right,
        top: bounds.top,
      };
    });
    assert.ok(mobileCalendarBounds.left >= 0);
    assert.ok(mobileCalendarBounds.right <= 390);
    assert.ok(mobileCalendarBounds.top >= 0);
    assert.ok(mobileCalendarBounds.bottom <= 844);
    assert.deepEqual(mobileErrors, []);
    await mobileContext.close();
  } finally {
    if (browser) await browser.close();
    await stopProcess(server);
  }
})().catch(error => {
  console.error(error.stack || error);
  process.exitCode = 1;
});