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:
18
.vscode/extensions/playwrong-syntax/README.md
vendored
18
.vscode/extensions/playwrong-syntax/README.md
vendored
@@ -57,8 +57,24 @@ dump "login_page"
|
|||||||
- Unknown HTML elements
|
- Unknown HTML elements
|
||||||
- Generic element selectors
|
- Generic element selectors
|
||||||
- Semantic misuse (e.g., `click` on input fields)
|
- Semantic misuse (e.g., `click` on input fields)
|
||||||
|
- **Undefined variables**: Variables that are not commonly defined environment variables
|
||||||
|
|
||||||
### Info
|
### Info
|
||||||
- Environment variable usage
|
- Environment variable usage
|
||||||
- Command placement suggestions
|
- 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
|
||||||
25
README.md
25
README.md
@@ -33,6 +33,31 @@ Run in headless mode (default):
|
|||||||
node src/cli.js tests/example.test Chrome --headless
|
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
|
## Test Language Syntax
|
||||||
|
|
||||||
### Profiles
|
### Profiles
|
||||||
|
|||||||
@@ -134,12 +134,14 @@ async function main() {
|
|||||||
console.log(' --full-page Take full page screenshots instead of viewport only');
|
console.log(' --full-page Take full page screenshots instead of viewport only');
|
||||||
console.log(' --lint Run linter before execution');
|
console.log(' --lint Run linter before execution');
|
||||||
console.log(' --strict Treat linter warnings as errors');
|
console.log(' --strict Treat linter warnings as errors');
|
||||||
|
console.log(' --strict-variables Treat undefined variables as errors');
|
||||||
console.log('Examples:');
|
console.log('Examples:');
|
||||||
console.log(' node src/cli.js tests/example.test Chrome');
|
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');
|
||||||
console.log(' node src/cli.js tests/example.test Chrome --headed --enable-animations');
|
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 --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 --lint --strict');
|
||||||
|
console.log(' node src/cli.js tests/example.test Chrome --strict-variables');
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,13 +152,14 @@ async function main() {
|
|||||||
const fullPageScreenshots = args.includes('--full-page');
|
const fullPageScreenshots = args.includes('--full-page');
|
||||||
const lint = args.includes('--lint');
|
const lint = args.includes('--lint');
|
||||||
const strict = args.includes('--strict');
|
const strict = args.includes('--strict');
|
||||||
|
const strictVariables = args.includes('--strict-variables');
|
||||||
|
|
||||||
if (!await fs.pathExists(testFile)) {
|
if (!await fs.pathExists(testFile)) {
|
||||||
console.error(`Test file not found: ${testFile}`);
|
console.error(`Test file not found: ${testFile}`);
|
||||||
process.exit(1);
|
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
|
currentRunner = runner; // Store reference for cleanup
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class TestExecutor {
|
|||||||
this.disableAnimations = options.disableAnimations !== false; // Default to disable animations
|
this.disableAnimations = options.disableAnimations !== false; // Default to disable animations
|
||||||
this.fullPageScreenshots = options.fullPageScreenshots || false; // Default to viewport screenshots
|
this.fullPageScreenshots = options.fullPageScreenshots || false; // Default to viewport screenshots
|
||||||
this.enableScreenshots = options.enableScreenshots !== false; // Default to enable 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.variables = {}; // Store extracted variables
|
||||||
this.shouldStop = false; // Flag to stop execution on shutdown
|
this.shouldStop = false; // Flag to stop execution on shutdown
|
||||||
|
|
||||||
@@ -2029,7 +2030,18 @@ class TestExecutor {
|
|||||||
// Then check environment variables
|
// Then check environment variables
|
||||||
const envValue = process.env[varName];
|
const envValue = process.env[varName];
|
||||||
if (envValue === undefined) {
|
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 match; // Return original if not found
|
||||||
}
|
}
|
||||||
return envValue;
|
return envValue;
|
||||||
|
|||||||
@@ -383,9 +383,14 @@ class TestLinter {
|
|||||||
this.addWarning(`Variable '${variable}' should use UPPER_CASE naming convention`, line.lineNumber);
|
this.addWarning(`Variable '${variable}' should use UPPER_CASE naming convention`, line.lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Info about common variables
|
// Check if variable is commonly defined
|
||||||
if (['$PASSWORD', '$PASSWORDMAIL', '$EMAIL', '$USERNAME'].includes(variable)) {
|
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);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user