This document describes the automated code quality checks and standards enforced by this framework.
Quality guardrails are enforced at three levels:
- Pre-commit (Git Hooks) — Blocks commits with code quality issues
- Lint (ESLint) — Detects code smells, unused variables, and best practices
- Format (Prettier) — Enforces consistent code style
# Code Quality Checks
npm run lint # Run ESLint; report all issues
npm run lint:fix # Auto-fix ESLint issues where possible
npm run format # Auto-format all JS/JSON/MD with Prettier
npm run format:check # Check formatting without modifying
npm run test:ci # Run tests in CI mode (includes quality checks via hooks)What: Automatically runs linting and formatting on staged files before commits.
Install: npm install (auto-installs via prepare script)
How it works:
git add e2e-tests/home.spec.js
git commit -m "Add new home test"
# → Automatically runs:
# eslint --fix e2e-tests/home.spec.js
# prettier --write e2e-tests/home.spec.js
# → If issues remain, commit is blockedBypass (
git commit --no-verify # Skip hooks entirelyConfiguration: eslint.config.js (flat config format)
Rules enforced:
| Rule | Level | Purpose |
|---|---|---|
no-console |
warn | Logs should use error/warn; log/info should be removed before commit |
no-unused-vars |
error | Catch dead code and accidental assignments |
no-var |
error | Use const/let instead of var |
prefer-const |
error | Mark immutable variables as const |
prefer-arrow-callback |
warn | Use arrow functions in callbacks |
eqeqeq |
error | Use === instead of == |
no-empty-function |
warn | Flag functions with no implementation |
no-duplicate-imports |
error | Combine multiple imports from same source |
Playwright-specific: Globals like test, expect, describe, beforeEach, etc. are pre-defined.
Test files: Override no-unused-expressions to allow expect() assertions.
Configuration: .prettierrc.json
Global format rules:
- Semicolons: ✅ enabled
- Quotes:
"double"for consistency - Tab width: 2 spaces
- Trailing commas: ES5 compatible (
{a, b,}) - Line length: 100 characters max
- Arrow function parens: always (
(x) =>notx =>) - Line endings: LF (Unix)
Run formatting:
npm run format # Format all files
npm run format:check # Check without modifying
prettier --write file.js # Format single fileConfiguration: .lintstagedrc.json
What files are checked:
| Files | Tools |
|---|---|
*.js |
ESLint (with --fix), Prettier |
*.json |
Prettier |
*.md |
Prettier |
Example workflow (on commit):
# You run:
git commit -m "my change"
# Lint-staged automatically runs:
eslint --fix <staged .js files>
prettier --write <staged .js, .json, .md files>
# If no issues remain → ✅ commit succeeds
# If issues remain → ❌ commit blocked; fix and re-commitFor legitimate exceptions, use inline ESLint disable comments:
// Disable a single rule for one line
const unused = require("something"); // eslint-disable-line no-unused-vars
// Disable for a block
/* eslint-disable no-console */
console.log("Debug info");
/* eslint-enable no-console */
// Disable for entire file (top of file)
/* eslint-disable no-unused-vars */Tests should follow these naming patterns for clarity and traceability:
test.describe("Feature: [Feature Name]", () => {
test.describe("Positive Cases", () => {
// Happy path tests
});
test.describe("Negative Cases", () => {
// Edge case and error tests
});
});// Good: Clear action and expected outcome
test("should add product to cart when size and color are selected");
test("should show error message when cart is empty");
// Avoid: Vague or implementation-specific
test("test cart functionality");
test("check the button");When ready to expand, add test categorization:
test("@smoke @critical should load home page", async ({ page }) => {
// Test code
});
// Run tagged tests:
// npx playwright test --grep "@smoke"In CI pipelines, guardrails are enforced as quality gates:
# All three checks must pass before merge
npm run format:check # Fail if formatting is incorrect
npm run lint # Fail if code quality issues exist
npm run test:ci # Fail if tests don't passGitHub Actions Example:
- name: Check Formatting
run: npm run format:check
- name: Lint Code
run: npm run lint
- name: Run Tests
run: npm run test:ciWhy: devices is imported but not used in simple configs.
Fix options:
-
Use underscore prefix:
const _devices = require(...) -
Add inline disable:
const devices = require(...); // eslint-disable-line -
Remove if truly unused:
// Before const { devices } = require("@playwright/test"); // After (if not needed) // No import needed
Why: Reporter logs via console.log().
Fix: Change to allowed methods:
// Change from:
console.log("Test started");
// To:
console.error("Test error"); // or console.warn()Or, disable for reporter file:
/* eslint-disable no-console */
// reporter codeSolution: The hook actually auto-fixes issues then re-runs checks. If it still blocks:
- Check the error messages
- Fix manually where auto-fix couldn't help
git addthe fixed files againgit commitagain
git commit --no-verifynpx husky uninstall- Test.only() detection (prevent accidental test skipping)
- Coverage thresholds (require min code coverage %)
- Commit message linting (enforce semantic commits)
- Security scanning (detect vulnerable dependencies)
- Performance budgets (monitor test execution time)
For questions or issues with guardrails:
- Check this document
- Run
npm run lint:fixto auto-resolve issues - Review specific rule docs:
eslint.config.jscomments - Open an issue with details about the blocked commit