
Gt Refactor Tests
- 1 installs
- Updated May 11, 2026
- dimasmaha/playwright-agentic-qa-automation-workflows
Audits and refactors Playwright test suites plan-first, categorizing issues as MUST/CAN/SKIP fix and applying approved changes in groups.
About
Runs a structured plan-first workflow to audit Playwright tests against best practices, produce an actionable diff plan, then apply fixes group by group on approval. A developer uses it to remove anti-patterns and enforce conventions in a Playwright suite.
- Plan-first audit of Playwright tests, categorizing issues MUST/CAN/SKIP
- Fixes anti-patterns like hard waits, missing awaits and brittle selectors
Gt Refactor Tests by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,750 of 2,153 Testing & QA skills by installs in the Skillselion catalog
- Data as of Jul 8, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dimasmaha/playwright-agentic-qa-automation-workflows --skill gt-refactor-testsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| Last updated | May 11, 2026 |
| Repository | dimasmaha/playwright-agentic-qa-automation-workflows ↗ |
What it does
Audits and refactors Playwright test suites plan-first, categorizing issues as MUST/CAN/SKIP fix and applying approved changes in groups.
Files
Playwright Test Improver Skill
A structured, plan-first workflow for auditing and improving Playwright test suites.
Agents using this skill must also use the playwright-best-practices skill as a required reference during analysis and validation.
---
Guiding Philosophy
Always plan before acting. This skill operates in two distinct phases:
1. PLAN MODE (default) — Analyze, categorize issues, produce an actionable plan with exact diffs. No files are changed. 2. EXECUTE MODE — Apply approved changes from the plan, one logical group at a time.
Never mix phases. Never modify files during PLAN MODE. Never skip the plan.
---
Self-awareness
If called from `gt-us-to-spec` orchestrator or `ft-orchestrator` (pipeline mode): skip PLAN MODE entirely. Determine autonomously what to fix:
- Apply all MUST FIX items without asking.
- Apply CAN FIX items that are clear-cut (naming, fixture consolidation, locator hygiene with existing page object coverage) — skip CAN FIX items that require app-side changes or are subjective.
- Never apply SKIP items.
- Emit a short summary of what was fixed and what was skipped, then continue the pipeline. Do not wait for approval at any step.
If called after `gt-spec-writer` (standalone): audit only the newly written spec file. Do not scan the full tests/ directory unless the user asks.
If called independently: ask which files to audit, or default to all of tests/ if no answer is given.
Source of truth for page objects: always check tests/pages/ first. If a locator can be expressed through an existing page object method, flag inline locators as a CAN FIX issue even if they technically work.
---
Phase 1: PLAN MODE
Step 1 — Discover the project
Read these locations (if they exist) before touching any test file:
tests/
├── pages/ ← page objects (source of truth for locators)
├── fixtures/ ← shared fixtures
├── *.spec.ts ← spec files
playwright.config.ts
package.jsonAlso read:
package.json— installed versions of@playwright/test, testing libs- The
playwright-best-practicesskill and apply its guidance as mandatory baseline rules .eslintrc/eslint.config.*— linting rules that apply to tests- Any existing
CONVENTIONS.mdorREADMEinside the playwright folder
Use bash_tool to list and read files. Prefer reading full files over snippets so patterns are visible.
Step 2 — Analyze
Scan every file in playwright/tests/ and playwright/app/. For each file, check against the reference list in references/best-practices.md.
Build an internal issue list with this structure per issue:
FILE: <relative path>
LINE: <line number or range>
ISSUE TYPE: <category>
SEVERITY: MUST | CAN | SKIP
DESCRIPTION: <what is wrong>
FIX: <exact change — before → after, or migration instruction>Step 3 — Categorize findings into three buckets
🔴 MUST FIX
Issues that cause flakiness, false positives, maintainability collapse, or violate core Playwright contracts. Examples:
page.waitForTimeout()(arbitrary waits)page.pause()left in- Hard-coded absolute URLs that bypass base URL config
- Missing
awaiton async Playwright calls expectassertions outside test blocks- Selectors using implementation-specific internals (e.g.,
.class-123abc) - Tests with no assertions
test.onlyortest.skipcommitted without a comment- Fixtures defined inline instead of in the shared fixture file
- Direct
page.goto()to full URLs instead of using relative paths +baseURL
🟡 CAN FIX
Issues worth fixing for clarity, reuse, and convention alignment, but not blocking. Examples:
- Missing Page Object encapsulation for repeated selectors
- Test descriptions that don't describe behavior (
test('works')) - Large test files that can be split by feature
- Repeated setup logic that should be a fixture or
beforeEach - Missing
data-testidattributes on key elements (note: requires app changes) - Inconsistent naming conventions (
camelCasevskebab-casefor files) - Missing tags (
@smoke,@regression) if the project uses them
⚪ SKIP
Changes that are subjective, high-risk without clear gain, or out of scope. Examples:
- Stylistic reformatting with no behavioral impact
- Changes requiring large app-side refactors
- Speculative improvements not grounded in actual test failures
- Tests that are unusual but intentional (e.g., custom retry logic for known flaky external deps)
Step 4 — Output the Plan
Print the plan in this exact format so it's easy to approve section-by-section:
---
````
🔍 PLAYWRIGHT TEST AUDIT PLAN
Summary
- Files scanned: N
- Total issues found: N
- 🔴 MUST FIX: N | 🟡 CAN FIX: N | ⚪ SKIP: N
---
🔴 MUST FIX (N issues)
[M1] <Short title>
File: playwright/tests/auth.spec.ts · Line: 42 Problem: page.waitForTimeout(2000) introduces a 2-second hard wait that causes flakiness. Fix: \```diff
- await page.waitForTimeout(2000);
+ await expect(page.locator('[data-testid="dashboard"]')).toBeVisible(); \```
[M2] ...
---
🟡 CAN FIX (N issues)
[C1] <Short title>
File: playwright/tests/checkout.spec.ts · Lines: 10–35 Problem: Selector div.sc-1x9abc > span is brittle — uses auto-generated CSS class. Fix: Add data-testid="checkout-total" to the component, then: \```diff
- page.locator('div.sc-1x9abc > span')
+ page.getByTestId('checkout-total') \```
⚠️ Requires app-side change in src/components/Checkout.tsx[C2] ...
---
⚪ SKIP (N issues — listed for transparency)
playwright/tests/legacy.spec.ts— entire file is deprecated, removal tracked in #123playwright/tests/payments.spec.ts:88— unusual retry loop is intentional per team decision
---
Execution Groups (for approval)
When you approve execution, I'll apply changes in these groups: 1. Group A — Hard waits (M1, M4, M7) 2. Group B — Missing awaits (M2, M3) 3. Group C — Selector hygiene (M5, M6, C1, C3) 4. Group D — Fixture consolidation (C2, C4)
Say "Execute Group A" (or "Execute all MUST FIX") to proceed. ````
---
Phase 2: EXECUTE MODE
Only enter this phase after the user explicitly approves (fully or partially).
Execution rules
1. Apply changes one group at a time unless told otherwise. 2. For each change:
- Show the exact diff before writing
- Apply using
str_replace(preferred) or rewrite the file - Confirm the change was written successfully
3. After each group, summarize what was done and ask if the user wants to continue to the next group. 4. Never apply SKIP items unless the user explicitly unlocks them. 5. If a CAN FIX item requires an app-side change (e.g., adding data-testid), note it as a manual task and skip the test-side change until confirmed.
---
Validation Mode
Use this after new tests are written or after Execute Mode completes.
Trigger phrases: "validate the tests", "check conventions", "review new tests against best practices"
Validation workflow
1. Read the files the user specifies (or the full playwright/tests/ and playwright/app/ if unspecified). 2. Re-run the analysis from Phase 1, but scope it to checking for regressions and convention alignment. 3. Output a Validation Report:
## ✅ VALIDATION REPORT
### Files checked: N
### New issues found: N | Previously fixed issues: N | Clean files: N
#### New issues (if any)
[Same format as MUST/CAN/SKIP above]
#### Convention alignment
- Naming: ✅ / ⚠️ <details>
- Fixture usage: ✅ / ⚠️ <details>
- Selector strategy: ✅ / ⚠️ <details>
- Assertion quality: ✅ / ⚠️ <details>
- Page object coverage: ✅ / ⚠️ <details>---
Iterative Improvement Loop
This skill is designed to be used repeatedly as tests evolve:
Write tests → Validate → Plan improvements → Approve → Execute → Validate againAfter each execution round, encourage the user to:
- Run the test suite and observe flakiness
- Re-trigger validation after any manual app-side changes
- Update the
playwright-best-practicesreference if new conventions emerge from the review
---
Reference
Read references/best-practices.md for the full checklist used during analysis.
Use the playwright-best-practices skill for every run of this skill and merge its rules with the built-in checklist — project-specific conventions always take precedence over generic ones.
Playwright Best Practices Reference
This is the canonical checklist used during audit analysis. Issues are grouped by category. Each item includes its default severity and a brief rationale.
---
1. Selector Strategy
| Severity | Rule |
|---|---|
| MUST | Use getByRole(), getByTestId(), getByLabel(), getByText() over CSS/XPath selectors |
| MUST | Never use auto-generated class names (e.g., .sc-1a2b3c, .css-xyz) |
| MUST | Never use positional selectors like nth-child() for non-list elements |
| CAN | Prefer data-testid attributes added to the app for stable anchoring |
| CAN | Use getByRole() with accessible names for form controls and buttons |
| SKIP | Migrating selectors that work fine and aren't fragile in practice |
2. Waiting & Timing
| Severity | Rule |
|---|---|
| MUST | Never use page.waitForTimeout() — replace with auto-waiting assertions |
| MUST | Never use page.pause() in committed tests |
| MUST | Don't poll with setTimeout in test logic — use Playwright's built-in retry |
| MUST | Don't use sleep() equivalents imported from utilities |
| CAN | Use page.waitForLoadState('networkidle') only when no better assertion exists |
| CAN | Prefer expect(locator).toBeVisible() over waitForSelector |
3. Assertions
| Severity | Rule |
|---|---|
| MUST | Every test must have at least one expect() assertion |
| MUST | Use web-first assertions (expect(locator).toBeVisible() not expect(await locator.isVisible()).toBe(true)) |
| MUST | Don't assert on implementation details (exact class names, internal state) |
| MUST | Avoid expect(x).toBeTruthy() — assert the specific value |
| CAN | Add { timeout } overrides only when justified with a comment |
| CAN | Use expect.soft() for non-blocking assertions in report-style tests |
4. Test Structure
| Severity | Rule |
|---|---|
| MUST | No test.only committed to main branch without a // TODO: comment |
| MUST | No test.skip without a reason comment or linked issue |
| MUST | Tests must be independent — no shared mutable state between tests |
| MUST | Don't use beforeAll to set up state that individual tests mutate |
| CAN | Group related tests with test.describe() blocks |
| CAN | Use test.describe.configure({ mode: 'parallel' }) for independent suites |
| CAN | Name tests as behaviors: 'should show error when email is invalid' |
| SKIP | Renaming tests that are clear but don't follow the exact naming convention |
5. Fixtures & Page Objects
| Severity | Rule |
|---|---|
| MUST | Don't define fixtures inline in spec files — put them in playwright/app/fixtures.ts |
| MUST | Don't repeat login/setup logic across tests — use a fixture |
| CAN | Wrap repeated selectors + actions in a Page Object class |
| CAN | Page Objects should NOT contain assertions — keep those in tests |
| CAN | Use fixture composition (test.extend) rather than inheritance |
| SKIP | Creating Page Objects for one-off interactions used in a single test |
6. Navigation & Base URL
| Severity | Rule |
|---|---|
| MUST | Use relative paths with baseURL from config — never hard-code http://localhost:3000 |
| MUST | Don't mix page.goto('/path') with absolute URLs in the same suite |
| CAN | Extract common routes to a routes.ts constant file |
7. Configuration
| Severity | Rule |
|---|---|
| MUST | playwright.config.ts must set baseURL, testDir, and use.trace |
| MUST | Retries should be configured per environment (CI: 2, local: 0) |
| CAN | Use projects for multi-browser or multi-role test configurations |
| CAN | Set screenshot: 'only-on-failure' and video: 'retain-on-failure' for CI |
| SKIP | Overhauling config unless specifically requested |
8. File & Naming Conventions
| Severity | Rule |
|---|---|
| MUST | Test files must end in .spec.ts |
| CAN | Use kebab-case for test filenames (e.g., user-auth.spec.ts) |
| CAN | Page Object files should use PascalCase.ts (e.g., LoginPage.ts) |
| CAN | Group tests by feature or domain in subdirectories |
| SKIP | Renaming files that are well-organized but use a different naming style |
9. Data & State Management
| Severity | Rule |
|---|---|
| MUST | Tests must not depend on execution order or shared database state |
| MUST | Clean up created test data — use test.afterEach or fixture teardown |
| CAN | Use API calls (via request fixture) to set up state rather than UI |
| CAN | Use storageState to persist authenticated sessions across tests |
| SKIP | Full test data factory setup if the project doesn't already have one |
10. Performance & Parallelism
| Severity | Rule |
|---|---|
| CAN | Tests that are slow (>30s) should be investigated for unnecessary waits |
| CAN | Use test.describe.configure({ mode: 'parallel' }) where safe |
| SKIP | Parallelism changes if the test suite isn't stable yet |
---
Project-Convention Override
If the project has a CONVENTIONS.md, README.md in the playwright folder, or a linked playwright-best-practices skill, those rules take precedence over the defaults above. Note any overrides at the top of the audit plan output.