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?: { /** 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 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