You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
We're using test-runner to take Visual Regression snapshots of our components. Sometimes the test runner compares an the incorrect story to the snapshot. So our "default story" would sometimes be compared against a snapshot of the next story, "warning story" in this case.
This usually doesn't happen when running the test runner a second time which makes me think it might be related to Vite taking a while to bundle the story on the first view?
To Reproduce
test-runner.ts
import{TestRunnerConfig,getStoryContext,waitForPageReady,}from'@storybook/test-runner'import{injectAxe,checkA11y,configureAxe}from'axe-playwright'import{toMatchImageSnapshot}from'jest-image-snapshot'importpathfrom'path'importfsfrom'fs'import{contract,gel2Themes,gel3Themes}from'@snsw-gel/theming'import{Page}from'playwright'constthemes=[...gel2Themes, ...gel3Themes]asyncfunctionwaitForReady(page: Page){awaitpage.waitForTimeout(30)awaitpage.waitForLoadState('networkidle')awaitwaitForPageReady(page)awaitpage.evaluate(async()=>{while(true){if(document.readyState==='complete'){awaitnewPromise(resolve=>setTimeout(resolve,100))if(document.readyState==='complete'){break}}awaitnewPromise(resolve=>{document.addEventListener('DOMContentLoaded',resolve,{once: true,})})}})awaitpage.evaluate(async()=>{awaitdocument.fonts.ready})}asyncfunctionremoveThemes(page: Page){awaitpage.evaluate(themes=>{document.body.classList.remove(...themes)},themes.map(t=>t.className),)}asyncfunctionenableTheme(page: Page,idx: number){awaitpage.evaluate(async([idx,themes])=>{themes.forEach((cls,i)=>{document.body.classList.toggle(cls,i===idx)})},[idx,themes.map(t=>t.className)]asconst,)}asyncfunctionrunAxeTest(page: Page,storyContext){awaitremoveThemes(page)// Apply story-level a11y rulesawaitconfigureAxe(page,{rules: storyContext.parameters?.a11y?.config?.rules,})awaitcheckA11y(page,'#storybook-root',{detailedReport: true,verbose: false,// pass axe options defined in @storybook/addon-a11yaxeOptions: storyContext.parameters?.a11y?.options,})}asyncfunctionrunVisualRegressionTesting(page: Page,storyContext){constbrowserName=page.context()?.browser()?.browserType().name()constbreakpointsToTest=newSet(['smMobile','lgMobile','tablet'])letentries=Object.entries(contract.config.breakpoints).filter(([key])=>breakpointsToTest.has(key),)letrootDir=path.resolve(storyContext.parameters.fileName)while(rootDir!=='/'){constpackageJsonPath=path.resolve(rootDir,'package.json')if(fs.existsSync(packageJsonPath)){break}rootDir=path.resolve(rootDir,'..')}if(browserName!=='webkit'){if(!storyContext.kind.includes('default'))returnentries=[entries[entries.length-1]]}for(let[breakpointKey,breakpoint]ofentries){letmaxWidth='max'inbreakpoint ? breakpoint.max : breakpoint.min+1letpageHeight=1080awaitpage.setViewportSize({width: maxWidth-1,height: pageHeight,})constheight=awaitpage.evaluate(()=>{returndocument.querySelector('#storybook-root')?.getBoundingClientRect().height})while(height&&pageHeight<height){pageHeight+=1080}awaitpage.setViewportSize({width: maxWidth-1,height: pageHeight,})for(leti=0;i<themes.length;i++){consttheme=themes[i]awaitenableTheme(page,i)awaitwaitForReady(page)constcustomSnapshotsDir=`${rootDir}/snapshots/${storyContext.kind}/${theme.className.replace('.','')}/${breakpointKey}`constimage=awaitpage.screenshot()expect(image).toMatchImageSnapshot({
customSnapshotsDir,customSnapshotIdentifier: storyContext.id,})}}}constconfig: TestRunnerConfig={logLevel: 'none',setup(){// @ts-ignoreexpect.extend({ toMatchImageSnapshot })},asyncpreVisit(page,context){// Inject Axe utilities in the page before the story rendersawaitinjectAxe(page)},asyncpostVisit(page,context){// Get entire context of a story, including parameters, args, argTypes, etc.conststoryContext=awaitgetStoryContext(page,context)if(storyContext.parameters?.e2e?.enabled===false){return}constbrowserName=page.context()?.browser()?.browserType().name()if(browserName!=='webkit'){if(!storyContext.kind.includes('default'))return}awaitpage.addStyleTag({content: ` * { transition: none !important; -webkit-transition: none !important; -moz-transition: none !important; -o-transition: none !important; -ms-transition: none !important; animation: none !important; -webkit-animation: none !important; -moz-animation: none !important; -o-animation: none !important; -ms-animation: none !important; transition-duration: 0s !important; animation-duration: 0s !important; } svg animate { display: none !important; } `,})awaitwaitForPageReady(page)// Do not test a11y for stories that disable a11yif(storyContext.parameters?.a11y?.enabled!==false){awaitrunAxeTest(page,storyContext)}if(storyContext.parameters?.visual?.enabled!==false&&!process.env.CI){awaitrunVisualRegressionTesting(page,storyContext)}},}exportdefaultconfig
main.tsx
importtype{StorybookConfig}from'@storybook/react-vite'import{InlineConfig,mergeConfig}from'vite'importfsfrom'fs'importosfrom'os'import{join,dirname,resolve}from'path'/** * This function is used to resolve the absolute path of a package. * It is needed in projects that use Yarn PnP or are set up within a monorepo. */functiongetAbsolutePath(value: string): any{returndirname(require.resolve(join(value,'package.json')))}constresolveCache=newMap<string,string>()constrequestersCache=newMap<string,Set<string>>()constconfig: StorybookConfig={stories: ['../../../packages/*/src/**/*.stories.@(js|ts|tsx|jsx)','../../../packages/*/stories/**/*.stories.@(js|ts|tsx|jsx)','../../../packages/*/stories/**/*.mdx',],staticDirs: ['../public'],typescript: {check: true,reactDocgen: 'react-docgen-typescript',reactDocgenTypescriptOptions: {shouldExtractLiteralValuesFromEnum: true,shouldRemoveUndefinedFromOptional: true,include: ['../../**/src/**/*.{ts,tsx}'],},},addons: [getAbsolutePath('@storybook/addon-links'),getAbsolutePath('@storybook/addon-essentials'),getAbsolutePath('@storybook/addon-interactions'),'@storybook/addon-docs',getAbsolutePath('storybook-addon-jsx'),getAbsolutePath('@storybook/addon-a11y'),getAbsolutePath('@storybook/addon-mdx-gfm'),],core: {},docs: {autodocs: true,},asyncviteFinal(config,{ configType }){if(configType==='DEVELOPMENT'){// Your development configuration goes here}if(configType==='PRODUCTION'){// Your production configuration goes here.}returnmergeConfig<InlineConfig,InlineConfig>(config,{assetsInclude: ['**/*.md'],resolve: {alias: [],},optimizeDeps: {include: ['@babel/parser','react-element-to-jsx-string','@babel/runtime/helpers/interopRequireWildcard','@mdx-js/react','@storybook/addon-docs','@storybook/react','@duetds/date-picker','@duetds/date-picker/dist/loader','@stencil/core','@base2/pretty-print-object','@storybook/client-api','@storybook/blocks','@storybook/client-logger','fast-deep-equal','lodash','styled-components','lodash-es','lodash/isPlainObject','lodash/mapValues','lodash/pickBy','lodash/pick','lodash/startCase','lodash/isFunction','lodash/isString','util-deprecate','@storybook/csf','react-router','react-router-dom','global','synchronous-promise','memoizerific','stable','doctrine','html-tags','escodegen','acorn','prettier','@prettier/sync','acorn-jsx','@base2/pretty-print-object','prop-types','react-dom','qs','uuid-browser','uuid-browser/v4','jest-mock',// '@snsw-gel/react',],},define: {'process.env.PATHNAME': JSON.stringify(process.env.PATHNAME||""),'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),'process.env.STORYBOOK': JSON.stringify(true),'PKG_NAME': JSON.stringify(''),'PKG_VERSION': JSON.stringify(''),'GEL_NAME': JSON.stringify(require('../../react/package.json').name,),'GEL_VERSION': JSON.stringify(require('../../react/package.json').version,),'SNAPSHOT_RELEASE': JSON.stringify(/\d+\.\d+.\d+-.*/.test(require('../../react/package.json').version,),),},// Your environment configuration hereplugins: [{enforce: 'post',name: 'vite-plugin-resolve',resolveId(id,requester, ...rest){if(id==='package.json'&&requester){lettarget=dirname(requester)letresolved=''while(!resolved&&target!==os.homedir()){letfoundPackage=resolve(target,'package.json',)if(fs.existsSync(foundPackage)){resolved=foundPackage}else{target=dirname(target)}}if(resolved){returnresolved}}if(id==='@snsw-gel/storybook'){returnrequire.resolve('../dist/esm/index.mjs')}letresulttry{result=require.resolve(id)}catch(e){returnnull}constcachedResult=resolveCache.get(id)letrequesters=requestersCache.get(id)if(!requesters){requesters=newSet()requesters.add(requester!)requestersCache.set(id,requesters)}if(cachedResult&&cachedResult!==result){console.warn(`Multiple requests resolving to different locations recieved for ${id}${[ ...requesters,].join(', ')}`,)}returnresult},},],})},framework: {name: getAbsolutePath('@storybook/react-vite'),options: {},},}exportdefaultconfig
Expected behaviour
Ideally the test runner would wait for the previous tests to finish before moving to the next story
Screenshots
In the above screenshot the test runner has rendered the next story "warning" before the the previous tests have finished
Describe the bug
We're using test-runner to take Visual Regression snapshots of our components. Sometimes the test runner compares an the incorrect story to the snapshot. So our "default story" would sometimes be compared against a snapshot of the next story, "warning story" in this case.
This usually doesn't happen when running the test runner a second time which makes me think it might be related to Vite taking a while to bundle the story on the first view?
To Reproduce
test-runner.ts
main.tsx
Expected behaviour
Ideally the test runner would wait for the previous tests to finish before moving to the next story
Screenshots
In the above screenshot the test runner has rendered the next story "warning" before the the previous tests have finished
System
System:
OS: macOS 13.6.2
CPU: (10) arm64 Apple M1 Pro
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.19.0 - /private/var/folders/fn/6s5sc1b56pv0618wzc4k16v00000gq/T/xfs-0781bbb6/node
Yarn: 4.0.2 - /private/var/folders/fn/6s5sc1b56pv0618wzc4k16v00000gq/T/xfs-0781bbb6/yarn <----- active
npm: 10.2.3 - /usr/local/bin/npm
Browsers:
Chrome: 122.0.6261.129
Safari: 16.6
Additional context
–
The text was updated successfully, but these errors were encountered: