Update SKILL.md
This commit is contained in:
+30
-37
@@ -160,15 +160,15 @@ await fileInput.setInputFiles('/path/to/image.png');
|
|||||||
await page.keyboard.press('Meta+v'); // always verify with screenshot!
|
await page.keyboard.press('Meta+v'); // always verify with screenshot!
|
||||||
```
|
```
|
||||||
|
|
||||||
**3. Using stale refs from old snapshots**
|
**3. Using stale locators from old snapshots**
|
||||||
Fallback refs like `ref=e23` change when page updates. Always get a fresh snapshot before clicking:
|
Locators (especially ones with `>> nth=`) can change when the page updates. Always get a fresh snapshot before clicking:
|
||||||
```js
|
```js
|
||||||
// BAD: using ref from minutes ago
|
// BAD: using ref from minutes ago
|
||||||
await page.locator('[id="old-id"]').click(); // element may have changed
|
await page.locator('[id="old-id"]').click(); // element may have changed
|
||||||
|
|
||||||
// GOOD: get fresh snapshot, then immediately use refs from it
|
// GOOD: get fresh snapshot, then immediately use locators from it
|
||||||
console.log(await accessibilitySnapshot({ page, showDiffSinceLastCall: true }));
|
console.log(await accessibilitySnapshot({ page, showDiffSinceLastCall: true }));
|
||||||
// Now use the NEW refs from this output
|
// Now use the NEW locators from this output
|
||||||
```
|
```
|
||||||
|
|
||||||
**4. Wrong assumptions about current page/element**
|
**4. Wrong assumptions about current page/element**
|
||||||
@@ -229,10 +229,10 @@ await loginPage.waitForURL('**/callback**');
|
|||||||
After any action (click, submit, navigate), verify what happened:
|
After any action (click, submit, navigate), verify what happened:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
console.log('url:', page.url()); console.log(await accessibilitySnapshot({ page }).then(x => x.split('\n').slice(0, 30).join('\n')));
|
console.log('url:', page.url()); console.log(await accessibilitySnapshot({ page }));
|
||||||
```
|
```
|
||||||
|
|
||||||
For visually complex pages (grids, galleries, dashboards), use `screenshotWithAccessibilityLabels({ page })` instead to understand spatial layout.
|
For visually complex pages (grids, galleries, dashboards), use `screenshotWithAccessibilityLabels({ page })` instead to understand spatial layout. Label refs are short `eN` strings (e.g. `e3`).
|
||||||
|
|
||||||
If nothing changed, try `await waitForPageLoad({ page, timeout: 3000 })` or you may have clicked the wrong element.
|
If nothing changed, try `await waitForPageLoad({ page, timeout: 3000 })` or you may have clicked the wrong element.
|
||||||
|
|
||||||
@@ -243,40 +243,36 @@ await accessibilitySnapshot({ page, search?, showDiffSinceLastCall? })
|
|||||||
```
|
```
|
||||||
|
|
||||||
- `search` - string/regex to filter results (returns first 10 matching lines)
|
- `search` - string/regex to filter results (returns first 10 matching lines)
|
||||||
- `showDiffSinceLastCall` - returns diff since last snapshot (useful after actions)
|
- `showDiffSinceLastCall` - returns diff since last snapshot (default: `true`). Pass `false` to get full snapshot.
|
||||||
|
|
||||||
For pagination, use `.split('\n').slice(offset, offset + limit).join('\n')`:
|
Snapshots automatically return diffs after the first call. The diff is returned only when it's shorter than the full content.
|
||||||
```js
|
|
||||||
console.log((await accessibilitySnapshot({ page })).split('\n').slice(0, 50).join('\n')); // first 50 lines
|
|
||||||
console.log((await accessibilitySnapshot({ page })).split('\n').slice(50, 100).join('\n')); // next 50 lines
|
|
||||||
```
|
|
||||||
|
|
||||||
Example output:
|
Example output:
|
||||||
|
|
||||||
```md
|
```md
|
||||||
- banner:
|
- banner:
|
||||||
- link "Home" id=nav-home
|
- link "Home" [id="nav-home"]
|
||||||
- navigation:
|
- navigation:
|
||||||
- link "Docs" data-testid=docs-link
|
- link "Docs" [data-testid="docs-link"]
|
||||||
- link "Blog" ref=e1
|
- link "Blog" role=link[name="Blog"]
|
||||||
|
|
||||||
# Locators (pass to page.locator()):
|
|
||||||
# nav-home → [id="nav-home"]
|
|
||||||
# docs-link → [data-testid="docs-link"]
|
|
||||||
# e1 → role=link[name="Blog"]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The attribute name reflects where the ref came from:
|
Each interactive line ends with a Playwright locator you can pass to `page.locator()`.
|
||||||
- `id=value` - element has an id attribute
|
If multiple elements share the same locator, a `>> nth=N` suffix is added (0-based)
|
||||||
- `data-testid=value` - element has a data-testid attribute (or similar test attrs)
|
to make it unique.
|
||||||
- `ref=e1` - fallback for elements without stable IDs
|
|
||||||
|
|
||||||
The **Locators** section at the end shows the exact selector to pass to `page.locator()`:
|
If a screenshot shows ref labels like `e3`, resolve them using the last snapshot:
|
||||||
|
|
||||||
|
```js
|
||||||
|
const snapshot = await accessibilitySnapshot({ page })
|
||||||
|
const locator = refToLocator({ ref: 'e3' })
|
||||||
|
await page.locator(locator!).click()
|
||||||
|
```
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await page.locator('[id="nav-home"]').click()
|
await page.locator('[id="nav-home"]').click()
|
||||||
await page.locator('[data-testid="docs-link"]').click()
|
await page.locator('[data-testid="docs-link"]').click()
|
||||||
await page.locator('role=link[name="Blog"]').click() // for fallback refs
|
await page.locator('role=link[name="Blog"]').click()
|
||||||
```
|
```
|
||||||
|
|
||||||
Search for specific elements:
|
Search for specific elements:
|
||||||
@@ -305,7 +301,7 @@ Both `accessibilitySnapshot` and `screenshotWithAccessibilityLabels` use the sam
|
|||||||
|
|
||||||
## selector best practices
|
## selector best practices
|
||||||
|
|
||||||
**For unknown websites**: use `accessibilitySnapshot()` - it shows what's actually interactive with stable refs.
|
**For unknown websites**: use `accessibilitySnapshot()` - it shows what's actually interactive with stable locators.
|
||||||
|
|
||||||
**For development** (when you have source code access), prefer stable selectors in this order:
|
**For development** (when you have source code access), prefer stable selectors in this order:
|
||||||
|
|
||||||
@@ -477,13 +473,13 @@ await getCleanHTML({ locator, search?, showDiffSinceLastCall?, includeStyles? })
|
|||||||
// Examples:
|
// Examples:
|
||||||
const html = await getCleanHTML({ locator: page.locator('body') })
|
const html = await getCleanHTML({ locator: page.locator('body') })
|
||||||
const html = await getCleanHTML({ locator: page, search: /button/i })
|
const html = await getCleanHTML({ locator: page, search: /button/i })
|
||||||
const diff = await getCleanHTML({ locator: page, showDiffSinceLastCall: true })
|
const fullHtml = await getCleanHTML({ locator: page, showDiffSinceLastCall: false }) // disable diff
|
||||||
```
|
```
|
||||||
|
|
||||||
**Parameters:**
|
**Parameters:**
|
||||||
- `locator` - Playwright Locator or Page to get HTML from
|
- `locator` - Playwright Locator or Page to get HTML from
|
||||||
- `search` - string/regex to filter results (returns first 10 matching lines with 5 lines context)
|
- `search` - string/regex to filter results (returns first 10 matching lines with 5 lines context)
|
||||||
- `showDiffSinceLastCall` - returns unified diff since last call for same locator/page. First call stores snapshot and returns message; subsequent calls return the diff. Useful for tracking DOM changes after actions.
|
- `showDiffSinceLastCall` - returns diff since last call (default: `true`). Pass `false` to get full HTML.
|
||||||
- `includeStyles` - keep style and class attributes (default: false)
|
- `includeStyles` - keep style and class attributes (default: false)
|
||||||
|
|
||||||
**HTML processing:**
|
**HTML processing:**
|
||||||
@@ -498,20 +494,15 @@ The function cleans HTML for compact, readable output:
|
|||||||
- All `data-*` test attributes
|
- All `data-*` test attributes
|
||||||
- Frequently used test IDs and special attributes (e.g., `testid`, `qa`, `e2e`, `vimium-label`)
|
- Frequently used test IDs and special attributes (e.g., `testid`, `qa`, `e2e`, `vimium-label`)
|
||||||
|
|
||||||
For pagination, use `.split('\n').slice(offset, offset + limit).join('\n')`:
|
Snapshots automatically return diffs after the first call. The diff is returned only when it's shorter than the full content.
|
||||||
```js
|
|
||||||
console.log((await getCleanHTML({ locator: page })).split('\n').slice(0, 50).join('\n')); // first 50 lines
|
|
||||||
console.log((await getCleanHTML({ locator: page })).split('\n').slice(50, 100).join('\n')); // next 50 lines
|
|
||||||
```
|
|
||||||
|
|
||||||
**getPageMarkdown** - extract main page content as plain text using Mozilla Readability (same algorithm as Firefox Reader View). Strips navigation, ads, sidebars, and other clutter. Returns formatted text with title, author, and content:
|
**getPageMarkdown** - extract main page content as plain text using Mozilla Readability (same algorithm as Firefox Reader View). Strips navigation, ads, sidebars, and other clutter. Returns formatted text with title, author, and content:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await getPageMarkdown({ page, search?, showDiffSinceLastCall? })
|
await getPageMarkdown({ page, search?, showDiffSinceLastCall? })
|
||||||
// Examples:
|
// Examples:
|
||||||
const content = await getPageMarkdown({ page }) // full article as plain text
|
const content = await getPageMarkdown({ page, showDiffSinceLastCall: false }) // full article
|
||||||
const matches = await getPageMarkdown({ page, search: /API/i }) // search within content
|
const matches = await getPageMarkdown({ page, search: /API/i }) // search within content
|
||||||
const diff = await getPageMarkdown({ page, showDiffSinceLastCall: true }) // track content changes
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output format:**
|
**Output format:**
|
||||||
@@ -528,7 +519,9 @@ The main article content as plain text, with paragraphs preserved...
|
|||||||
**Parameters:**
|
**Parameters:**
|
||||||
- `page` - Playwright Page to extract content from
|
- `page` - Playwright Page to extract content from
|
||||||
- `search` - string/regex to filter content (returns first 10 matching lines with 5 lines context)
|
- `search` - string/regex to filter content (returns first 10 matching lines with 5 lines context)
|
||||||
- `showDiffSinceLastCall` - returns unified diff since last call. Useful for tracking content changes.
|
- `showDiffSinceLastCall` - returns diff since last call (default: `true`). Pass `false` to get full content.
|
||||||
|
|
||||||
|
Snapshots automatically return diffs after the first call. The diff is returned only when it's shorter than the full content.
|
||||||
|
|
||||||
**Use cases:**
|
**Use cases:**
|
||||||
- Extract article text for LLM processing without HTML noise
|
- Extract article text for LLM processing without HTML noise
|
||||||
|
|||||||
Reference in New Issue
Block a user