Skip to content

Commit 96677d6

Browse files
committed
feat(react-text-vr): bootstrap visual-regression project
1 parent f7a583d commit 96677d6

14 files changed

+473
-0
lines changed

.github/CODEOWNERS

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ packages/react-components/react-tabs/library @microsoft/cxe-prg @dmytrokirpa
250250
packages/react-components/react-tabs/stories @microsoft/cxe-prg @dmytrokirpa
251251
packages/react-components/react-text/library @microsoft/cxe-prg @marcosmoura
252252
packages/react-components/react-text/stories @microsoft/cxe-prg @marcosmoura
253+
packages/react-components/react-text/visual-regression @microsoft/cxe-prg @marcosmoura
253254
packages/react-components/react-textarea/library @microsoft/cxe-prg
254255
packages/react-components/react-textarea/stories @microsoft/cxe-prg
255256
packages/react-components/react-tooltip/library @microsoft/cxe-prg
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
{
2+
"extends": ["../../../../.eslintrc.json"],
3+
"ignorePatterns": ["!**/*"],
4+
"overrides": [
5+
{
6+
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
7+
"rules": {}
8+
},
9+
{
10+
"files": ["*.ts", "*.tsx"],
11+
"rules": {}
12+
},
13+
{
14+
"files": ["*.js", "*.jsx"],
15+
"rules": {}
16+
},
17+
{
18+
"files": ["*.json"],
19+
"parser": "jsonc-eslint-parser",
20+
"rules": {
21+
"@nx/dependency-checks": [
22+
"error",
23+
{
24+
"ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"]
25+
}
26+
]
27+
}
28+
}
29+
]
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
const path = require('path');
2+
3+
const { registerTsPaths, registerRules, rules, loadWorkspaceAddon } = require('@fluentui/scripts-storybook');
4+
const tsConfigPath = path.resolve(__dirname, '../../../../../tsconfig.base.json');
5+
6+
module.exports = /** @type {import('@storybook/react-webpack5').StorybookConfig} */ ({
7+
addons: [loadWorkspaceAddon('@fluentui/react-storybook-addon', { tsConfigPath })],
8+
stories: ['../src/**/*.stories.tsx'],
9+
core: {
10+
disableTelemetry: true,
11+
},
12+
framework: {
13+
name: '@storybook/react-webpack5',
14+
options: {
15+
builder: {
16+
useSWC: true,
17+
lazyCompilation: false,
18+
},
19+
},
20+
},
21+
typescript: {
22+
// disable react-docgen-typescript (totally not needed here, slows things down a lot)
23+
reactDocgen: false,
24+
},
25+
webpackFinal: (config, options) => {
26+
if (options.configType === 'PRODUCTION') {
27+
// Disable source maps
28+
config.devtool = false;
29+
}
30+
registerTsPaths({ config, configFile: tsConfigPath });
31+
registerRules({ config, rules: [rules.griffelRule] });
32+
33+
return config;
34+
},
35+
swc() {
36+
return {
37+
jsc: {
38+
target: 'es2019',
39+
parser: {
40+
syntax: 'typescript',
41+
tsx: true,
42+
decorators: true,
43+
dynamicImport: true,
44+
},
45+
transform: {
46+
decoratorMetadata: true,
47+
legacyDecorator: true,
48+
},
49+
keepClassNames: true,
50+
externalHelpers: true,
51+
loose: true,
52+
minify: {
53+
mangle: false,
54+
},
55+
},
56+
};
57+
},
58+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/** @type {import("@fluentui/react-storybook-addon").FluentParameters} */
2+
export const parameters = {
3+
layout: 'none',
4+
mode: 'vr-test',
5+
reactStorybookAddon: {
6+
disabledDecorators: ['AriaLive'],
7+
},
8+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "",
5+
"allowJs": true,
6+
"checkJs": true,
7+
"types": ["static-assets", "environment"]
8+
},
9+
"include": ["*.js"]
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# react-text-visual-regression
2+
3+
This library was generated with [Nx](https://nx.dev).
4+
5+
## Building
6+
7+
Run `nx build react-text-visual-regression` to build the library.
8+
9+
## Running visual regression
10+
11+
Run `nx run react-text-visual-regression:test-vr-cli`.
12+
13+
## About
14+
15+
Project for visual regression scenarios.
16+
17+
> Uses Free, Secure and OSS VR testing solution based on:
18+
>
19+
> - Storybook to author VR scenarios
20+
> - StoryWright for capturing Stories and their interactions
21+
> - Visual Regression Assert CLI - to execute diffing and updating snapshots baseline
22+
23+
## Authoring VR scenarios
24+
25+
1. write stories following Storybook CSF3 format
26+
27+
```ts
28+
import { Steps, type StoryParameters } from 'storywright';
29+
30+
export default {
31+
title: 'Text Converged',
32+
// 1. Define decorators to create scoped images that won't change dimensions over time
33+
decorators: [
34+
Story => (
35+
<div className="testWrapper" style={{ width: '250px' }}>
36+
<Story />
37+
</div>
38+
),
39+
],
40+
// 2. If interactions are needed , define those via StoryWright Steps API
41+
parameters: {
42+
storyWright: { steps: new Steps().snapshot('normal', { cropTo: '.testWrapper' }).end() },
43+
} satisfies StoryParameters,
44+
} satisfies Meta<typeof Text>;
45+
```
46+
47+
2. Override steps per story if needed
48+
49+
```ts
50+
export const Default = {
51+
name: 'Default',
52+
render: () => {
53+
return <div>markup</div>;
54+
},
55+
// 1. overriding default export steps - this story will execute different behaviors
56+
parameters: {
57+
storyWright: { steps: new Steps().click().snapshot('normal').end() },
58+
} satisfies StoryParameters,
59+
} satisfies StoryObj;
60+
```
61+
62+
3. leverage `@fluentui/visual-regression-utilities` to create scenarios for Right to Left, Dark Mode, High Contrast Mode etc
63+
64+
```ts
65+
export const Default = {
66+
// 1. name is mandatory to properly propagate it to getStoryVariant fn call
67+
name: 'Default',
68+
render: () => {
69+
return <div>markup</div>;
70+
},
71+
} satisfies StoryObj;
72+
73+
// 2. create new Variants of your scenario
74+
export const DefaultRTL = getStoryVariant(Default, RTL);
75+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "@fluentui/react-text-visual-regression",
3+
"version": "0.0.0",
4+
"private": true,
5+
"dependencies": {
6+
"@fluentui/react-text": "*",
7+
"@fluentui/visual-regression-utilities": "*"
8+
},
9+
"peerDependencies": {
10+
"@storybook/react": "^7.6.20"
11+
},
12+
"devDependencies": {
13+
"@fluentui/react-storybook-addon": "*",
14+
"@fluentui/scripts-storybook": "*"
15+
},
16+
"type": "commonjs",
17+
"main": "./src/index.js",
18+
"typings": "./src/index.d.ts"
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
{
2+
"name": "react-text-visual-regression",
3+
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
4+
"sourceRoot": "packages/react-components/react-text/visual-regression/src",
5+
"projectType": "library",
6+
"tags": ["vNext", "platform:web", "visual-regression"],
7+
"targets": {
8+
"build-storybook": {
9+
"command": "storybook build -o dist/storybook --quiet",
10+
"options": {
11+
"cwd": "{projectRoot}"
12+
}
13+
},
14+
"generate-image-for-vrt": {
15+
"command": "rm -rf dist/vrt/actual && storywright --browsers chromium --url dist/storybook --destpath dist/vrt/actual --waitTimeScreenshot 500 --concurrency 4 --headless true",
16+
"options": {
17+
"cwd": "{projectRoot}"
18+
},
19+
"metadata": {
20+
"help": {
21+
"command": "yarn storywright --help",
22+
"example": {}
23+
}
24+
},
25+
"dependsOn": ["build-storybook"],
26+
"inputs": ["{projectRoot}/src/**/*.stories.tsx"],
27+
"outputs": ["{projectRoot}/dist/vrt/actual/**"],
28+
"cache": true
29+
},
30+
"test-vr-cli": {
31+
"command": "visual-regression-assert assert --baselineDir src/__snapshots__ --outputPath dist/vrt",
32+
"options": {
33+
"cwd": "{projectRoot}"
34+
},
35+
"dependsOn": [
36+
"build-storybook",
37+
"generate-image-for-vrt",
38+
{ "projects": ["visual-regression-assert"], "target": "build" }
39+
],
40+
"inputs": ["{projectRoot}/dist/vrt/screenshots/**", "{projectRoot}/src/**/*.stories.tsx"],
41+
"metadata": {
42+
"help": {
43+
"command": "yarn visual-regression-assert --help",
44+
"example": {}
45+
}
46+
}
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)