Add variable validation features to README and CLI; implement linting and strict mode for environment variables in executor and linter. Enhance VSCode extension documentation for improved user guidance.

This commit is contained in:
sebseb7
2025-07-22 09:59:12 +02:00
parent 85537b26bf
commit 9e73900197
5 changed files with 66 additions and 5 deletions

View File

@@ -57,8 +57,24 @@ dump "login_page"
- Unknown HTML elements
- Generic element selectors
- Semantic misuse (e.g., `click` on input fields)
- **Undefined variables**: Variables that are not commonly defined environment variables
### Info
- Environment variable usage
- Command placement suggestions
- Best practice tips
- Best practice tips
## Variable Validation
The extension now provides enhanced validation for environment variables:
- **Common variables** like `$PASSWORD`, `$PASSWORDMAIL`, `$EMAIL`, `$USERNAME`, `$API_KEY`, `$TOKEN`, `$BASE_URL` show as info messages
- **Undefined variables** that are not commonly defined show as warnings
- Use the CLI with `--strict-variables` flag to treat undefined variables as errors during execution
## CLI Integration
The extension works with the PlayWrong CLI which supports:
- `--lint` - Run linter before execution
- `--strict` - Treat linter warnings as errors
- `--strict-variables` - Treat undefined variables as errors during execution

View File

@@ -33,6 +33,31 @@ Run in headless mode (default):
node src/cli.js tests/example.test Chrome --headless
```
## Variable Validation
PlayWrong now provides comprehensive validation for environment variables:
### Linting (Static Analysis)
```bash
node src/cli.js tests/example.test Chrome --lint
```
- **Common variables** like `$PASSWORD`, `$PASSWORDMAIL`, `$EMAIL`, `$USERNAME` show as info messages
- **Undefined variables** that are not commonly defined show as warnings
### Runtime Validation
During execution, undefined variables:
- Show prominent warnings with helpful instructions
- Are used as literal text (e.g., `$UNDEFINED_VAR` stays as `$UNDEFINED_VAR`)
- Can be treated as errors with `--strict-variables` flag
### Strict Mode
```bash
node src/cli.js tests/example.test Chrome --strict-variables
```
- Treats undefined variables as errors
- Stops execution immediately when an undefined variable is encountered
- Useful for CI/CD pipelines to ensure all variables are properly set
## Test Language Syntax
### Profiles

View File

@@ -134,12 +134,14 @@ async function main() {
console.log(' --full-page Take full page screenshots instead of viewport only');
console.log(' --lint Run linter before execution');
console.log(' --strict Treat linter warnings as errors');
console.log(' --strict-variables Treat undefined variables as errors');
console.log('Examples:');
console.log(' node src/cli.js tests/example.test Chrome');
console.log(' node src/cli.js tests/example.test Chrome --headed');
console.log(' node src/cli.js tests/example.test Chrome --headed --enable-animations');
console.log(' node src/cli.js tests/example.test Chrome --headed --full-page');
console.log(' node src/cli.js tests/example.test Chrome --lint --strict');
console.log(' node src/cli.js tests/example.test Chrome --strict-variables');
process.exit(1);
}
@@ -150,13 +152,14 @@ async function main() {
const fullPageScreenshots = args.includes('--full-page');
const lint = args.includes('--lint');
const strict = args.includes('--strict');
const strictVariables = args.includes('--strict-variables');
if (!await fs.pathExists(testFile)) {
console.error(`Test file not found: ${testFile}`);
process.exit(1);
}
const runner = new TestRunner({ headless, disableAnimations, fullPageScreenshots, lint, strict });
const runner = new TestRunner({ headless, disableAnimations, fullPageScreenshots, lint, strict, strictVariables });
currentRunner = runner; // Store reference for cleanup
try {

View File

@@ -15,6 +15,7 @@ class TestExecutor {
this.disableAnimations = options.disableAnimations !== false; // Default to disable animations
this.fullPageScreenshots = options.fullPageScreenshots || false; // Default to viewport screenshots
this.enableScreenshots = options.enableScreenshots !== false; // Default to enable screenshots
this.strictVariables = options.strictVariables || false; // Default to allow undefined variables
this.variables = {}; // Store extracted variables
this.shouldStop = false; // Flag to stop execution on shutdown
@@ -2029,7 +2030,18 @@ class TestExecutor {
// Then check environment variables
const envValue = process.env[varName];
if (envValue === undefined) {
console.warn(`Warning: Variable ${varName} is not defined in stored variables or environment`);
const warningMessage = `⚠️ WARNING: Variable ${varName} is not defined in stored variables or environment`;
console.warn(warningMessage);
// Log additional helpful information
console.warn(` Variable '${varName}' will be used as literal text: '${match}'`);
console.warn(` To fix this, set the environment variable or use the 'extract' command to store the variable`);
// In strict mode, throw an error for undefined variables
if (this.strictVariables) {
throw new Error(`Undefined variable: ${varName}. In strict variables mode, all variables must be defined.`);
}
return match; // Return original if not found
}
return envValue;

View File

@@ -383,9 +383,14 @@ class TestLinter {
this.addWarning(`Variable '${variable}' should use UPPER_CASE naming convention`, line.lineNumber);
}
// Info about common variables
if (['$PASSWORD', '$PASSWORDMAIL', '$EMAIL', '$USERNAME'].includes(variable)) {
// Check if variable is commonly defined
const commonVariables = ['$PASSWORD', '$PASSWORDMAIL', '$EMAIL', '$USERNAME', '$API_KEY', '$TOKEN', '$BASE_URL'];
if (commonVariables.includes(variable)) {
this.addInfo(`Using environment variable '${variable}' - ensure it's defined in your environment`, line.lineNumber);
} else {
// Warn about potentially undefined variables
this.addWarning(`Variable '${variable}' may not be defined. Ensure it's set as an environment variable or stored variable`, line.lineNumber);
}
}
}