modify template
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
## Playwright
|
||||
|
||||
Playwright is a critical part of the JavaScript API available to you.
|
||||
|
||||
You only have access to a limited subset of the Playwright API, so only call functions that are explicitly defined.
|
||||
You do have access to `tab.playwright.evaluate(...)`, but only in a read-only page scope.
|
||||
Use locators for scoped interactions and targeted checks. For bulk DOM inspection, prefer one bounded read-only `evaluate(...)` that queries and projects the needed data. Avoid loops of locator property calls. In `evaluate(...)`, use basic DOM reads, limit returned elements, and do not assume globals or helpers such as `performance`, `NodeFilter`, `document.createTreeWalker`, or `FormData` exist.
|
||||
|
||||
When using Playwright, keep and reuse a recent `tab.playwright.domSnapshot()` when it is available and you need it for locator construction or retry decisions. Treat the latest relevant snapshot as the source of truth for locator construction and retry decisions.
|
||||
|
||||
### Snapshot Discipline
|
||||
|
||||
- Keep and reuse the latest relevant `domSnapshot()` until it proves stale or you need locator ground truth for UI that was not present in it.
|
||||
- Take a fresh `domSnapshot()` after navigation when you need to orient yourself or construct locators on the new page.
|
||||
- If a click times out, strict mode fails, or a selector parse error occurs, take a fresh `domSnapshot()` before forming the next locator.
|
||||
- Construct locators only from what appears in the latest snapshot. Do not guess labels, accessible names, or selectors.
|
||||
- Do not print full snapshot text repeatedly when a smaller excerpt, a `count()`, a specific attribute, or a direct locator check would answer the question with fewer tokens.
|
||||
- Do not discover page content by iterating through many results, cards, links, or rows and reading their text or attributes one by one.
|
||||
- Do not loop over a broad locator with `all()` and call `getAttribute(...)`, `textContent()`, or `innerText()` on each match. Each read crosses the browser boundary and becomes extremely expensive on large pages.
|
||||
- `locator.getAttribute(...)` is a single-element read, not a batch read. If the locator matches multiple elements, expect a strict-mode error rather than an array of attributes.
|
||||
- Use one broad observation to orient yourself: usually one fresh snapshot, or one screenshot if the visual structure is clearer than the DOM.
|
||||
- After that orientation step, narrow to the relevant section or a small number of strong candidates.
|
||||
- If the page is not getting narrower, do not scale up extraction across more elements. Change strategy instead.
|
||||
- Do not use `locator(...).allTextContents()`, `locator("body").textContent()`, or `locator("body").innerText()` as exploratory search tools across a page or large container.
|
||||
- Use broad text or attribute extraction only after you have already identified the exact container or element you need, and only when a smaller scoped check would not answer the question.
|
||||
- When you need many links, media URLs, or result titles, prefer a single `domSnapshot()` and parse the relevant lines, use the site's own search/filter UI, or navigate directly to a focused results page. Only fall back to per-element reads for a small, already-scoped set of candidates.
|
||||
- Do not use large body-text dumps, embedded app-state JSON such as `__NEXT_DATA__`, or repeated full-page extraction across multiple candidate pages as an exploratory search strategy.
|
||||
- Use large text or embedded JSON extraction only after you have already identified the relevant page, or when a site-specific skill explicitly depends on it.
|
||||
|
||||
### Hard Constraints For Playwright In This Runtime
|
||||
|
||||
- Do not pass a regex as `name` to `getByRole(...)` in this environment. Use a plain string `name` only.
|
||||
- Do not use `.first()`, `.last()`, or `.nth()` unless you have just called `count()` on the same locator and explicitly confirmed why that position is correct.
|
||||
- Do not click, fill, or press on a locator until you have verified it resolves to exactly one element when uniqueness is not obvious.
|
||||
- Do not retry the same failing locator without a fresh `domSnapshot()`.
|
||||
- Do not use a guessed locator as an exploratory probe. If the latest snapshot does not clearly support the locator, do not spend timeout budget testing it.
|
||||
- Do not assume browser-side Playwright supports the full upstream API surface. If a method is not explicitly known to exist, do not call it.
|
||||
- Do not assume `locator(...).selectOption(...)` exists in this environment.
|
||||
|
||||
### Required Interaction Recipe
|
||||
|
||||
Before every click, fill, select-like action, or press:
|
||||
|
||||
1. Reuse the latest relevant `domSnapshot()` when it still contains the locator ground truth you need. Take a fresh one only when it does not.
|
||||
2. Build the most stable locator from the latest snapshot.
|
||||
3. If uniqueness is not obvious from the selector itself, call `count()` on that locator.
|
||||
4. Proceed only if the locator resolves to exactly one element.
|
||||
5. Perform the action.
|
||||
6. After the action, collect another observation only when the next decision requires it. Prefer a targeted state check when it answers the question; take a fresh snapshot when you need new locator ground truth.
|
||||
|
||||
If `count()` is `0`:
|
||||
|
||||
- The selector is wrong, stale, hidden, or the UI state is not ready.
|
||||
- Do not click anyway.
|
||||
- Do not wait on that locator to see if it eventually works.
|
||||
- Re-snapshot and rebuild the locator.
|
||||
|
||||
If `count()` is greater than `1`:
|
||||
|
||||
- The selector is ambiguous.
|
||||
- Scope to the correct container or switch to a stronger attribute.
|
||||
- Do not use `.first()` as a shortcut.
|
||||
|
||||
### Locator Strategy
|
||||
|
||||
Build locators from what the snapshot actually shows, not what looks visually obvious.
|
||||
|
||||
Prefer the most stable contract, in this order:
|
||||
|
||||
1. `data-testid`
|
||||
2. Stable `data-*` attributes
|
||||
3. Stable `href` (prefer exact or strong matches over broad substrings)
|
||||
4. Scoped semantic role + accessible name using a string `name`
|
||||
5. Scoped `getByText(...)`
|
||||
6. Scoped CSS selectors via `locator(...)`
|
||||
7. A scoped DOM-based click path or node-ID-based click when Playwright cannot produce a unique stable locator
|
||||
|
||||
Use the most specific locator that is still durable.
|
||||
|
||||
Treat a stable `href` as a strong hint, not proof of uniqueness. If multiple elements share the same `href`, scope to the correct card or container and confirm `count()` before clicking.
|
||||
|
||||
Treat generic labels like `Menu`, `Main Menu`, `Help`, `Close`, `Default`, `Color`, `Size`, single-letter size labels such as `S`, `M`, `L`, `XL`, `Sort by`, `Search`, and `Add to cart` as ambiguous by default. Scope them to the correct container before acting.
|
||||
|
||||
On search results, product grids, carousels, and modal-heavy pages, repeated `href`s and repeated generic labels are ambiguous by default. First identify the stable card or container, then scope the locator inside that container before clicking.
|
||||
|
||||
### Using `getByRole(..., { name })`
|
||||
|
||||
- `name` is the accessible name, which may differ from visible text.
|
||||
- In the snapshot:
|
||||
- `link "X"` usually reflects the accessible name.
|
||||
- Nested text may be visible text only.
|
||||
- Use `getByRole` only when the accessible name is clearly present and likely unique in the latest snapshot.
|
||||
|
||||
### Interaction Best Practices
|
||||
|
||||
- Scope before acting: find the right container or section first, then target the child element.
|
||||
- If you call `count()` on a locator, store the result in a local variable and reuse it unless the DOM changes.
|
||||
- Match the locator to the actual element type shown in the snapshot (link vs button vs menuitem vs generic text).
|
||||
- Do not assume every click navigates. If opening a menu or filter, wait for the expected UI state, not page load.
|
||||
- Prefer structured local signals such as selected control state, visible confirmation text, modal contents, a specific line item, or URL parameters over scraping broad result sections or dumping large parts of the page.
|
||||
- Do not add explicit `timeoutMs` to routine `click`, `fill`, `check`, or `setChecked` calls unless you have a concrete reason the target is slow to become actionable.
|
||||
- Reserve explicit timeout values for navigation, state transitions, or other known slow operations.
|
||||
- If you already know the exact destination URL and no click-side effect matters, prefer `tab.goto(url)` over a brittle locator click.
|
||||
- Do not reacquire `tab` inside each `node_repl` call. Reuse the existing `tab` binding to save tokens and preserve state. Only reacquire or reassign it when you intentionally switch tabs, after a kernel reset, or after a failed call that did not create the binding.
|
||||
- Do not use fixed sleeps as a default waiting strategy. After an action, prefer a concrete state check or targeted wait. Take a fresh snapshot when you need new locator ground truth.
|
||||
- If a fixed delay is truly unavoidable for a known transition, keep it short and follow it immediately with a specific verification step.
|
||||
|
||||
### Error Recovery
|
||||
|
||||
- A strict mode violation means your locator is ambiguous.
|
||||
- Do not retry the same locator after a strict mode violation.
|
||||
- After strict mode fails, immediately inspect a fresh snapshot and rebuild the locator using tighter scope, a disambiguating container, or a stable attribute.
|
||||
- If a checkbox or radio exists but `check()` or `setChecked()` reports that it is hidden or did not change state, stop retrying the underlying input. Click its scoped visible associated `label[for]` or enclosing visible control once, then verify checked state.
|
||||
- A selector parse error means the locator syntax is invalid in this runtime.
|
||||
- Do not reuse the same locator form after a selector parse error.
|
||||
- A timeout usually means the target is missing, hidden, stale, offscreen, not yet rendered, or the selector is too broad.
|
||||
- Do not retry the same locator immediately after a timeout.
|
||||
- After a timeout, take a fresh snapshot, confirm the target still exists, and then either refine the locator or fall back to a more stable attribute.
|
||||
- If role or accessible-name targeting is unstable, fall back deliberately to a stable attribute (`data-*`, `href`, etc.), not brittle CSS structure.
|
||||
- If two locator attempts fail on the same target, stop escalating complexity on role or text locators. Switch to the most stable visible attribute from the snapshot or use a scoped DOM-based click path.
|
||||
|
||||
### Fallback Guidance
|
||||
|
||||
- Prefer stable `href` values copied from the snapshot over guessed URL patterns.
|
||||
- Prefer scoped attribute selectors over global text selectors.
|
||||
- Use `getByText(...)` only when role-based or attribute-based locators are not reliable, and scope it to a container whenever possible.
|
||||
- Prefer attributes copied directly from the latest snapshot over inferred semantics, fragile CSS chains, or positional selectors.
|
||||
- Do not invent likely selectors. If the snapshot does not clearly expose a unique target, fetch a fresh snapshot and reassess before acting.
|
||||
Reference in New Issue
Block a user