playwright-selector-generator
v0.0.0
Published
Playwright's official selector generator, extracted as a standalone browser-side module. Same code that powers `playwright codegen` and the trace viewer.
Maintainers
Readme
playwright-selector-generator
Playwright's official selector generator, extracted via a Vite plugin as a standalone browser-side module. This is the exact code that powers playwright codegen and the trace viewer.
Install
npm install playwright-selector-generatorNo runtime dependencies. The Playwright InjectedScript is pre-bundled at build time.
Usage
generateLocator(element, options?)
Generate the best Playwright locator for a DOM element:
import { generateLocator } from 'playwright-selector-generator';
document.addEventListener('click', (e) => {
const locator = generateLocator(e.target);
console.log(locator);
// => "getByRole('button', { name: 'Submit' })"
// => "getByTestId('my-id')"
// => "getByLabel('Email')"
// => "locator('#sidebar .nav-item')"
});Options:
| Option | Type | Default | Description |
| ----------------- | --------------------- | --------------- | --------------------------------------------------------- |
| testIdAttribute | string | 'data-testid' | Attribute for test IDs |
| root | Element \| Document | document | Scope queries to a subtree |
| lang | string | 'javascript' | Output language: javascript, python, java, csharp |
generateSelectors(element, options?)
Get all selector alternatives for an element, ranked by quality. Returns internal-format strings — convert with selectorToLocator():
import {
generateSelectors,
selectorToLocator,
} from 'playwright-selector-generator';
const selectors = generateSelectors(button);
// [
// 'internal:testid=[data-testid="submit-btn"s]',
// 'internal:role=button[name="Submit"i]',
// 'css=#submit',
// ]
// Convert to any language:
selectors.map((s) => selectorToLocator(s, 'python'));
// [
// "get_by_test_id('submit-btn')",
// "get_by_role('button', name='Submit')",
// "locator('#submit')",
// ]selectorToLocator(selector, lang?)
Convert an internal Playwright selector to a locator string:
import { selectorToLocator } from 'playwright-selector-generator';
selectorToLocator('internal:role=button[name="OK"i]');
// => "getByRole('button', { name: 'OK' })"
selectorToLocator('internal:role=button[name="OK"i]', 'python');
// => "get_by_role('button', name='OK')"
selectorToLocator('internal:role=button[name="OK"i]', 'java');
// => "getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(\"OK\"))"Vite plugin
For advanced usage, a Vite plugin is included that serves Playwright's InjectedScript as a virtual module. This is useful if you need direct access to the InjectedScript class or are running it on an updated playwright package.
// vite.config.ts
import playwrightInjected from 'playwright-selector-generator/vite';
export default defineConfig({
plugins: [playwrightInjected()],
});Then import in your code:
import { InjectedScript } from 'virtual:playwright-injected';TypeScript: Add the type declarations via either a triple-slash reference:
/// <reference types="playwright-selector-generator/virtual-playwright-injected" />Or in tsconfig.json:
{
"compilerOptions": {
"types": ["playwright-selector-generator/virtual-playwright-injected"]
}
}The Vite plugin requires playwright-core as a peer dependency (to extract the InjectedScript at build time).
How it works
At package build time, a Vite plugin extracts Playwright's InjectedScript from playwright-core/lib/generated/injectedScriptSource.js and bundles it alongside the locatorGenerators utilities into a single self-contained ES module. No runtime eval, no playwright-core dependency for consumers.
