Skip to content
Draft
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
29 changes: 29 additions & 0 deletions apps/popover-tests-headless/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.storybook/
.vscode/
bundle-size/
config/
coverage/
e2e/
etc/
node_modules/
src/
dist/types/
temp/
__fixtures__
__mocks__
__tests__

*.api.json
*.log
*.spec.*
*.stories.*
*.test.*
*.yml

# config files
*config.*
*rc.*
.editorconfig
.eslint*
.git*
.prettierignore
10 changes: 10 additions & 0 deletions apps/popover-tests-headless/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const rootMain = require('../../../.storybook/main');

module.exports = /** @type {Omit<import('../../../.storybook/main'), 'typescript'|'babel'>} */ ({
...rootMain,
stories: [...rootMain.stories, '../src/**/*.mdx', '../src/**/index.stories.@(ts|tsx)'],
addons: [...rootMain.addons],
webpackFinal: (config, options) => {
return { ...rootMain.webpackFinal(config, options) };
},
});
9 changes: 9 additions & 0 deletions apps/popover-tests-headless/.storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as rootPreview from '../../../.storybook/preview';

/** @type {typeof rootPreview.decorators} */
export const decorators = [...rootPreview.decorators];

/** @type {typeof rootPreview.parameters} */
export const parameters = { ...rootPreview.parameters };

export const tags = ['autodocs'];
10 changes: 10 additions & 0 deletions apps/popover-tests-headless/.storybook/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "",
"allowJs": true,
"checkJs": true,
"types": ["static-assets", "environment"]
},
"include": ["../src/**/*.stories.ts", "../src/**/*.stories.tsx", "*.js"]
}
70 changes: 70 additions & 0 deletions apps/popover-tests-headless/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# @fluentui/popover-tests-headless

Private test application for the Headless overlay runtime.

The app exercises both implementations behind the same component APIs:

- native HTML Popover/Dialog and CSS Anchor Positioning;
- lazy Portal, Tabster, and `react-positioning` fallback.

No Playwright tests are included yet. The initial workflow is manual
verification, followed by Playwright coverage after the scenarios are approved.

## CSR manual verification

Start the private Storybook from the repository root:

```bash
yarn nx storybook popover-tests-headless
```

Each control has its own page under **Overlay Runtime / CSR**:

| Control | Story URL |
| -------- | -------------------------------------------- |
| Popover | `?path=/story/overlay-runtime-csr--popover` |
| Menu | `?path=/story/overlay-runtime-csr--menu` |
| Tooltip | `?path=/story/overlay-runtime-csr--tooltip` |
| Dropdown | `?path=/story/overlay-runtime-csr--dropdown` |
| Dialog | `?path=/story/overlay-runtime-csr--dialog` |
| Toast | `?path=/story/overlay-runtime-csr--toast` |

Every CSR page provides reload controls for:

- auto-detected mode;
- forced native mode;
- forced fallback mode.

The Popover page includes basic, nested, and collision-placement scenarios.
Stable `data-testid` hooks are included for future Playwright tests.

## SSR verification

Run the SSR harness:

```bash
yarn nx run popover-tests-headless:test-ssr
```

Each control also has a separate **Overlay Runtime / SSR** page:

| Control | Story URL |
| -------- | -------------------------------------------- |
| Popover | `?path=/story/overlay-runtime-ssr--popover` |
| Menu | `?path=/story/overlay-runtime-ssr--menu` |
| Tooltip | `?path=/story/overlay-runtime-ssr--tooltip` |
| Dropdown | `?path=/story/overlay-runtime-ssr--dropdown` |
| Dialog | `?path=/story/overlay-runtime-ssr--dialog` |
| Toast | `?path=/story/overlay-runtime-ssr--toast` |

The SSR harness renders each `*.stories.tsx` export without a browser. The same
pages can be opened in Storybook to inspect client hydration.

Every SSR page reports:

- server render mode: always `ssr`;
- requested hydration runtime: auto, native, or fallback;
- runtime resolved by the hydrated client.

The hydration runtime buttons use the same `overlayRuntime` query parameter as
the CSR pages. They do not change the server render mode.
3 changes: 3 additions & 0 deletions apps/popover-tests-headless/config/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/** Jest test setup file. */

require('@testing-library/jest-dom');
14 changes: 14 additions & 0 deletions apps/popover-tests-headless/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// @ts-check
const fluentPlugin = require('@fluentui/eslint-plugin');

/** @type {import("eslint").Linter.Config[]} */
module.exports = [
...fluentPlugin.configs['flat/node'],
{
rules: {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'import/no-extraneous-dependencies': ['error', { packageDir: ['../../', './'] }],
'no-restricted-globals': 'off',
},
},
];
15 changes: 15 additions & 0 deletions apps/popover-tests-headless/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @ts-check

/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
displayName: 'popover-tests-headless',
preset: '../../jest.preset.js',
transform: {
'^.+\\.tsx?$': ['@swc/jest', {}],
},
testEnvironment: 'jsdom',
coverageDirectory: './coverage',
setupFilesAfterEnv: ['./config/tests.js'],
};
3 changes: 3 additions & 0 deletions apps/popover-tests-headless/just.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { preset } from '@fluentui/scripts-tasks';

preset();
24 changes: 24 additions & 0 deletions apps/popover-tests-headless/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@fluentui/popover-tests-headless",
"version": "0.0.0",
"description": "Private SSR and CSR verification app for Headless overlays",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/microsoft/fluentui"
},
"license": "MIT",
"scripts": {
"clean": "yarn run -T just-scripts clean",
"code-style": "yarn run -T just-scripts code-style",
"lint": "yarn run -T just-scripts lint",
"storybook": "yarn run -T storybook dev",
"test": "yarn run -T jest --passWithNoTests",
"type-check": "yarn run -T just-scripts type-check",
"test-ssr": "yarn run -T test-ssr \"./src/stories/**/*.stories.tsx\""
},
"dependencies": {
"@fluentui/react-components": "*",
"@fluentui/react-headless-components-preview": "*"
}
}
8 changes: 8 additions & 0 deletions apps/popover-tests-headless/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "popover-tests-headless",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"implicitDependencies": [],
"sourceRoot": "apps/popover-tests-headless/src",
"tags": ["vNext", "platform:web"]
}
Loading
Loading