Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/desktop-pipeline-logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fluentui-react-native/storybook-desktop": patch
"@fluentui-react-native/desktop-driver": patch
---

Capture ordered per-command stdout/stderr logs, replay full output on failure or in verbose mode, and report contextual story navigation and test failures with nested causes.
7 changes: 7 additions & 0 deletions .changeset/inline-wdio-story-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fluentui-react-native/storybook-desktop": minor
"@fluentui-react-native/desktop-driver": minor
"@fluentui-react-native/components": patch
---

Add opt-in executable WebdriverIO callbacks in React Native stories, Storybook-owned test configuration, isolated Node execution, and Button examples.
7 changes: 7 additions & 0 deletions .changeset/named-platform-wdio-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fluentui-react-native/storybook-desktop": minor
"@fluentui-react-native/desktop-driver": patch
"@fluentui-react-native/components": patch
---

Add named, individually isolated WDIO story tests with target-platform context and test-name filtering. Migrate Button's declarative desktop-driver plans to executable WebdriverIO callbacks.
6 changes: 6 additions & 0 deletions .changeset/story-grouped-desktop-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fluentui-react-native/storybook-desktop": patch
"@fluentui-react-native/components": patch
---

Navigate to each test's story before execution, bound navigation waits, and group static plans and inline WebdriverIO callbacks by story in desktop smoke tests.
5 changes: 5 additions & 0 deletions .changeset/storybook-ci-readiness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@fluentui-react-native/storybook-desktop': patch
---

Wait for the authenticated Storybook preview to initialize before navigating after app startup or restart. Allow the aggregate WDIO subprocess contract enough CI time without relaxing individual callback deadlines.
5 changes: 5 additions & 0 deletions .changeset/storybook-source-config-import.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fluentui-react-native/storybook-desktop": patch
---

Fix loading WDIO settings from Storybook's source-config fallback before compiled JavaScript exists.
Original file line number Diff line number Diff line change
Expand Up @@ -113,37 +113,48 @@ layout order, or native class names. Keep the initial args deterministic and
add identifiers only to the small smoke set that agents and CI actively
validate.

Portable desktop automation is authored inline under
`parameters.desktopDriver` and typed with `DesktopStoryTests` from
`@fluentui-react-native/desktop-driver/authoring`:
Prefer executable WebdriverIO tests under `wdio`, typed with
`WdioStory<StoryObj<typeof Component>>` from
`@fluentui-react-native/storybook-desktop/testing` using `import type`.
The story is the suite (`describe`), and named functions are its cases (`it`):

```tsx
export const Default: Story = {
tags: ['desktop-e2e'],
parameters: {
desktopDriver: {
version: 1,
tests: [
{
id: 'enabled-button',
steps: [
{ action: 'wait', target: { testId: 'story-button' } },
{ expect: { state: 'enabled', target: { testId: 'story-button' }, value: true } },
],
},
],
} satisfies DesktopStoryTests,
wdio: {
'is enabled': async ({ browser, expect }) => {
await expect(await browser.$('~story-button')).toBeEnabled();
},
},
};
```

Keep the plan a static JSON literal. Storybook extracts it without importing
the React Native module, so variables, functions, spreads, computed properties,
and runtime platform branches are rejected. Express real differences with
`platforms`, `requires`, and explicit skip results. Use `testID` for actions;
use role, accessible name, state, and value assertions to verify the public
accessibility contract. Button, Checkbox, and Input defaults are the canonical
initial examples.
Each callback receives `browser`, `expect`, `platform`, `desktop`, `signal`,
and `skip`. The typed target `platform` is `macos`, `windows`, or `win32`;
Win32 is distinct from its WebDriver `platformName` of `windows`. Branch
inside callbacks for genuine platform differences and use explicit skip
reasons for unsupported `browser.capabilities['furn:features']`.

Button is the proof of concept and no longer uses custom `desktopDriver`
plans. Keep names static and callbacks self-contained. Node helpers may be
dynamically imported inside each callback, but callbacks cannot capture
story-module bindings. The shared Babel config strips all test functions
before native dependency collection. Named cases get independent previews,
sessions, workers, deadlines, results, and failure evidence.

The single-function `wdio` form remains supported. Run with
`yarn storybook test --<platform>` and optionally `--test <name-glob>`.
`--list` discovers names without executing code. The `stories-and-tests`
smoke mode runs these functions alongside remaining legacy plans, grouped by
story. See the [executable test contract](../../../../packages/agentic/storybook-desktop/README.md#executable-tests-inside-stories).

Legacy Checkbox and Input tests still use static JSON
`parameters.desktopDriver` plans typed with `DesktopStoryTests` from
`@fluentui-react-native/desktop-driver/authoring`. Keep those plans static and
use declarative `platforms` and `requires` until they are migrated; do not add
functions or dynamic values to the old format.

The components package's `test:stories` project checks the experimental
Button stories without emitting them into the component library.

Button uses focused appearance, size, shape, icon, selection, disabled, and constrained-content stories. Icon uses a
source and size overview plus focused font, image, SVG, size, color, and accessibility stories.
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ jobs:
name: Storybook_macos_Dump
path: |
apps/storybook/artifacts/macos
apps/storybook/artifacts/storybook-commands
${{ steps.desktop-driver.outputs.doctor-path }}

ios:
Expand Down Expand Up @@ -409,6 +410,7 @@ jobs:
name: Storybook_windows_Dump
path: |
apps/storybook/artifacts/windows
apps/storybook/artifacts/storybook-commands
${{ steps.desktop-driver.outputs.doctor-path }}
${{ steps.desktop-driver.outputs.cache-root }}/v1/artifacts/**/build.log
${{ steps.desktop-driver.outputs.cache-root }}/v1/diagnostics/**
Expand Down Expand Up @@ -500,6 +502,7 @@ jobs:
name: Storybook_win32_Dump
path: |
apps/storybook/artifacts/win32
apps/storybook/artifacts/storybook-commands
${{ steps.desktop-driver.outputs.doctor-path }}
${{ steps.desktop-driver.outputs.cache-root }}/v1/artifacts/**/build.log
${{ steps.desktop-driver.outputs.cache-root }}/v1/diagnostics/**
Expand Down
19 changes: 16 additions & 3 deletions apps/storybook/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,24 @@ Read [`agent-map.yaml`](agent-map.yaml) first for the compact architecture, look
commands against that listener.
- macOS, Windows, and Win32 use their source-built native helpers. Keep the
deterministic fake provider limited to package contract tests.
- Authored tests belong in component story `parameters.desktopDriver`, not in
this app. The app owns identity, package discovery, platform exclusions, and
generated manifests.
- Author new tests as component story `wdio` functions or named function
collections, not app-local test scripts. Button demonstrates migration from
the legacy `parameters.desktopDriver` plans, which remain supported.
The app owns identity, package discovery, platform exclusions, and manifests.
- Run executable tests with `yarn storybook test --<platform>` and optionally
`--test <name-glob>`. Callbacks receive the target endpoint as `platform`;
each named case gets an isolated worker/session and fresh preview. Defaults belong in
`storybook.config.mts` under `wdio`; the shared Babel config removes
callbacks from native bundles. `stories-and-tests` smoke mode runs configured
callbacks together with static plans, grouped by story. Always navigate to
the requested story and await correlated readiness before executing tests.
- Keep `storybook-desktop.generated`, reports, trees, screenshots, and run
manifests ignored. Never patch generated runtime identity or story manifests.
- Shared command logs merge stdout/stderr in write order under
`artifacts/storybook-commands`. Failed commands replay the complete log;
`--verbose` also replays successful commands. Preserve labeled stderr
diagnostics and nested failure causes rather than replacing them with
exit-code-only summaries.
- Treat the exact-platform and portable-plan digests as contracts. A dynamic or
invalid plan must fail generation rather than disappear from the manifest.
- Preserve nonce-authenticated runtime hello/readiness/error messages and
Expand Down
27 changes: 24 additions & 3 deletions apps/storybook/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ app-owned, while the platform-neutral UI, configuration helpers, and `storybook-
from the shared package. The app exposes only the shared CLI entry points; native lifecycle scripts
remain package-owned.

Button demonstrates named executable `wdio` tests instead of custom
`desktopDriver` plans. Each callback receives the target `platform` and its
own fresh preview/session/worker. Run `yarn storybook test --macos --list` to
discover the case names, or use `--test <name-glob>` to filter them. With
`yarn storybook driver --macos` running and the app launched via
`yarn storybook run --macos`, run
`yarn storybook test --macos --story 'components-button--*'`.
The shared runner extracts the callbacks for Node, injects WebdriverIO and
native assertions, and leaves test dependencies out of Metro. Optional runner
defaults belong under `wdio` in `storybook.config.mts`; no separate test config
is needed. See the [authoring contract](../../packages/agentic/storybook-desktop/README.md#executable-tests-inside-stories).
`stories-and-tests` smoke mode also runs these callbacks, grouped with each
story's static plans. Both paths select the correct page before executing tests.

Commands retain merged stdout/stderr logs under `artifacts/storybook-commands`.
Successful commands emit short summaries; failures replay their complete log
and print contextual story/test diagnostics. Use
`yarn storybook --verbose smoke --macos --mode stories-and-tests` to include
successful-command output as well. No shell redirection is required.

## Layout

```
Expand Down Expand Up @@ -305,7 +325,8 @@ Run it alongside `yarn start` and `yarn storybook run --macos|--windows`. The on
## Writing stories

Follow the package-level story authoring instructions in `../../packages/agentic/components/AGENTS.md`. Add a
`*.stories.tsx` file next to its component; standalone native package story globs are listed explicitly in `src/main.ts`.
`*.stories.tsx` file next to its component; package discovery belongs in `storybook.config.mts`, adapted by `src/main.ts`.
See `../../packages/agentic/components/src/components/button/button.stories.tsx` for the canonical higher-order component example.
Portable tests are static `parameters.desktopDriver` data with stable `testID`
selectors; Button, Checkbox, and Input demonstrate the initial contract.
Prefer named `wdio` functions with stable `testID` selectors and injected
`platform` context, as demonstrated by Button. Checkbox and Input retain the
legacy static `parameters.desktopDriver` format during migration.
12 changes: 12 additions & 0 deletions apps/storybook/agent-map.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ services:
instance:
command: yarn storybook instance --<platform>
policy: use-reported-ports-and-target-id
executable_tests:
command: yarn storybook test --<platform>
discovery: yarn storybook test --<platform> --list
authoring: top-level wdio callbacks or named callback collections in CSF3 stories
config: storybook.config.mts wdio settings
lifecycle: attached-session-per-test-with-isolated-node-worker
context_platform: macos-or-windows-or-win32-target-endpoint
test_filter: --test <name-glob>
smoke_mode: stories-and-tests
execution: navigate-and-remount-then-run-tests-grouped-by-story

agent_commands:
generate_manifest: yarn storybook manifest --<platform>
Expand Down Expand Up @@ -81,6 +91,8 @@ validation:
lifecycle: yarn storybook smoke --<platform> --mode stories-and-tests

output_hygiene:
- Commands retain merged stdout/stderr logs under artifacts/storybook-commands; failures replay grouped output.
- Use --verbose to replay successful-command logs; files update continuously while commands run.
- Use structured CLI output instead of logging raw channel events.
- Search large native build logs for errors and final status instead of reading them in full.
- Keep warning suppression exact; console diagnostics remain available even when LogBox hides a warning.
16 changes: 12 additions & 4 deletions packages/agentic/components/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@ invariants; detailed authoring recipes live in the
- Higher-order components live in `src/components`; read `src/components/AGENTS.md`.
- Primitive components live in `src/primitives`; read `src/primitives/AGENTS.md`.
- Story files are library source and follow the tests and stories reference.
- Portable desktop story tests are static `parameters.desktopDriver` plans.
Use the public authoring types, stable `testID` selectors, declarative
capability requirements, and no platform branches or executable callbacks.
- Prefer executable tests under top-level `wdio`, as one callback or a map
of named callbacks. Button is the migration proof of concept; legacy
`parameters.desktopDriver` plans remain supported for other components.
Use stable `testID` selectors and the injected target `platform` for real
platform differences, with explicit skips for unsupported capabilities.
- Executable tests are typed
with `WdioStory` from `storybook-desktop/testing` using `import type`.
Keep callbacks self-contained; dynamically import Node helpers inside
them so the shared Babel transform can exclude them from native bundles.
Each named case gets a fresh story, session, and worker; do not share native
element handles or depend on previous cases.
- Storybook application, native project, Metro, bundle, or CocoaPods work follows the
[Storybook instructions](../../../apps/storybook/AGENTS.md) and the `agentic-storybook-development` skill.
- Native React Native Windows Fabric component work follows the
Expand Down Expand Up @@ -42,7 +50,7 @@ invariants; detailed authoring recipes live in the
- Export higher-order components and public types explicitly from `src/index.ts`; export primitives and their public types
explicitly from `src/primitives/index.ts`. Never use wildcard exports.
- Colocate runtime tests, type tests, and Storybook stories with the implementation.
- Keep desktop story plans inline and statically extractable; do not hide them
- Keep legacy desktop story plans inline and statically extractable; do not hide them
behind variables, spreads, functions, or computed values.
- Use package scripts for format, lint, build, tests, and snapshots.
- Do not copy web-only APIs, CSS behavior, or DOM assumptions into React Native.
Expand Down
6 changes: 5 additions & 1 deletion packages/agentic/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"format": "fluentui-scripts format",
"lint": "fluentui-scripts lint",
"report:spec-source-drift": "node ./scripts/spec-contracts/report-spec-source-drift.cjs",
"test": "node ./scripts/spec-contracts/check-spec-contracts.cjs && fluentui-scripts jest",
"test": "node ./scripts/spec-contracts/check-spec-contracts.cjs && yarn test:stories && fluentui-scripts jest",
"test:stories": "tsc -p tsconfig.stories.json",
"update-snapshots": "fluentui-scripts jest -u"
},
"dependencies": {
Expand All @@ -48,19 +49,22 @@
"@fluentui-react-native/desktop-driver": "workspace:*",
"@fluentui-react-native/focus-zone": "workspace:*",
"@fluentui-react-native/scripts": "workspace:*",
"@fluentui-react-native/storybook-desktop": "workspace:*",
"@office-iss/react-native-win32": "^0.81.0",
"@react-native-community/cli": "^20.0.0",
"@react-native-community/cli-platform-android": "^20.0.0",
"@react-native-community/cli-platform-ios": "^20.0.0",
"@react-native/babel-preset": "^0.81.0",
"@react-native/metro-config": "^0.81.0",
"@storybook/react-native": "^10.4.7",
"@testing-library/react-native": "catalog:",
"@types/react": "~19.1.4",
"react": "19.1.4",
"react-native": "^0.81.6",
"react-native-macos": "^0.81.0",
"react-native-svg": "^15.12.1",
"react-native-windows": "^0.81.0",
"storybook": "^10.4.0",
"test-renderer": "catalog:"
},
"peerDependencies": {
Expand Down
10 changes: 6 additions & 4 deletions packages/agentic/components/src/components/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ audit.
layout.
- Test both paths of a self-driving axis, and test that an externally driven `selected` does not change on press.
- Keep a self-driving controlled prop out of story `args`, and keep an identity-changing axis out of story controls.
- Author desktop automation under `parameters.desktopDriver` as static data
satisfying `DesktopStoryTests`. Use one stable `testID` per interacted
element, declare capabilities, and assert public native semantics rather than
implementation structure.
- Prefer top-level `wdio` functions or named function collections demonstrated
by Button. Use the injected `platform`, explicit capability skips, stable
`testID` selectors, and public native semantics. The story supplies the suite
scope and each named case is isolated. Run with `storybook test`.
- Legacy `parameters.desktopDriver` plans remain supported. Do not put
functions in static plans or import Node helpers at story-module scope.

## Focused references

Expand Down
Loading
Loading