diff design_system/test/storybook_test.js @ 254:2b6e732087ff

[ui] Add complete native component catalog Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Tue, 04 Aug 2026 15:12:09 -0700
parents fdf3816959cb
children 30c2196d03d4
line wrap: on
line diff
--- a/design_system/test/storybook_test.js	Tue Aug 04 12:21:19 2026 -0700
+++ b/design_system/test/storybook_test.js	Tue Aug 04 15:12:09 2026 -0700
@@ -120,6 +120,7 @@
     for (const route of [
       '/',
       '/tokens',
+      '/icons',
       '/components',
       '/components/button',
       '/components/card',
@@ -138,7 +139,10 @@
     for (const asset of [
       '/styles/tokens.css',
       '/styles/components.css',
+      '/styles/shadcn.css',
       '/components/index.js',
+      '/components/icon.js',
+      '/catalog.js',
       '/storybook.js',
     ]) {
       const response = await fetch(`${baseUrl}${asset}`);
@@ -154,9 +158,23 @@
     const context = await browser.newContext({ colorScheme: 'light' });
     const page = await context.newPage();
     const errors = [];
-    page.on('pageerror', error => errors.push(error.message));
+    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') errors.push(message.text());
+      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) {
@@ -167,10 +185,121 @@
     await page.goto(`${baseUrl}/components/button`, {
       waitUntil: 'networkidle',
     });
-    await page.waitForFunction(() =>
-      customElements.get('zen-button') &&
-      customElements.get('zen-story')
+    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, 66);
+    assert.equal(catalogState.links, 66);
+    assert.equal(catalogState.elements.length, 65);
+    assert.deepEqual(catalogState.missing, []);
+    assert.deepEqual(
+      [...new Set(catalogState.statuses)],
+      [200],
     );
+    const brokenCatalogPages = await page.evaluate(routes => {
+      const failures = [];
+      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`);
+          }
+        }
+      }
+      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(),
+      66,
+    );
+    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,
@@ -265,6 +394,114 @@
     });
     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}/tokens`, { waitUntil: 'networkidle' });
+    const colorTokenState = await page.evaluate(() => {
+      const root = document.documentElement;
+      const value = name => getComputedStyle(root)
+        .getPropertyValue(`--zen-color-${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 = value('surface-muted');
+      root.dataset.zenTheme = 'dark';
+      const darkMuted = value('surface-muted');
+      const darkData = Array.from(
+        { length: 10 },
+        (_, index) => value(`data-${index + 1}`),
+      );
+      delete root.dataset.zenTheme;
+      return {
+        darkData,
+        darkMuted,
+        data,
+        lightMuted,
+        materials,
+        rampsComplete,
+      };
+    });
+    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.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.goto(`${baseUrl}/components/field`, {
       waitUntil: 'networkidle',
     });
@@ -285,6 +522,13 @@
     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');
@@ -351,6 +595,519 @@
     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(--zen-color-surface-muted)';
+      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 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(dialogTrigger, dialog);
+
+      const popoverTrigger = document.createElement('button');
+      popoverTrigger.type = 'button';
+      popoverTrigger.dataset.zenTrigger = '';
+      const popover = document.createElement('div');
+      popover.dataset.zenContent = '';
+      popoverHost.append(popoverTrigger, popover);
+
+      const tooltipTrigger = document.createElement('button');
+      tooltipTrigger.type = 'button';
+      tooltipTrigger.dataset.zenTrigger = '';
+      const tooltip = document.createElement('span');
+      tooltip.dataset.zenContent = '';
+      tooltipHost.append(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,
+    );
+    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',
     });
@@ -846,6 +1603,74 @@
     );
     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 === 66
+    );
+    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);