diff --git a/apps/vr-tests-react-components/screener.config.js b/apps/vr-tests-react-components/screener.config.js index 56a9934f99dc1c..0e229136d99d10 100644 --- a/apps/vr-tests-react-components/screener.config.js +++ b/apps/vr-tests-react-components/screener.config.js @@ -24,7 +24,7 @@ function getCurrentHash() { * @param {string} options.sourceBranchName * @param {string} options.deployUrl * @param {string} options.targetBranch - * @returns + * @returns {import('@fluentui/scripts/screener/screener.types').ScreenerRunnerConfig} */ function getConfig({ screenerApiKey, sourceBranchName, deployUrl, targetBranch }) { const baseBranch = targetBranch ? targetBranch.replace(/^refs\/heads\//, '') : 'master'; @@ -38,6 +38,7 @@ function getConfig({ screenerApiKey, sourceBranchName, deployUrl, targetBranch } baseBranch, failureExitCode: 0, alwaysAcceptBaseBranch: true, + states: [], ...(sourceBranchName !== 'master' ? { commit: getCurrentHash() } : null), baseUrl: `${deployUrl}/react-components-screener/iframe.html`, }; diff --git a/apps/vr-tests/screener.config.js b/apps/vr-tests/screener.config.js index b928986b51524a..13f073e99c97d0 100644 --- a/apps/vr-tests/screener.config.js +++ b/apps/vr-tests/screener.config.js @@ -27,7 +27,7 @@ function getCurrentHash() { * @param {string} options.sourceBranchName * @param {string} options.deployUrl * @param {string} options.targetBranch - * @returns + * @returns {import('@fluentui/scripts/screener/screener.types').ScreenerRunnerConfig} */ function getConfig({ screenerApiKey, sourceBranchName, deployUrl, targetBranch }) { const baseBranch = targetBranch ? targetBranch.replace(/^refs\/heads\//, '') : 'master'; @@ -44,6 +44,7 @@ function getConfig({ screenerApiKey, sourceBranchName, deployUrl, targetBranch } alwaysAcceptBaseBranch: true, ...(sourceBranchName !== 'master' ? { commit: getCurrentHash() } : null), baseUrl: `${deployUrl}/react-screener/iframe.html`, + states: [], }; console.log('Screener config: ' + JSON.stringify({ ...config, apiKey: '...' }, null, 2)); return config; diff --git a/gulpfile.ts b/gulpfile.ts index e7f72e8db3565c..dd562b2ee3f980 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -22,7 +22,8 @@ tsPaths.register({ require('./scripts/gulp/tasks/bundle'); require('./scripts/gulp/tasks/component-info'); require('./scripts/gulp/tasks/docs'); -require('./scripts/gulp/tasks/screener'); +require('./scripts/gulp/tasks/vr-build'); +require('./scripts/gulp/tasks/vr-test'); require('./scripts/gulp/tasks/stats'); require('./scripts/gulp/tasks/test-unit'); require('./scripts/gulp/tasks/perf'); diff --git a/scripts/gulp/tasks/vr-build.ts b/scripts/gulp/tasks/vr-build.ts new file mode 100644 index 00000000000000..6fe6cb4460b0ff --- /dev/null +++ b/scripts/gulp/tasks/vr-build.ts @@ -0,0 +1,21 @@ +import { task, series } from 'gulp'; +import fs from 'fs'; + +import config from '../../config'; +import getScreenerStates from '../../screener/screener.states'; + +const { paths } = config; + +task('screener:states', cb => { + const states = getScreenerStates(); + const statesJson = JSON.stringify(states, null, 2); + fs.writeFile(paths.docsDist('screenerStates.json'), statesJson, { encoding: 'utf8' }, err => { + if (err) { + cb(err); + } + + cb(); + }); +}); + +task('screener:build', series('build:docs', 'screener:states')); diff --git a/scripts/gulp/tasks/screener.ts b/scripts/gulp/tasks/vr-test.ts similarity index 76% rename from scripts/gulp/tasks/screener.ts rename to scripts/gulp/tasks/vr-test.ts index 329bf716c30e82..9e99e85fda6182 100644 --- a/scripts/gulp/tasks/screener.ts +++ b/scripts/gulp/tasks/vr-test.ts @@ -1,11 +1,13 @@ -import { task, series } from 'gulp'; +import { task } from 'gulp'; import { argv } from 'yargs'; import config from '../../config'; import { getAllPackageInfo } from '../../monorepo'; import { screenerRunner } from '../../screener/screener.runner'; +import getConfig from '../../screener/screener.config'; const { paths } = config; +const docsPackageName = '@fluentui/docs'; // ---------------------------------------- // Visual @@ -15,15 +17,11 @@ task('screener:runner', cb => { // screener-runner doesn't allow to pass custom options if (argv.filter) process.env.SCREENER_FILTER = argv.filter as string; - const docsPackageName = '@fluentui/docs'; - const packageInfos = getAllPackageInfo(); if (Object.values(packageInfos).every(packageInfo => packageInfo.packageJson.name !== docsPackageName)) { throw new Error(`package ${docsPackageName} does not exist in the repo`); } - const screenerConfigPath = paths.base('scripts/screener/screener.config.js'); - // kill the server when done const handlePromiseExit = promise => promise @@ -36,17 +34,14 @@ task('screener:runner', cb => { process.exit(1); }); - const getConfig = require(screenerConfigPath); const screenerConfig = getConfig({ screenerApiKey: process.env.SCREENER_API_KEY, sourceBranchName: process.env.BUILD_SOURCEBRANCHNAME, + deployUrl: process.env.DEPLOYURL, }); + const screenerStates = require(paths.docsDist('screenerStates.json')); + screenerConfig.states = screenerStates; + handlePromiseExit(screenerRunner(screenerConfig)); }); - -// ---------------------------------------- -// Default -// ---------------------------------------- - -task('screener:build', series('build:docs')); diff --git a/scripts/screener/screener.config.js b/scripts/screener/screener.config.js index 64384043d2cab5..ee63d4dea9ec77 100644 --- a/scripts/screener/screener.config.js +++ b/scripts/screener/screener.config.js @@ -36,11 +36,13 @@ const baseBranch = 'master'; * @param {Object} options * @param {string} options.screenerApiKey * @param {string} options.sourceBranchName - * @returns + * @param {string} options.deployUrl + * @returns {import('./screener.types').ScreenerRunnerConfig} */ -function getConfig({ screenerApiKey, sourceBranchName }) { +function getConfig({ screenerApiKey, sourceBranchName, deployUrl }) { // https://github.com/screener-io/screener-runner return { + baseUrl: `${deployUrl}/react-northstar-screener`, apiKey: screenerApiKey, projectRepo: 'microsoft/fluentui/fluentui', @@ -54,9 +56,7 @@ function getConfig({ screenerApiKey, sourceBranchName }) { minShiftGraphic: 1, // Optional threshold for pixel shifts in graphics. compareSVGDOM: false, // Pass if SVG DOM is the same. Defaults to false. }, - - // screenshot every example in maximized mode - states: require('./screener.states').default, + states: [], alwaysAcceptBaseBranch: true, baseBranch, diff --git a/scripts/screener/screener.states.ts b/scripts/screener/screener.states.ts index 20ad7881f1b9fc..5876517c02c5df 100644 --- a/scripts/screener/screener.states.ts +++ b/scripts/screener/screener.states.ts @@ -7,42 +7,44 @@ import path from 'path'; import getScreenerSteps from './screener.steps'; import { ScreenerState } from './screener.types'; -const baseUrl = `${process.env.DEPLOYURL}/react-northstar-screener`; -const examplePaths = glob.sync('packages/fluentui/docs/src/examples/**/*.tsx', { - ignore: ['**/index.tsx', '**/*.knobs.tsx', '**/BestPractices/*.tsx', '**/Playground.tsx'], -}); - -const pathFilter = process.env.SCREENER_FILTER; -const filteredPaths: string[] = minimatch.match(examplePaths, pathFilter || '*', { - matchBase: true, -}); - -if (pathFilter) { - console.log(chalk.bgGreen.black(' --filter '), pathFilter); - filteredPaths.forEach(filteredPath => console.log(`${_.repeat(' ', 10)} ${filteredPath}`)); -} - -const getStateForPath = (examplePath: string): ScreenerState => { - const { name: exampleNameWithoutExtension, base: exampleNameWithExtension, dir: exampleDir } = path.parse( - examplePath, - ); - - const rtl = exampleNameWithExtension.endsWith('.rtl.tsx'); - const exampleUrl = _.kebabCase(exampleNameWithoutExtension); - const pageUrl = `${baseUrl}/maximize/${exampleUrl}/${rtl}`; - - return { - url: pageUrl, - name: exampleNameWithExtension, - - // https://www.npmjs.com/package/screener-runner#testing-interactions - steps: getScreenerSteps(pageUrl, `${exampleDir}/${exampleNameWithoutExtension}.steps`), +export default function getScreenerStates() { + const baseUrl = `${process.env.DEPLOYURL}/react-northstar-screener`; + const examplePaths = glob.sync('packages/fluentui/docs/src/examples/**/*.tsx', { + ignore: ['**/index.tsx', '**/*.knobs.tsx', '**/BestPractices/*.tsx', '**/Playground.tsx'], + }); + + const pathFilter = process.env.SCREENER_FILTER; + const filteredPaths: string[] = minimatch.match(examplePaths, pathFilter || '*', { + matchBase: true, + }); + + if (pathFilter) { + console.log(chalk.bgGreen.black(' --filter '), pathFilter); + filteredPaths.forEach(filteredPath => console.log(`${_.repeat(' ', 10)} ${filteredPath}`)); + } + + const getStateForPath = (examplePath: string): ScreenerState => { + const { name: exampleNameWithoutExtension, base: exampleNameWithExtension, dir: exampleDir } = path.parse( + examplePath, + ); + + const rtl = exampleNameWithExtension.endsWith('.rtl.tsx'); + const exampleUrl = _.kebabCase(exampleNameWithoutExtension); + const pageUrl = `${baseUrl}/maximize/${exampleUrl}/${rtl}`; + + return { + url: pageUrl, + name: exampleNameWithExtension, + + // https://www.npmjs.com/package/screener-runner#testing-interactions + steps: getScreenerSteps(pageUrl, `${exampleDir}/${exampleNameWithoutExtension}.steps`), + }; }; -}; -const screenerStates = filteredPaths.reduce((states, examplePath) => { - states.push(getStateForPath(examplePath)); - return states; -}, [] as ReturnType<typeof getStateForPath>[]); + const screenerStates = filteredPaths.reduce((states, examplePath) => { + states.push(getStateForPath(examplePath)); + return states; + }, [] as ReturnType<typeof getStateForPath>[]); -export default screenerStates; + return screenerStates; +} diff --git a/scripts/screener/screener.types.ts b/scripts/screener/screener.types.ts index 087f92d7ef536d..d7f38c24ec7f43 100644 --- a/scripts/screener/screener.types.ts +++ b/scripts/screener/screener.types.ts @@ -2,7 +2,7 @@ export type ScreenerRunnerConfig = { apiKey: string; projectRepo: string; - diffOptions: { + diffOptions?: { structure: boolean; layout: boolean; style: boolean; @@ -10,14 +10,14 @@ export type ScreenerRunnerConfig = { minLayoutPosition: number; // Optional threshold for Layout changes. Defaults to 4 pixels. minLayoutDimension: number; // Optional threshold for Layout changes. Defaults to 10 pixels. minShiftGraphic: number; // Optional threshold for pixel shifts in graphics. - compareSVGDOM: number; // Pass if SVG DOM is the same. Defaults to false. + compareSVGDOM: boolean; // Pass if SVG DOM is the same. Defaults to false. }; states: ScreenerState[]; alwaysAcceptBaseBranch: boolean; baseBranch: string; - commit: string; + commit?: string; failureExitCode: number; /** Base url of deployed storybook screener should test */