Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/zzatpku-playwright
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: testing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/playwright
What's inside
- Skill name
playwright- Description
- Browser automation via Playwright. Enables opening web pages, clicking elements, typing text, reading DOM, handling modals, and more.
- License
- MIT
- Instructions
- 352 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Playwright Browser Automation Tool
Playwright is a Python library for automating Chromium, Firefox, and WebKit browsers. It allows your subagent to interact with web pages programmatically — navigate URLs, click buttons, fill forms, read page content, take screenshots, and handle popups/modals.
## Usage
```python
from playwright.sync_api import sync_playwright
```
## Core Concepts
### 1. Launch Browser and Open Page
```python
from playwright.sync_api import sync_playwright
import os, json, re, tools
PROJECT_ROOT = os.path.dirname(os.path.abspath(tools.__file__))
USER_DATA_DIR = os.path.join(PROJECT_ROOT, ".browser_profile")
with sync_playwright() as p:
# Use persistent context to preserve login sessions across runs
context = p.chromium.launch_persistent_context(
USER_DATA_DIR,
headless=False, # set True for headless, False to see the browser
channel="chrome",
locale="zh-CN",
viewport={"width": 1280, "height": 800},
args=["--disable-blink-features=AutomationControlled"],
)
page = context.new_page()
page.goto("https://example.com", wait_until="domcontentloaded")
page.wait_for_timeout(2000)
# ... do work ...
context.close()
```
### 2. Find Interactive Elements (with iframe support)
Inject JavaScript to discover **all visible interactive elements** across the main page and all iframes. Each element is tagged with a unique `data-bid` and described with rich attributes.
```python
JS_TAG_ELEMENTS = """(startId) => {
document.querySelectorAll('[data-bid]').forEach(e => e.removeAttribute('data-bid'));
const sels = 'button, input, textarea, select, a[href], ' +
'[role="button"], [role="tab"], [role="link"], [role="menuitem"], ' +
'[role="option"], [role="switch"], [role="textbox"], [role="combobox"], ' +
'[role="checkbox"], [role="radio"], [contenteditable="true"], ' +
'[onclick], [tabindex]:not([tabindex="-1"])';
const candidates = [...document.querySelectorAll(sels)];
// Catch styled divs/spans acting as buttons (cursor:pointer)
document.querySelectorAll('div, span, li, label, td, img, svg').forEach(el => {
if (el.matches(sels)) return;
try {
if (window.getComputedStyle(el).cursor === 'pointer') candidates.push(el);
} catch(e) {}
});
const seen = new Set();
const results = [];
let id = startId;
for (const el of candidates) {
if (seen.has(el)) continue;
seen.add(el);
const rect = el.getBoundingClientRect();
if (rect.width < 2 || rect.height < 2) continue;
// Only include elements visible in the current viewport
if (rect.bottom < 0 || rect.top > window.innerHeight) continue;
if (rect.right < 0 || rect.left > window.innerWidth) continue;
const style = window.getComputedStyle(el);
if (style.display === 'none' || style.visibility === 'hidden' || style.opacity === '0') continue;
id++;
el.setAttribute('data-bid', String(id));
const text = (el.innerText || '').trim().slice(0, 80);
const tag = el.tagName.toLowerCase();
const role = el.getAttribute('role') || '';
const ariaLabel = el.getAttribute('aria-label') || '';
const title = el.getAttribute('title') || '';
const ph = el.getAttribute('placeholder') || '';
const type = el.getAttribute('type') || '';
const cls = (el.className || '').toString().slice(0, 80);
const disabled = el.disabled || el.getAttribute('aria-disabled') === 'true';
const checked = el.checked === true;
const ariaSelected = el.getAttribute('aria-selected');
const ariaExpanded = el.getAttribute('aria-expanded');
const value = (tag === 'input' || tag === 'textarea') ? (el.value || '').slice(0, 40) : '';
let desc = '[' + id + '] <' + tag + '>';
if (role) desc += ' role="' + role + '"';
if (text) desc += ' "' + text + '"';
if (ariaLabel && ariaLabel !== text) desc += ' aria="' + ariaLabel + '"';
if (title && title !== text) desc += ' title="' + title + '"';
if (ph) desc += ' placeholder="' + ph + '"';
if (type) desc += ' type="' + type + '"';
if (cls) desc += ' class="' + cls + '"';
if (disabled) desc += ' [disabled]';
if (checked) desc += ' [checked]';
if (ariaSelected === 'true') desc += ' [selected]';
if (ariaExpanded !== null) desc += ' expanded=' + ariaExpanded;
if (value) desc += ' value="' + value + '"';
desc += ' @(' + Math.round(rect.x) + ',' + Math.round(rect.y) + ',' + Math.round(rect.width) + 'x' + Math.round(rect.height) + ')';
results.push(desc);
}
return JSON.stringify({text: results.join('\\n'), nextId: id});
}"""
def get_all_elements(page):
"""Discover interactive elements across main page AND all iframes.
Returns (elements_text, element_frames_dict).
element_frames maps bid(int) -> frame, used by click_element / type_in_element.
"""
element_frames = {}
all_text = []
next_id = 0
for i, frame in enumerate(page.frames):
try:
raw = frame.evaluate(JS_TAG_ELEMENTS, next_id)
result = json.loads(raw)
if result['text']:
label = "Main Page" if i == 0 else frame.url.split('?')[0][-50:]From zzatpku/AgentFactory, MIT.
More from zzatpku/AgentFactory
- 0.513score
finish
zzatpku
Complete the task with a final answer and save reusable subagents as skills.
SkillDFreshness: D★ 66Claude Code +9 - 0.509score
view_subagent_code
zzatpku
View the source code of a saved subagent skill.
SkillDFreshness: D★ 66Claude Code +9 - 0.509score
list_saved_subagents
zzatpku
List all previously saved subagent skills.
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
google_search
zzatpku
Search the internet via Google (Serper API).
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
open_page
zzatpku
Retrieve the full content of a document by its ID.
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
local_search
zzatpku
Search for relevant documents in the local knowledge base.
SkillDFreshness: D★ 66Claude Code +9 - 0.503score
run_subagent
zzatpku
Run a subagent - either a newly created one from workspace or a saved subagent from previous sessions.
SkillDFreshness: D★ 66Claude Code +9 - 0.503score
modify_subagent
zzatpku
Edit an existing subagent file by replacing specific code snippets.
SkillDFreshness: D★ 66Claude Code +9 - 0.502score
read_url_jina
zzatpku
Retrieve the full content of a web page by its URL.
SkillDFreshness: D★ 66Claude Code +9 - 0.502score
execute_shell_command
zzatpku
Execute standard Bash shell commands in a non-interactive environment.
SkillDFreshness: D★ 66Claude Code +9 - 0.502score
create_subagent
zzatpku
Create a new Python subagent file in the workspace.
SkillDFreshness: D★ 66Claude Code +9 - 0.273score
tencent_docs_final
zzatpku
No description from the publisher yet.
SkillDFreshness: D★ 66Claude Code +9
Signals
- Stars
- 66
- Forks
- 8
- Open issues
- 0
- Last commit (this folder)
- Feb 28, 2026 (8 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/zzatpku/AgentFactory
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from zzatpku
- 0.513score
finish
zzatpku
Complete the task with a final answer and save reusable subagents as skills.
SkillDFreshness: D★ 66Claude Code +9 - 0.509score
view_subagent_code
zzatpku
View the source code of a saved subagent skill.
SkillDFreshness: D★ 66Claude Code +9 - 0.509score
list_saved_subagents
zzatpku
List all previously saved subagent skills.
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
local_search
zzatpku
Search for relevant documents in the local knowledge base.
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
open_page
zzatpku
Retrieve the full content of a document by its ID.
SkillDFreshness: D★ 66Claude Code +9 - 0.506score
google_search
zzatpku
Search the internet via Google (Serper API).
SkillDFreshness: D★ 66Claude Code +9
Cite this page
playwright skill. Agent Mart. https://agentmart.dev/skills/zzatpku-playwright (last updated 2026-10-24)