From 1fdb21c32fe529dc99c8e74e75f24667f925d511 Mon Sep 17 00:00:00 2001 From: cxx5208 Date: Sat, 4 Apr 2026 13:23:10 -0700 Subject: [PATCH 1/3] Add fileOnLargeOutput outputMode and maxStdOutputSize config options Closes #339 --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7450688..3d7ac8f 100644 --- a/README.md +++ b/README.md @@ -436,8 +436,17 @@ Playwright CLI will load config from `.playwright/cli.config.json` by default so /** * Whether to save snapshots, console messages, network logs and other session logs to a file or to the standard output. Defaults to "stdout". + * - "stdout": Output to console immediately + * - "file": Save all output to files in outputDir + * - "fileOnLargeOutput": Output to stdout if small, otherwise save to file (controlled by maxStdOutputSize) */ - outputMode?: 'file' | 'stdout'; + outputMode?: 'file' | 'stdout' | 'fileOnLargeOutput'; + + /** + * When outputMode is "fileOnLargeOutput", defines the maximum size in bytes before switching to file output. + * Defaults to 1048576 (1MB). + */ + maxStdOutputSize?: number; console?: { /** From d856a62169b0e04c4edbdb7ca7c66fd623761af7 Mon Sep 17 00:00:00 2001 From: cxx5208 Date: Sat, 4 Apr 2026 13:23:12 -0700 Subject: [PATCH 2/3] Implement fileOnLargeOutput logic for CLI output handling Closes #339 --- playwright-cli.js | 89 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/playwright-cli.js b/playwright-cli.js index 6ea172f..151b822 100755 --- a/playwright-cli.js +++ b/playwright-cli.js @@ -16,6 +16,93 @@ */ const { program } = require('playwright-core/lib/tools/cli-client/program'); +const fs = require('fs'); +const path = require('path'); +const os = require('os'); const packageJson = require('./package.json'); -program({ embedderVersion: packageJson.version }); +const DEFAULT_MAX_OUTPUT_SIZE = 1048576; + +function getOutputMode() { + try { + const configPath = path.join(process.cwd(), '.playwright', 'cli.config.json'); + if (fs.existsSync(configPath)) { + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + return config.outputMode || null; + } + } catch {} + return null; +} + +function getMaxStdOutputSize() { + try { + const configPath = path.join(process.cwd(), '.playwright', 'cli.config.json'); + if (fs.existsSync(configPath)) { + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + if (config.maxStdOutputSize !== undefined) { + return config.maxStdOutputSize; + } + } + } catch {} + return DEFAULT_MAX_OUTPUT_SIZE; +} + +function getOutputDir() { + try { + const configPath = path.join(process.cwd(), '.playwright', 'cli.config.json'); + if (fs.existsSync(configPath)) { + const config = JSON.parse(fs.readFileSync(configPath, 'utf8')); + if (config.outputDir) { + return config.outputDir; + } + } + } catch {} + return path.join(os.tmpdir(), 'playwright-cli-output'); +} + +async function main() { + const outputMode = getOutputMode(); + + if (outputMode !== 'fileOnLargeOutput') { + await program({ embedderVersion: packageJson.version }); + return; + } + + const maxSize = getMaxStdOutputSize(); + const outputDir = getOutputDir(); + + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + const originalLog = console.log; + let outputBuffer = ''; + + console.log = (...args) => { + outputBuffer += args.map(a => String(a)).join(' ') + '\n'; + }; + + try { + await program({ embedderVersion: packageJson.version }); + } finally { + console.log = originalLog; + } + + const outputSize = Buffer.byteLength(outputBuffer, 'utf8'); + + if (outputSize > maxSize) { + const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); + const fileName = `output-${timestamp}.txt`; + const filePath = path.join(outputDir, fileName); + + fs.writeFileSync(filePath, outputBuffer, 'utf8'); + originalLog(`\nOutput exceeded ${maxSize} bytes (${outputSize} bytes). Saved to: ${filePath}`); + } else { + originalLog(outputBuffer); + } +} + +main().catch(e => { + console.error(e.message); + process.exit(1); +}); \ No newline at end of file From 58a53b7d4660ff79ef12bca0542b381c5826d4b5 Mon Sep 17 00:00:00 2001 From: cxx5208 Date: Sat, 4 Apr 2026 13:23:18 -0700 Subject: [PATCH 3/3] Add testing validation results for fileOnLargeOutput feature Closes #339 --- TEST_RESULTS.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 TEST_RESULTS.md diff --git a/TEST_RESULTS.md b/TEST_RESULTS.md new file mode 100644 index 0000000..8c76254 --- /dev/null +++ b/TEST_RESULTS.md @@ -0,0 +1,30 @@ +# Testing Validation Results for fileOnLargeOutput Feature + +## Test Summary +| Test Case | Configuration | Expected | Result | +|-----------|--------------|----------|--------| +| Default threshold | `outputMode: "fileOnLargeOutput"` (no maxStdOutputSize) | Output to stdout | ✓ Pass | +| Small threshold | `maxStdOutputSize: 100` | Output to file | ✓ Pass | +| Zero threshold | `maxStdOutputSize: 0` | Output to file | ✓ Pass | +| Large threshold | `maxStdOutputSize: 100000` | Output to stdout | ✓ Pass | +| stdout mode | `outputMode: "stdout"` | Output to stdout | ✓ Pass | +| file mode | `outputMode: "file"` | Output to stdout (existing behavior) | ✓ Pass | +| No config | No config file | Default behavior | ✓ Pass | +| snapshot command | `maxStdOutputSize: 100` | Output to file | ✓ Pass | +| --help flag | `outputMode: "fileOnLargeOutput"` | No wrapping | ✓ Pass | + +## Manual Tests Performed +1. **Small output (100 byte threshold)**: Output exceeded threshold, saved to file with message +2. **Default threshold (1MB)**: Small output printed to stdout normally +3. **Zero threshold**: All output saved to file +4. **Empty config (only outputMode set)**: Uses default 1MB threshold, works correctly + +## Edge Cases Tested +- Config value `0` for maxStdOutputSize → correctly treated as threshold +- Config without outputDir → defaults to temp directory +- Config without maxStdOutputSize → defaults to 1MB + +## Verification +- Feature implements issue requirements: https://github.com/microsoft/playwright-cli/issues/339 +- All existing modes (stdout, file) continue to work unchanged +- New fileOnLargeOutput mode correctly switches based on output size \ No newline at end of file