agentleFS
sayurionishisayurionishi/playwright-scaffold/CLAUDE.md

playwright-scaffold

CLAUDE.md1 starsChanged 3 months agoMITView on GitHub

This file is always loaded. It is the constitution (hard rules), the workflow, and the index of skills. The deep rules live in .claude/skills/<name>/SKILL.md; this file routes you there. When this file and a skill disagree, the skill wins — and that's a bug to fix here. You are working in an AI-native Playwright + TypeScript scaffold that distills hard-won lessons from real-world Playwright suites. It tests UI (functional + e2e) and API, with security coverage, using the Page Object…

  • Reads credentials

The file

We split this CLAUDE.md into the rules it gives an agent

7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    If PROJECT.md does NOT exist in the repo root, this is a fresh clone.

    line 15
  2. Very specific:

    If PROJECT.md exists, read it — it records the target's profile, auth model, locator strategy, and API-contract source.

    line 20
  3. Very specific:

    If the recorded profile is salesforce, also load the salesforce skill before doing anything else Salesforce-specific — the pack (§7) …

    line 23
  4. Distinctive:

    Never ship, and refuse to generate, any of the following:

    line 30
  5. Distinctive:

    Every non-trivial task runs the same loop:

    line 61
  6. Very specific:

    If nothing matches, default to common-tasks or ASK.

    line 132
  7. Very specific:

    If the profile is NOT salesforce, bootstrap prunes all of the above.

    line 203

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md — Test Automation Scaffold Constitution

This file is always loaded. It is the constitution (hard rules), the workflow, and the index of skills. The deep rules live in .claude/skills/<name>/SKILL.md; this file routes you there. When this file and a skill disagree, the skill wins — and that's a bug to fix here.

You are working in an AI-native Playwright + TypeScript scaffold that distills hard-won lessons from real-world Playwright suites. It tests UI (functional + e2e) and API, with security coverage, using the Page Object Model, fixture-based DI, deterministic waits, and runtime-validated schemas.


0. First contact — is this scaffold even configured?

If PROJECT.md does NOT exist in the repo root, this is a fresh clone. Run the bootstrap skill first — it interviews the user about the target app, applies a profile (generic / controlled / salesforce / api-only), prunes what isn't needed, and writes PROJECT.md. Do not generate tests against an unconfigured scaffold.

If PROJECT.md exists, read it — it records the target's profile, auth model, locator strategy, and API-contract source. Those decisions override the generic defaults below.

If the recorded profile is salesforce, also load the salesforce skill before doing anything else Salesforce-specific — the pack (§7) replaces several generic defaults outright.


1. The Constitution (hard stops — these are REFUSALS, not warnings)

Never ship, and refuse to generate, any of the following:

#ForbiddenInstead
1page.waitForTimeout(...)Web-first assertion or a pre-registered response wait (wait-strategy)
2page.waitForLoadState('networkidle') on an SPAThe specific gating response (helpers/util/network.ts). Acceptable ONLY on static/SSR pages that truly go quiet — never on a chatty SPA. On the salesforce profile this is a hard REFUSAL, not a discouragement (Aura never goes quiet). See wait-strategy.
3XPath, CSS-class, nth-child, or auto-generated-id selectorsSemantic / testId per the active profile (selectors)
4A guessed selector, URL, enum value, endpoint, or UI stringExplore first (playwright-cli / OpenAPI) or ASK. Never invent.
5any typeA real type or unknown + narrowing (type-safety)
6z.object(...) for an API schemaz.strictObject(...) (catches contract drift)
7Skipping expect(Schema.parse(body)) / { schema } on an API responseValidate every response body
8Assertions inside a page objectPage objects act; specs assert
9Raw locators in a specLocators live in page objects only
10new SomePage(page) inside a testConsume via the fixture (async ({ somePage }) => …)
11Hardcoded URL / credentialprocess.env.* via config/; paths & messages via enums/
12.json static data.ts with as const
13Silencing a failure (try/catch on expect, raised timeout, silent .skip)Fix the root cause; test.skip requires // FIXME: <ticket>
14More than one tag per testExactly one (@smoke/@sanity/@regression/@api/@e2e/@security/@contract/@persona); @destructive wins
15A Salesforce object or field API name written from memoryRead it from describe / ui-api/object-info (salesforce-metadata-contract)

A hook (ESLint) enforces #1, #2, #5. The rest are on you.

Rule #15 is the Salesforce-specific sharpening of #4, and it earns its own row because Salesforce field API names are org state, not application source. An admin can add, rename, or delete a field with no deploy and no commit, so there is no repository to read them from — describe is the only source of truth. Margin__c existing in someone else's org proves nothing about yours.


2. The conversation contract — audit-then-edit

Every non-trivial task runs the same loop:

  1. State — the user states the goal in plain language.
  2. Route + explore — load the matching skill (§4); gather evidence (playwright-cli / OpenAPI / ls). Missing a primary input → ASK, do not guess.
  3. Propose — emit a scope block: what changes, in which files, why, trade-offs, and a confidence 1–10. Confidence < 5 means exploration is incomplete → do NOT propose; go back and ASK.
  4. Approve — wait for the user. No code before approval (except trivial Direct-Mode fixes).
  5. Apply — make the edits per the leaf skill; re-check every Constitution rule.
  6. Verify — lint + run the affected tests (never the whole suite). Red → debugging.
  7. Report + commit — list files changed; ask before committing.

Direct Mode: one-line fixes / typos may skip the proposal — but still verify the premise is real first. The user can opt into Direct Mode for a session by saying "just do it."


3. The architecture in one screen

config/        URLs + runtime settings (process.env). NEVER paths/messages.
enums/         endpoint PATHS, UI ROUTES, UI MESSAGES (as const). Verified, never guessed.
env/           .env.<environment> files (gitignored; *.example tracked).
helpers/       util/network.ts (deterministic waits), util/forms.ts, auth/auth.setup.ts
pages/         base.page.ts + *.page.ts + components/  (locators-on-top, actions only)
test-data/     factories/ (Faker, dynamic happy-path) + static/ (as const, invalid/boundary)
fixtures/      api/ (ApiRequest + Zod schemas) + pom/ + helper/ + test-options.ts (single import)
tests/         api/ (backend = SUT)  functional/ (one screen)  e2e/ (full journey)

Projects, not just folders (playwright.config.ts): api (no browser), setup (auth state), functional, e2e. The SEAM is what is the system under test — not which tool makes the call. API-as-setup is a fixture inside UI tests; API-as-SUT is the api project.

Every spec imports from one place: import { test, expect } from '<...>/fixtures/test-options';


4. Routing — describe the work, the skill loads itself

You want to…First skillChains to
Configure a fresh clone for an appbootstrapselectors, config, api-testing
Add a page object / new screenpage-objectsselectors, fixtures, enums
Pick or fix a locatorselectorspage-objects
Add a UI functional testtest-standardspage-objects, data-strategy
Add an end-to-end journeytest-standardspage-objects, data-strategy
Make a test pass/wait reliably; fix a flakewait-strategydebugging, selectors
Add API tests for an endpointapi-testingtype-safety, data-strategy, enums, security-testing
Add security / input-fuzzing testssecurity-testingapi-testing, data-strategy
Write/refactor a Zod schema or kill an anytype-safetyapi-testing
Create a factory / curated invalid datadata-strategytype-safety
Wire a fixture (page object / helper)fixturesapi-testing
Add an endpoint / route / messageenumsselectors (verify live text)
Add an env var / URL / credentialconfigenums, type-safety
Debug a failing / flaky testdebuggingwait-strategy, selectors, fixtures
"How do I…" / "generate a prompt for…"common-tasksthe matching skill
Understand the whole way of workingai-native-workflow—

Salesforce (only when PROJECT.md profile is salesforce)

These override the generic skills above for anything Salesforce-specific. salesforce is the hub — load it first if you're unsure which of the six applies.

You want to…SkillChains to
Understand what to test (and NOT test) in an orgsalesforceall of the below
Authenticate to an org / get past MFA / SSOsalesforce-authconfig, salesforce-personas
Locate a Lightning element; fix a strict-mode clashsalesforce-locatorsselectors, page-objects
Make a Lightning test wait reliablysalesforce-waitswait-strategy, debugging
Test who can see/do what (profiles, permsets, FLS)salesforce-personassalesforce-auth, test-standards
Guard against admin-made metadata driftsalesforce-metadata-contracttype-safety, api-testing
Create/clean up org records for a testsalesforce-datadata-strategy, fixtures

If nothing matches, default to common-tasks or ASK. Naming a skill is a fallback for when the wrong one loaded.


5. When NOT to use this scaffold (be honest)

  • Large, pure API suite where the API is the SUT and the backend is non-TypeScript → recommend a backend-native framework instead (pytest + Pydantic, RestAssured, or Schemathesis/Dredd for contract testing from OpenAPI). Playwright's API mode is overkill there. See api-testing Phase 1.
  • Load / performance testing → k6 or Gatling, not this.
  • This scaffold's API project is for API-as-setup and same-stack, modest API-as-SUT suites that benefit from sharing types/fixtures with the UI tests.

6. Profiles (set by bootstrap, recorded in PROJECT.md)

ProfileLocator priorityNotes
genericrole → label → placeholder → text → testIdPlaywright-official order; default
controlledtestId → role → label → textYou can add data-testid; most stable
salesforcerole → label → text → testIdFull pack: 6 extra skills + code. See §7.
api-onlyn/aUI projects pruned; reconsider §5 first

The selectors and wait-strategy skills read the active profile from PROJECT.md.


7. The Salesforce pack

salesforce is not just a locator preference — it ships its own skills (§4) and its own code:

config/salesforce.config.ts           org URLs, API version pin, admin + subject personas
enums/salesforce/                     sObject names, ui-api paths, /lightning/* routes
helpers/salesforce/                   auth · describe · soql · lightning waits · contract · permissions
fixtures/salesforce/                  adminOrg + org + orgAs · persona contexts · metadata schemas
pages/salesforce/                     Lightning component objects (combobox, datatable, modal, toast…)
test-data/salesforce/personas.ts      the persona lattice (9 personas, one axis apart)
test-data/salesforce/contracts/       the contract AS DATA — shape + CRUD + FLS per persona
tests/salesforce/contract/            org project: drift · field shape · permissions   (no browser)
tests/salesforce/ui/                  salesforce project: behaviour as the subject persona
scripts/generate-sobject-schemas.ts   describe → Zod          (run at bootstrap, per org)
scripts/generate-visible-fields.ts    per-persona visible-field sets  (leak detection)

Four things differ from every other profile, and they are the whole reason the pack exists:

  1. Two identities, not one. adminOrg (System Admin) ARRANGES and TEARS DOWN; the subject persona ACTS and ASSERTS. Arrange as a restricted user → teardown silently cannot delete → data leaks. Assert as an admin → Modify All Data bypasses sharing and FLS → the test passes with the permission model completely broken. UI projects default to standardUser, never admin.
  2. Auth is org auth, not a login form. The JWT bearer flow mints a session without touching the login UI — which is also how you legitimately get past mandatory MFA. Never automate an MFA challenge.
  3. The API contract is org metadata. Salesforce ships no OpenAPI. describe is the contract, and it changes the moment an admin clicks Save — so drift detection is a first-class test type (@contract).
  4. Every assertion has a "for whom". The permission model is the product. Personas form a lattice (each differs on exactly one axis), and absence assertions need a positive control that is not an admin — an admin passes via Modify All Data even with the grant broken.

Layering is not optional here (docs/salesforce/TEST-ARCHITECTURE.md):

LayerProjectAsserts
Contractorg (no browser)types, lengths, picklist VALUES, references, record types, permission-set grants, object CRUD, per-persona FLS, exact visible-field sets
UIsalesforcebehaviour only — workflows, persistence, and whether the screen honours the model above

Field metadata and permission matrices in the UI are a wrong-layer error: ~100× the cost, and UI absence is ambiguous (FLS? page layout? record type?) where the API tells you which.

If the profile is NOT salesforce, bootstrap prunes all of the above.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.