AGENT SKILL

e2e-tests

Autonomously launch, monitor, retry, and report all Physical AI cloud E2E tests across independent Azure ML and OSMO GPU infrastructure.

License 许可
MIT
最近更新
2026-11-11
Stars
★ 138
Forks
72

01 前言 Front Matter

name
testing
description
Test patterns, fixture structure, and when to use E2E vs unit tests.

02 资源文件 2

03 SKILL.md 正文

Testing

Use this skill when writing or modifying tests in this repository.

Rust crate tests

Unit tests live alongside code in #[cfg(test)] modules. Integration tests go in each crate's tests/ directory.

cargo test -p microsoft-webui-handler   # one crate
cargo test --workspace                   # all crates
cargo xtask test                         # via xtask (part of quality gate)

Every code change ships with tests:

Change type Requirement
New public API At least one unit test per function/method
Bug fix Regression test that fails without the fix
Performance change Benchmark comparison (before/after)
Refactor Existing tests pass unchanged

Never remove, weaken, or #[ignore] an existing test unless explicitly asked.

WebUI Node package tests

cargo xtask test builds the host native addon and the WebUI TypeScript package, then runs pnpm --filter @microsoft/webui test with WEBUI_ADDON_PATH set to the artifact reported by Cargo. This includes the projection compiler, adapter, class-factory, parser, and native build/render regressions in both the local cargo xtask check gate and the PR Test job. Browser suites run separately via cargo xtask e2e.

Shared test utilities (webui-test-utils)

The webui-test-utils crate provides common Rust test helpers, builders, and fixtures. Check it before writing new helpers - avoid duplicating across crates.

[dev-dependencies]
webui-test-utils = { path = "../webui-test-utils" }

Docs component tests

Colocate docs component tests under docs/.webui-press/components/<component>/, for example benchmark-preview/benchmark-preview.test.ts. Keep component coverage with its owner rather than in packages/webui-press/tests/.

Keep tutorial tests beside the Markdown lessons in docs/start/ and site-navigation tests beside their regions in docs/.webui-press/regions/. The shared Press runner includes these tests through pnpm --filter @microsoft/webui-press test. Its build:test command type-checks and bundles these locations into dist-test; use unique owner-prefixed test filenames. Reuse the existing native and website fixture helpers. Test modules are not component runtime entries and must not enter the published site.

webui-framework E2E fixtures

The packages/webui-framework package uses Playwright for E2E tests. Each fixture is a mini WebUI app compiled and rendered by the real pipeline.

See tests/fixtures/README.md for the full reference.

Fixture structure

tests/fixtures/<name>/
  src/
    index.html                 Page template (uses the component)
    <tag-name>/
      <tag-name>.html          Component template (real WebUI syntax)
      <tag-name>.css           Component CSS (optional)
  state.json                   Initial render state (all bound properties)
  element.ts                   Component class (NO template registration)
  <name>.spec.ts               Playwright tests
  webui.config.json            Build options override (optional)

How it works

The test server (fixture-render.ts) auto-discovers fixtures with src/index.html, calls @microsoft/webui build() + render() to produce SSR HTML with template IIFEs, hydration markers, and inventory. The result is served at /<name>/fixture.html.

Creating a new fixture

  1. Create fixtures/<name>/src/index.html — page template:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"><title>My Fixture</title></head>
<body>
  <test-widget label="Hello"></test-widget>
</body>
</html>
  1. Create fixtures/<name>/src/test-widget/test-widget.html — component template:
<span class="label">{{label}}</span>
<span class="count">{{count}}</span>
<button class="inc" @click="{increment()}">+</button>
  1. Create fixtures/<name>/state.json — initial state:
{ "label": "Hello", "count": 0 }
  1. Create fixtures/<name>/element.ts — component class only:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { WebUIElement, attr, observable } from '../../../src/index.js';

export class TestWidget extends WebUIElement {
  @attr label = 'Hello';
  @observable count = 0;

  increment(): void {
    this.count += 1;
  }
}

TestWidget.define('test-widget');
  1. Create fixtures/<name>/<name>.spec.ts — Playwright tests:
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { expect, test } from '@playwright/test';

test.describe('widget fixture', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/<name>/fixture.html');
    await page.waitForFunction(() => {
      const el = document.querySelector('test-widget');
      return el && (el as any).$ready === true;
    });
  });

  test('renders SSR content', async ({ page }) => {
    await expect(page.locator('test-widget .label')).toHaveText('Hello');
    await expect(page.locator('test-widget .count')).toHaveText('0');
  });

  test('updates on click', async ({ page }) => {
    await page.locator('test-widget .inc').click();
    await expect(page.locator('test-widget .count')).toHaveText('1');
  });
});

Template syntax quick reference

Feature Syntax
Text binding {{propertyName}}
Event binding @click="{handler()}" or @click="{handler(e)}"
Boolean attribute ?disabled="{{isDisabled}}"
Dynamic attribute href="{{url}}"
Mixed attribute href="/items/{{id}}"
Complex property :items="{{items}}"
Element ref w-ref="{myElement}"
Conditional <if condition="show">...</if>
Negation <if condition="!hidden">...</if>
Comparison <if condition="count > 0">...</if>
Compound <if condition="active && !busy">...</if>
Loop <for each="item in items">...</for>
Nested loop <for each="group in groups">...<for each="item in group.items">...</for></for>
Shadow DOM <template shadowrootmode="open">...</template>
Root event <template shadowrootmode="open" @click="{handler(e)}">
Slot <slot></slot>

Dynamic children pattern

Components only created via document.createElement() (not in any template) need a false <if> in the page template to make their template IIFEs available:

<body>
  <my-host></my-host>
  <if condition="showChild"><my-child></my-child></if>
</body>

With state.json: { "showChild": false }.

Per-fixture build config

Create webui.config.json to override build options:

{ "css": "module" }

Light and Shadow fixtures

Ordinary unwrapped fixture components exercise the Shadow default. Set "dom": "light" in webui.config.json to exercise global Light rendering; a fixture component requiring Shadow inside that build must author a sole top-level <template shadowrootmode="open">. A sole bare top-level <template> explicitly exercises Light even in the default Shadow fixture. See fixtures/dom-default/ and fixtures/light-dom/ for both paths through the real pipeline. Reserve manual registerCompiledTemplate fixtures for raw template-metadata scenarios.

Running framework E2E tests

cd packages/webui-framework
pnpm build                    # build the framework
pnpm test                     # unit + E2E tests
npx playwright test           # E2E only
npx playwright test tests/fixtures/<name>/  # one fixture

Test support package (@microsoft/webui-test-support)

The packages/webui-test-support package provides:

  • registerCompiledTemplate(name, meta) — register a raw TemplateMeta object (for manual/light-DOM fixtures)
  • renderTemplateScript(name, meta) — render a template as an inline <script> tag
  • renderFixtures({ fixturesRoot }) — build+render all pipeline fixtures
  • buildFixtureEntries({ ... }) — bundle element.ts files via esbuild
  • startFixtureServer({ ... }) — start the HTTP fixture server

When to use what

Scenario Tool
Rust crate logic (parsing, rendering, state, expressions) #[test] unit tests
Rust crate integration (full pipeline) tests/ integration tests
Rust performance cargo bench with Criterion
Framework hydration, reactive updates, DOM behavior Playwright E2E fixtures
Router navigation, lazy loading, chain diffing Playwright E2E fixtures
Template metadata encoding/decoding Node unit tests (pnpm test:unit)

04 同仓库更多 Skills