44 * Uses a tab pool for efficient browser tab management
55 */
66
7+ import { existsSync , readFileSync } from 'node:fs' ;
8+ import { dirname , join , parse } from 'node:path' ;
79import { closeBrowser , launchBrowser } from './browser.js' ;
810import { loadConfig } from './config.js' ;
911import { discoverStories } from './crawler.js' ;
@@ -16,9 +18,6 @@ import { generateTasks, processAllTasks } from './tasks.js';
1618 * @returns {Promise<boolean> } True if TDD server is running
1719 */
1820async function isTddModeAvailable ( ) {
19- let { existsSync, readFileSync } = await import ( 'node:fs' ) ;
20- let { join, parse, dirname } = await import ( 'node:path' ) ;
21-
2221 try {
2322 // Look for .vizzly/server.json
2423 let currentDir = process . cwd ( ) ;
@@ -64,11 +63,17 @@ function hasApiToken(config) {
6463 * Uses a tab pool for efficient parallel screenshot capture
6564 * @param {string } storybookPath - Path to static Storybook build
6665 * @param {Object } options - CLI options
67- * @param {Object } context - Plugin context (logger , config, services)
66+ * @param {Object } context - Plugin context (output , config, services)
6867 * @returns {Promise<void> }
6968 */
7069export async function run ( storybookPath , options = { } , context = { } ) {
71- let { logger, config : vizzlyConfig , services } = context ;
70+ let {
71+ output : providedOutput ,
72+ logger : legacyOutput ,
73+ config : vizzlyConfig ,
74+ services,
75+ } = context ;
76+ let output = providedOutput || legacyOutput ;
7277 let browser = null ;
7378 let pool = null ;
7479 let serverInfo = null ;
@@ -77,8 +82,10 @@ export async function run(storybookPath, options = {}, context = {}) {
7782 let buildId = null ;
7883 let startTime = null ;
7984
80- if ( ! logger ) {
81- throw new Error ( 'Logger is required but was not provided in context' ) ;
85+ if ( ! output ) {
86+ throw new Error (
87+ 'Output utilities are required but were not provided in context'
88+ ) ;
8289 }
8390
8491 try {
@@ -90,9 +97,9 @@ export async function run(storybookPath, options = {}, context = {}) {
9097 let hasToken = hasApiToken ( vizzlyConfig ) ;
9198
9299 if ( isTdd ) {
93- logger . info ( '📍 TDD mode: Using local server' ) ;
100+ output . info ( '📍 TDD mode: Using local server' ) ;
94101 } else if ( hasToken ) {
95- logger . info ( '☁️ Run mode: Uploading to cloud' ) ;
102+ output . info ( '☁️ Run mode: Uploading to cloud' ) ;
96103 }
97104
98105 let buildUrl = null ;
@@ -108,7 +115,7 @@ export async function run(storybookPath, options = {}, context = {}) {
108115 testRunner . once ( 'build-created' , buildInfo => {
109116 if ( buildInfo . url ) {
110117 buildUrl = buildInfo . url ;
111- logger . info ( `🔗 ${ buildInfo . url } ` ) ;
118+ output . info ( `🔗 ${ buildInfo . url } ` ) ;
112119 }
113120 } ) ;
114121
@@ -125,7 +132,7 @@ export async function run(storybookPath, options = {}, context = {}) {
125132 pullRequestNumber = gitInfo . prNumber ;
126133 } else {
127134 // Fallback for older CLI versions - use environment variables
128- logger . warn (
135+ output . warn (
129136 '⚠️ Upgrade to @vizzly-testing/cli@>=0.25.0 for improved git detection'
130137 ) ;
131138 branch = process . env . VIZZLY_BRANCH || 'main' ;
@@ -167,29 +174,29 @@ export async function run(storybookPath, options = {}, context = {}) {
167174 process . env . VIZZLY_ENABLED = 'true' ;
168175 } catch ( error ) {
169176 // Log the error and continue without cloud mode
170- logger . error ( `Failed to initialize cloud mode: ${ error . message } ` ) ;
171- logger . warn ( '⚠️ Falling back to local-only mode' ) ;
172- logger . info ( ' Screenshots will not be uploaded to cloud' ) ;
177+ output . error ( `Failed to initialize cloud mode: ${ error . message } ` ) ;
178+ output . warn ( '⚠️ Falling back to local-only mode' ) ;
179+ output . info ( ' Screenshots will not be uploaded to cloud' ) ;
173180 testRunner = null ;
174181 }
175182 }
176183
177184 if ( ! isTdd && ! hasToken ) {
178- logger . warn ( '⚠️ No TDD server or API token found' ) ;
179- logger . info ( ' Run `vizzly tdd start` or set VIZZLY_TOKEN' ) ;
185+ output . warn ( '⚠️ No TDD server or API token found' ) ;
186+ output . info ( ' Run `vizzly tdd start` or set VIZZLY_TOKEN' ) ;
180187 }
181188
182189 // Start HTTP server to serve Storybook static files
183190 serverInfo = await startStaticServer ( config . storybookPath ) ;
184191
185192 // Discover stories
186193 let stories = await discoverStories ( config . storybookPath , config ) ;
187- logger . info (
194+ output . info (
188195 `📚 Found ${ stories . length } stories in ${ config . storybookPath } `
189196 ) ;
190197
191198 if ( stories . length === 0 ) {
192- logger . warn ( '⚠️ No stories found' ) ;
199+ output . warn ( '⚠️ No stories found' ) ;
193200 return ;
194201 }
195202
@@ -199,18 +206,18 @@ export async function run(storybookPath, options = {}, context = {}) {
199206
200207 // Generate all tasks upfront (stories × viewports)
201208 let tasks = generateTasks ( stories , serverInfo . url , config ) ;
202- logger . info (
209+ output . info (
203210 `📸 Processing ${ tasks . length } screenshots (${ config . concurrency } concurrent tabs)`
204211 ) ;
205212
206213 // Process all tasks through the tab pool
207- let errors = await processAllTasks ( tasks , pool , config , logger ) ;
214+ let errors = await processAllTasks ( tasks , pool , config , output ) ;
208215
209216 // Report summary
210217 if ( errors . length > 0 ) {
211- logger . warn ( `\n⚠️ ${ errors . length } screenshot(s) failed:` ) ;
218+ output . warn ( `\n⚠️ ${ errors . length } screenshot(s) failed:` ) ;
212219 errors . forEach ( ( { story, viewport, error } ) => {
213- logger . error ( ` ${ story } @${ viewport } : ${ error } ` ) ;
220+ output . error ( ` ${ story } @${ viewport } : ${ error } ` ) ;
214221 } ) ;
215222 }
216223
@@ -220,11 +227,11 @@ export async function run(storybookPath, options = {}, context = {}) {
220227 await testRunner . finalizeBuild ( buildId , false , true , executionTime ) ;
221228
222229 if ( buildUrl ) {
223- logger . info ( `🔗 View results: ${ buildUrl } ` ) ;
230+ output . info ( `🔗 View results: ${ buildUrl } ` ) ;
224231 }
225232 }
226233 } catch ( error ) {
227- logger . error ( 'Failed to process stories:' , error . message ) ;
234+ output . error ( 'Failed to process stories:' , error . message ) ;
228235
229236 // Mark build as failed if in run mode
230237 if ( testRunner && buildId ) {
0 commit comments