Skip to content

Commit

Permalink
feat (web-components-v3): Add dedicated vr-tests package and integrat…
Browse files Browse the repository at this point in the history
…e with Visual Regression Pipelines (#28222)
  • Loading branch information
TristanWatanabe authored and radium-v committed May 10, 2024
1 parent 16d07dc commit 3c3a7ea
Show file tree
Hide file tree
Showing 14 changed files with 431 additions and 228 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ apps/ts-minbar-test-react @microsoft/fluentui-react-build
apps/ts-minbar-test-react-components @microsoft/fluentui-react-build
apps/vr-tests @microsoft/fluentui-react
apps/vr-tests-react-components @microsoft/fluentui-react
apps/vr-tests-web-components @microsoft/fui-wc
apps/ssr-tests @microsoft/fluentui-react
apps/pr-deploy-site @microsoft/fluentui-react-build
apps/public-docsite-v9 @microsoft/cxe-red @microsoft/fluentui-react-build
Expand Down
14 changes: 14 additions & 0 deletions apps/vr-tests-web-components/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "import"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off"
}
}
85 changes: 85 additions & 0 deletions apps/vr-tests-web-components/.storybook/main.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const path = require('path');
const CircularDependencyPlugin = require('circular-dependency-plugin');
const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin');

const tsBin = require.resolve('typescript');
const tsConfigPath = path.resolve(__dirname, '../../../tsconfig.base.wc.json');

const tsPaths = new TsconfigPathsPlugin({
configFile: tsConfigPath,
});

module.exports = /** @type {import('../../../.storybook/main').StorybookBaseConfig} */ ({
addons: [
{
name: '@storybook/addon-docs',
},
{
name: '@storybook/addon-essentials',
options: {
backgrounds: false,
viewport: false,
toolbars: false,
actions: false,
},
},
],

stories: ['../src/**/*.stories.tsx'],
core: {
builder: 'webpack5',
disableTelemetry: true,
},
babel: {},
typescript: {
// disable react-docgen-typescript (totally not needed here, slows things down a lot)
reactDocgen: false,
},
webpackFinal: async config => {
config.resolve = config.resolve ?? {};
config.resolve.extensions = config.resolve.extensions ?? [];
config.resolve.plugins = config.resolve.plugins ?? [];
config.module = config.module ?? {};
config.plugins = config.plugins ?? [];

config.resolve.extensionAlias = {
'.js': ['.ts', '.js'],
'.mjs': ['.mts', '.mjs'],
};
config.resolve.extensions.push(...['.ts', '.js']);
config.resolve.plugins.push(tsPaths);
config.module.rules = config.module.rules ?? [];
config.module.rules.push(
{
test: /\.([cm]?ts|tsx)$/,
loader: 'ts-loader',
sideEffects: true,
options: {
transpileOnly: true,
compiler: tsBin,
},
},
// Following config is needed to be able to resolve @storybook packages imported in specified files that don't ship valid ESM
// It also enables importing other packages without proper ESM extensions, but that should be avoided !
// @see https://webpack.js.org/configuration/module/#resolvefullyspecified
{
test: /\.m?js/,
resolve: { fullySpecified: false },
},
);

config.plugins.push(
new CircularDependencyPlugin({
exclude: /node_modules/,
failOnError: process.env.NODE_ENV === 'production',
}),
);

// Disable ProgressPlugin which logs verbose webpack build progress. Warnings and Errors are still logged.
if (process.env.TF_BUILD || process.env.LAGE_PACKAGE_NAME) {
config.plugins = config.plugins.filter(({ constructor }) => constructor.name !== 'ProgressPlugin');
}

return config;
},
});
11 changes: 11 additions & 0 deletions apps/vr-tests-web-components/.storybook/manager.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { addons } from '@storybook/addons';

addons.setConfig({
previewTabs: {
canvas: { hidden: true },
},
enableShortcuts: false,
sidebar: {
showRoots: true,
},
});
13 changes: 13 additions & 0 deletions apps/vr-tests-web-components/.storybook/preview.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const parameters = {
layout: 'fullscreen',
controls: { expanded: true },
viewMode: 'docs',
previewTabs: {
canvas: { hidden: true },
},
options: {
storySort: {
method: 'alphabetical',
},
},
};
18 changes: 18 additions & 0 deletions apps/vr-tests-web-components/jest.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// @ts-check

/**
* @type {import('@jest/types').Config.InitialOptions}
*/
module.exports = {
displayName: 'vr-tests-web-components',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsConfig: '<rootDir>/tsconfig.json',
diagnostics: false,
},
},
transform: {
'^.+\\.tsx?$': 'ts-jest',
},
};
29 changes: 29 additions & 0 deletions apps/vr-tests-web-components/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@fluentui/vr-tests-web-components",
"version": "0.0.1",
"private": true,
"description": "Visual regression tests for @fluentui/web-components",
"type": "module",
"scripts": {
"build": "build-storybook -o dist/storybook",
"format": "prettier . -w --ignore-path ../../.prettierignore",
"lint": "eslint src --ext .ts,.tsx",
"start": "start-storybook",
"test": "jest --passWithNoTests",
"type-check": "tsc",
"vr:build": "yarn build",
"vr:test": "storywright --browsers chromium --url dist/storybook --destpath dist/screenshots --waitTimeScreenshot 500 --concurrency 4 --headless true"
},
"devDependencies": {
"@fluentui/eslint-plugin": "*",
"@fluentui/scripts-tasks": "*",
"html-react-parser": "4.0.0",
"typescript": "4.7.4"
},
"dependencies": {
"@fluentui/react-button": "^9.2.3",
"@fluentui/react-storybook-addon": "*",
"@fluentui/web-components": "3.0.0-alpha.24",
"tslib": "^2.1.0"
}
}
6 changes: 6 additions & 0 deletions apps/vr-tests-web-components/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "@fluentui/vr-tests-web-components",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"projectType": "application",
"implicitDependencies": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import * as React from 'react';
import parse from 'html-react-parser';
import { StoryWright, Steps } from 'storywright';
import { accordionDefinition, accordionItemDefinition, FluentDesignSystem } from '@fluentui/web-components';

accordionDefinition.define(FluentDesignSystem.registry);
accordionItemDefinition.define(FluentDesignSystem.registry);

export default {
title: 'Accordion',
decorators: [
(story: () => React.ReactElement) => {
return (
<StoryWright
steps={new Steps()
.snapshot('normal', { cropTo: '.testWrapper' })
.click('#accordion-0')
.snapshot('opened', { cropTo: '.testWrapper' })
.end()}
>
<div className="testWrapper" style={{ width: '300px' }}>
{story()}
</div>
</StoryWright>
);
},
],
};

const add20Filled = `<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M10.5 2.75C10.5 2.33579 10.1642 2 9.75 2C9.33579 2 9 2.33579 9 2.75V9H2.75C2.33579 9 2 9.33579 2 9.75C2 10.1642 2.33579 10.5 2.75 10.5H9V16.75C9 17.1642 9.33579 17.5 9.75 17.5C10.1642 17.5 10.5 17.1642 10.5 16.75V10.5H16.75C17.1642 10.5 17.5 10.1642 17.5 9.75C17.5 9.33579 17.1642 9 16.75 9H10.5V2.75Z"
fill="#212121"
/>
</svg>`;
const subtract20Filled = `<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<rect x="3" y="9.25" width="14" height="1.5" rx="0.75" fill="#212121" />
</svg>`;

export const AccordionWithCustomIcons = () =>
parse(`
<fluent-accordion>
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 1</span>
Accordion Panel 1
</fluent-accordion-item>
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 2</span>
Accordion Panel 1
</fluent-accordion-item>
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 3</span>
Accordion Panel 1
</fluent-accordion-item>
</fluent-accordion>
`);

export const AccordionWithCustomIconsRTL = () =>
parse(`
<fluent-accordion dir="rtl">
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 1</span>
Accordion Panel 1
</fluent-accordion-item>
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 2</span>
Accordion Panel 1
</fluent-accordion-item>
<fluent-accordion-item>
<span slot="collapsed-icon">${add20Filled}</span>
<span slot="expanded-icon">${subtract20Filled}</span>
<span slot="heading">Accordion Header 3</span>
Accordion Panel 1
</fluent-accordion-item>
</fluent-accordion>
`);
15 changes: 15 additions & 0 deletions apps/vr-tests-web-components/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.base.wc.json",
"compilerOptions": {
"target": "ES2019",
"module": "ESNext",
"noEmit": true,
"experimentalDecorators": true,
"resolveJsonModule": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"typeRoots": ["../../node_modules/@types"]
},
"include": ["./src", "./.storybook/*"]
}
45 changes: 45 additions & 0 deletions azure-pipelines.vrt-baseline-web-components.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
batch: true
branches:
include:
- web-components-v3

variables:
skipComponentGovernanceDetection: true

pool: '1ES-Host-Ubuntu'

jobs:
# TODO: When web-components-v3 branch is merged with master, this file can be deleted and everything below this comment
# can be moved to azure-pipelines.vrt-baseline.yml. The corresponding pipeline on ADO can be deleted as well.
- job: VRToolUpdateBaseline_WebComponents
workspace:
clean: all
steps:
- template: .devops/templates/tools.yml

- template: .devops/templates/runpublishvrscreenshot.yml
parameters:
fluentVersion: webcomponents
vrTestPackageName: '@fluentui/vr-tests-web-components'
vrTestPackagePath: 'apps/vr-tests-web-components'

- bash: node node_modules/vrscreenshotdiff/lib/index.js release --clientType "FluentUI-web-components" --buildId $(Build.BuildId)
displayName: 'Run Screenshotdiff update baseline'
env:
API_URL: $(System.CollectionUri)
API_TOKEN: $(fabric-public-pipeline-access-PAT)
API_REPOSITORY: $(Build.Repository.Name)
API_PROJECT: $(System.TeamProject)
SCREENSHOT_ARTIFACT_FOLDER: vrscreenshotwebcomponents
GITHUB_API_TOKEN: $(githubRepoStatusPAT)
STORAGE_ACCOUNT_FLUENTUI: $(STORAGE-ACCOUNT-FLUENTUI)
STORAGE_KEY_FLUENTUI: $(STORAGE-KEY-BLOB-FLUENTUI)
BLOB_CONNECTION_STRING: $(BLOB-CONNECTION-STRING)
VR_APPROVAL_CLIENT_SECRET: $(VR-APPROVAL-CLIENT-SECRET)
VR_APPROVAL_HOST: $(VR_APPROVAL_HOST)
Loading

0 comments on commit 3c3a7ea

Please sign in to comment.