• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
khawjaahmad

khawjaahmad

playwright-selector-gen

MCP: Fetch URL DOM and generate unique Playwright selectors
Public
Like
playwright-selector-gen
Home
Code
2
README.md
H
main.ts
Environment variables
5
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
README.md
Code
/
README.md
Search
…
Viewing readonly version of main branch: v4
View latest version
README.md

Playwright Selector Generator

Endpoint: https://playwright.val.run

Fetches any URL's DOM and generates unique, production-grade selectors for Playwright TypeScript tests. Every CSS selector returned is verified to match exactly one element in the document.


Quick Start

curl -X POST https://playwright.val.run \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com"}'

Filter by tag

curl -X POST https://playwright.val.run \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com", "filter": ["a", "button", "input"]}'

API

GET /

Health check. Returns:

{ "status": "ok", "service": "playwright-selector-gen" }

POST /

FieldTypeRequiredDescription
urlstringYesPage URL to crawl
filterstring[]NoOnly return elements matching these tag names

Response

{ "url": "https://example.com", "totalElements": 5, "selectorsGenerated": 4, "elements": [ { "tag": "h1", "text": "Example Domain", "selectors": { "css_first_child": "h1:first-child", "css_nth_child": "h1:nth-child(1)", "css_child_combinator": "html > body > div > h1", "css_nested_div_path": "div > h1", "xpath_absolute": "/html/body/div/h1", "xpath_optimised": "//h1[normalize-space()='Example Domain']", "xpath_first": "(//h1)[1]" } } ] }

Selector Strategies

XPath

KeyStyleExample
xpath_absoluteFull path with indexes/html/body/div[2]/form/input[3]
xpath_optimisedShortest unique (id/name/text/aria)//input[@name='email']
xpath_firstfirst() positional(//input)[1]

CSS – Positional / Structural

KeyStyleExample
css_nth_childIndex among all siblingsinput:nth-child(3)
css_nth_of_typeIndex among same-tag siblingsdiv:nth-of-type(2)
css_first_childFirst childli:first-child
css_last_childLast childli:last-child
css_child_combinatorFull parent > child chainhtml > body > div:nth-of-type(2) > form > input
css_nested_div_pathDiv-only ancestor chaindiv:nth-of-type(2) > div > input

CSS – Attribute-based

KeyAttribute usedExample
css_idid#login-btn
css_namenameinput[name="email"]
css_testiddata-testid[data-testid="submit"]
css_aria_labelaria-labelbutton[aria-label="Close"]
css_rolerolediv[role="dialog"]
css_typetypeinput[type="password"]
css_hrefhrefa[href="/about"]
css_placeholderplaceholderinput[placeholder="Search…"]
css_titletitleimg[title="Logo"]
css_classclass (first 3)div.container.main.wrapper

Uniqueness Guarantee

  • CSS selectors are tested against the parsed DOM — only selectors resolving to exactly 1 element are included.
  • XPath selectors are structurally unique by construction (absolute paths with sibling indexes).

Using in Playwright Tests

import { test, expect } from '@playwright/test'; test('login form', async ({ page }) => { await page.goto('https://myapp.com/login'); // CSS child combinator await page.locator('html > body > div > form > input:nth-of-type(1)').fill('user@test.com'); // XPath optimised await page.locator("//input[@name='password']").fill('secret'); // CSS nth-child await page.locator('button:nth-child(2)').click(); // XPath first() await expect(page.locator("(//h1)[1]")).toHaveText('Dashboard'); });

Supported Elements

Interactive and structural tags are scanned: a, button, input, select, textarea, form, label, img, h1–h6, nav, header, footer, main, section, article, table, tr, th, td, ul, ol, li, details, summary, dialog, iframe, video, audio, svg, span, p, div.

Elements with role, data-testid, aria-label, onclick, or tabindex attributes are also included regardless of tag.

Results are capped at 500 elements per request.


Provider Config

Provider : Anthropic
Model    : anthropic/claude-opus-4-20250514
URL      : https://api.z.ai/api/anthropic
API Key  : your_zai_api_key

Error Responses

StatusMeaning
400Missing url in request body
405Method not allowed (use POST)
502Target URL could not be fetched
500Internal parsing error
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.