Review a pull request for Playwright test automation using project standards. Use when user asks to review a PR, check a pull request, or mentions a PR number.
Installation
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Review a pull request for Playwright test automation using project standards. Use when user asks to review a PR, check a pull request, or mentions a PR number.
allowed-tools
Bash(gh:*), Bash(git:*), Read, Grep, Glob
Pull Request Review
Process
1. Gather PR Information
# Get PR metadata
gh pr view <number> --json title,body,state,additions,deletions,changedFiles,baseRefName,headRefName
# Get full diff
gh pr diff <number>
2. Read modified files for context
Use Read tool to view complete files mentioned in the diff.
3. Review Checklist (Production Focus)
Critical Issues (Block Merge)
Build/compilation errors or type issues
Test failures or broken fixtures
Logic errors in test scenarios
Data integrity issues (duplicate users, race conditions)
Test Design & Business Logic
Test covers actual user scenarios - not just happy paths
Business logic is correct - verifies the right behavior
Test scope is appropriate - not too broad or too narrow
Edge cases considered - what could go wrong?
Assertions validate meaningful outcomes - not just presence of elements
Test Stability & Reliability
User-Facing Locators - prefer getByRole/getByText over CSS/XPath
Selectors are resilient - won't break on UI changes (use role, text, semantic HTML where possible)
No race conditions - proper waits for async operations
No hard-coded waits - page.waitForTimeout() is a red flag
Parallel execution safe - no shared state or dependencies
Data isolation - each test has unique data, no conflicts
File without proper suffix (e.g., Checkout.ts instead of checkout.page.ts)
Page object in wrong folder (e.g., cart page in product/ folder)
Component that should be in components/ but is nested in a page folder
Test file not following .spec.ts convention
Mixed concerns in one folder (pages + utils + types together)
Missing explicit return types on exported functions (non-exported local/private arrow functions may omit return types when the type is obvious from context)
Naming Conventions:
Variables/methods follow conventions - camelCase, descriptive, no abbreviations
File names are consistent - kebab-case, clear purpose
Declarative Naming - follow should [outcome] when [scenario] pattern
Constants are UPPER_CASE - configuration values, magic numbers extracted
Page Object method names match their return type and intent:
No unnecessary complexity - KISS principle, straightforward solutions
No over-generic methods - specific is better than flexible
No unused code - dead code removed, imports cleaned up
Method Optimization:
Methods do one thing - single responsibility
No duplicate logic - DRY principle applied where it makes sense
Explicit return types on exported functions - all exported/public functions must have explicit return types (e.g., Promise<void>, string, number). Non-exported local arrow functions may omit return types when obvious from context.
Strict Type Safety - NO 'any' type, use generics/unknown
Async/await used correctly - no unnecessary awaits, proper error handling
Code Style:
No redundant assignments - don't assign parameter to new variable of same type (e.g., const userData = user when user is already typed)
No unnecessary intermediate variables - use parameters directly when no transformation needed
Consistent access modifiers - follow base class patterns (e.g., protected for uniqueElement if BasePage uses protected)
No shadowing - avoid variable names that shadow outer scope variables
No duplicated assertion blocks - extract repeated assertions into private helper methods (e.g., same assertions for delivery/invoice address → assertAddressBlock(locator, data))
Use template literals - prefer `${a} ${b}` over a + ' ' + b for string concatenation
Types & Constants Organization:
This is a tricky area with multiple valid approaches. Flag for discussion when patterns are inconsistent.
Where types should live:
Shared types in src/ui/types/ - types used across multiple pages (e.g., CartItem used in cart.page.ts AND checkout.page.ts → extract to types/cart.types.ts)
No duplicate type definitions - same type defined in multiple files is a red flag; search for duplicates
Page-specific types can stay in page files - if a type is ONLY used in one page, it can stay there
Derived types stay with constants - when type uses typeof CONSTANT (e.g., type CreditCard = typeof CREDIT_CARDS[keyof typeof CREDIT_CARDS]), keep them together in constants file - this is OK
Utility Types used - Pick, Omit, Partial for leaner types
Interface Segregation - functions take only needed data (e.g. id not User obj)
No Enums - prefer as const string unions
Constants organization:
Module Boundaries - no circular refs or reaching into private folders
Constants in test-data/constants/ - test data like credit cards, URLs, timeouts
Constants file = one domain - credit-card.ts for cards, urls.ts for URLs, don't mix domains
UPPER_CASE for constants - CREDIT_CARDS not creditCards
as const for literal types - enables type inference from values
Recommended structure:
src/ui/
├── types/ # Shared types
│ ├── cart.types.ts # CartItem, OrderItem
│ ├── user.types.ts # Person, Address
│ └── index.ts # Re-exports
├── test-data/
│ └── constants/ # Test data with derived types
│ ├── credit-card.ts # CREDIT_CARDS + CreditCard type (OK together)
│ └── timeouts.ts # TIMEOUTS
└── pages/
└── cart/
└── cart.page.ts # Imports from types/, no local CartItem
Red flags to catch:
Same interface/type defined in 2+ files → extract to shared types
Type in page file that's imported by another page → move to types/
Constants scattered across page files → consolidate to constants/
Mixing unrelated constants in one file → split by domain
Config Organization:
Environment configs are clean - no hardcoded URLs/credentials in code
Config structure makes sense - easy to find and modify settings
Secrets are not committed - .env files in .gitignore
Config is typed - TypeScript interfaces for config objects
Utils & Helpers:
Utils are truly reusable - used in multiple places, not premature
Utils have clear purpose - not a dumping ground
Utils are well-documented - JSDoc or clear naming
Utils are testable - pure functions when possible
Reporting & Debugging:
@step() usage is meaningful - steps tell a story in reports
Error messages are actionable - include context, expected vs actual
Console logs are removed - no debug statements left behind
Screenshots/videos will be useful - failures capture enough context
Page Object Quality
Single Responsibility (SRP) - elements & interactions only, NO assertions
Encapsulation - private/protected locators, public action methods
Action-Oriented Methods - submitForm not clickSubmit
Dependency Inversion - injected via Fixtures (no new Page(page))
Component Composition - use shared components (e.g. Header)
Abstractions make sense - methods represent user actions
Not over-engineered - simple, clear, maintainable
Proper error handling - failures are debuggable with clear messages
CI/CD & Pipeline Considerations
Timeouts are reasonable - won't fail in slow CI environments
Resource efficient - not creating unnecessary browser contexts
Environment agnostic - works in CI without local dependencies
Retry-friendly - tests work with Playwright's retry mechanism
Parallelization ready - consider worker count and resource limits
Test Maintainability (6-month test)
Easy to update - when requirements change, is this easy to modify?
Config changes - verify no unintended side effects
New dependencies introduced - npm packages reviewed
Git Hygiene
Commit messages are clear - explain WHY, not just WHAT
PR title is descriptive - explains the feature/fix clearly
Commits are logical - each commit is a coherent unit of work
No "WIP", "test", "fix" commit messages - be professional
4. Output Format
Review Style - Senior AQA Mindset:
Direct, concise, production-focused
CRITICAL: Re-read ALL changed files before posting - don't review stale code
Only show sections with issues - skip sections that are fine
At the end, list areas that are good in one line: "✅ Good: [area1], [area2], [area3]"
For commits with issues, provide specific rewrite suggestions
Think long-term: "Will this be maintainable in 6 months?"
Challenge decisions: "Why this approach? Is it necessary?"
Consider CI/CD: "Will this work reliably in pipeline?"
Assess risk: "What could this break? What's not covered?"
DO NOT include "Test Coverage Analysis" section - this will be handled by a separate agent
Patterns to IGNORE (not issues):
Duplicate fixture definitions across different fixture files (e.g., pages in both fixtures/index.ts and api-fixtures/api-user.fixture.ts) — these may coexist intentionally for A/B performance comparison between fixture strategies. Do not flag as duplication or suggest mergeTests unless the duplicates have diverged in behavior.
Patterns to flag for extra review (not issues, just note them):