donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
96 lines • 4.37 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LocateResultSchema = void 0;
const v4_1 = require("zod/v4");
/**
* Flat object schema for a single locator step. All value fields are optional
* because which ones are relevant depends on `method`. This avoids
* discriminated unions / `oneOf` in the generated JSON Schema, which many
* tool-calling LLM providers handle poorly.
*
* After parsing, the consumer must read `method` and pick the appropriate
* fields (e.g. `method: "getByRole"` → use `role` and optionally `name`).
*/
const LocatorStepSchema = v4_1.z
.object({
method: v4_1.z
.enum([
'getByRole',
'getByText',
'getByLabel',
'getByPlaceholder',
'getByTestId',
'locator',
])
.describe('Playwright locator method. Prefer semantic methods (getByRole, getByText, getByLabel, getByPlaceholder, getByTestId) over CSS selectors (locator).'),
role: v4_1.z
.string()
.optional()
.describe('ARIA role name — required when method is "getByRole". E.g. "button", "row", "cell", "heading", "link".'),
name: v4_1.z
.string()
.optional()
.describe('Accessible name to filter by — used with "getByRole". E.g. the button text or aria-label.'),
text: v4_1.z
.string()
.optional()
.describe('Text to match — required when method is "getByText", "getByLabel", or "getByPlaceholder".'),
testId: v4_1.z
.string()
.optional()
.describe('Value of the data-testid attribute — required when method is "getByTestId".'),
selector: v4_1.z
.string()
.optional()
.describe('CSS or XPath selector — required when method is "locator". Use as a last resort.'),
exact: v4_1.z
.boolean()
.optional()
.describe('Whether text/name matching should be exact. Applies to getByRole (name), getByText, getByLabel, getByPlaceholder. Mutually exclusive with nameIsRegex / textIsRegex.'),
nameIsRegex: v4_1.z
.boolean()
.optional()
.describe('Set true when "name" is a regex pattern (compiled via new RegExp(name)). Use this for dynamic accessible names — e.g. "\\d+ comments" matches any "N comments" link. Used with getByRole. Do not combine with exact:true.'),
textIsRegex: v4_1.z
.boolean()
.optional()
.describe('Set true when "text" is a regex pattern (compiled via new RegExp(text)). Use this for dynamic page text — counts, dates, prices, "X ago" timestamps. Used with getByText / getByLabel / getByPlaceholder. Do not combine with exact:true.'),
})
.describe('A single Playwright locator step.');
const FrameStepSchema = v4_1.z
.object({
method: v4_1.z
.enum(['frameLocator', 'frame'])
.describe('"frameLocator" to select by CSS selector, "frame" to select by iframe name attribute.'),
selector: v4_1.z
.string()
.optional()
.describe('CSS selector for the <iframe> element — required when method is "frameLocator".'),
name: v4_1.z
.string()
.optional()
.describe('Value of the iframe name attribute — required when method is "frame".'),
})
.describe('Identifies an iframe to scope into before applying locator steps.');
/**
* Zod schema passed to {@link GptClient.getStructuredOutput} so the LLM
* returns a mechanically constructable Playwright locator.
*/
exports.LocateResultSchema = v4_1.z.object({
frames: v4_1.z
.array(FrameStepSchema)
.optional()
.describe('If the element lives inside one or more iframes, list the frames from outermost to innermost. Omit or leave empty if the element is in the main frame.'),
steps: v4_1.z
.array(LocatorStepSchema)
.min(1)
.max(3)
.describe('Locator chain from broadest scope to the target element (1–3 steps). Each step is an object with a "method" field and the corresponding value fields. Prefer semantic locators (getByRole, getByText, getByLabel) over CSS selectors.'),
nth: v4_1.z
.number()
.int()
.min(0)
.optional()
.describe('Zero-based index to disambiguate when the chain matches multiple elements. Omit if the chain is unique.'),
});
//# sourceMappingURL=locateSchema.js.map