playwright-genie 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +435 -0
- package/dist/index.cjs +1185 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +253 -0
- package/dist/index.js +1138 -0
- package/dist/index.js.map +7 -0
- package/package.json +70 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/entry.js", "../src/llm/client.js", "../src/llm/prompt.js", "../src/llm/parser.js", "../src/cache/disk-cache.js", "../src/cache/memory-cache.js", "../src/page-structure.js", "../src/resolver.js", "../src/actions.js", "../src/smart-locator.js", "../src/llm-locator.js"],
|
|
4
|
+
"sourcesContent": ["export { createSmartLocator, clearCache, clearAllCaches } from './smart-locator.js';\nexport { SmartAction } from './actions.js';\nexport { resolveLocator, getLocator, resolveLocatorsBatch } from './resolver.js';\nexport { getPageStructure } from './page-structure.js';\nexport { chatCompletion, getConfig } from './llm/client.js';\nexport { findLocator, findAllMatches } from './llm-locator.js';", "import 'dotenv/config';\nimport OpenAI from 'openai';\n\nconst DEBUG = process.env.LLM_LOCATOR_DEBUG === 'true';\n\nconst LLM_API_KEY = process.env.LLM_API_KEY || process.env.ROUTELLM_API_KEY || process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY;\nconst LLM_BASE_URL = process.env.LLM_BASE_URL || process.env.ROUTELLM_BASE_URL || 'https://api.openai.com/v1';\nconst LLM_MODEL = process.env.LLM_MODEL || process.env.ROUTELLM_MODEL || 'gpt-4o-mini';\n\nif (!LLM_API_KEY) {\n throw new Error(\n 'No LLM API key found. Set one of: LLM_API_KEY, ROUTELLM_API_KEY, OPENAI_API_KEY, or ANTHROPIC_API_KEY'\n );\n}\n\nconst client = new OpenAI({\n baseURL: LLM_BASE_URL,\n apiKey: LLM_API_KEY\n});\n\nasync function chatCompletion(messages, options = {}) {\n const {\n model = LLM_MODEL,\n temperature = 0,\n maxTokens = 1024\n } = options;\n\n if (DEBUG) {\n console.log(`[LLM Client] model=${model} base=${LLM_BASE_URL} msgs=${messages.length}`);\n }\n\n const completion = await client.chat.completions.create({\n model,\n temperature,\n max_tokens: maxTokens,\n messages\n });\n\n return completion.choices[0].message.content.trim();\n}\n\nfunction getConfig() {\n return {\n apiKey: LLM_API_KEY ? '***' + LLM_API_KEY.slice(-4) : null,\n baseUrl: LLM_BASE_URL,\n model: LLM_MODEL\n };\n}\n\nexport { chatCompletion, getConfig, LLM_MODEL };", "\nconst SYSTEM_PROMPT = `You are an expert at generating Playwright locators from page structure.\nYou receive a (possibly trimmed) accessibility tree in YAML and special DOM elements.\n\nCRITICAL RULES:\n1. ONLY use exact text/names that EXIST in the provided structure. NEVER invent or echo the user's query as locator text.\n2. The user's query is a DESCRIPTION of the element, NOT the element's text. You must FIND the matching element in the tree.\n Example: Query \"Admin Tab\" \u2192 find the link/tab named \"Admin\" in the tree \u2192 getByRole('link', { name: /Admin/i })\n Example: Query \"login button\" \u2192 find button named \"Login\" in the tree \u2192 getByRole('button', { name: /Login/i })\n3. YAML format: \"- link \\\\\"Sign in\\\\\"\" means a link element with accessible name \"Sign in\"\n \"- textbox \\\\\"Username\\\\\"\" means a textbox with accessible name \"Username\"\n4. Prefer getByRole with name regex: { name: /text/i } for robustness.\n5. Words like \"tab\", \"button\", \"link\", \"field\", \"textbox\", \"input\" in the query describe the ELEMENT TYPE, not the text content.\n\nACTION-AWARE RULES:\n- If action is \"fill\", \"type\", \"clear\", \"press\": The target MUST be an editable element (textbox, searchbox, combobox, input). Use getByRole('textbox', ...) or getByPlaceholder or getByLabel. NEVER target a label or static text.\n- If action is \"click\", \"dblclick\", \"tap\", \"focus\", \"hover\": Target the interactive element (link, button, tab, menuitem, etc).\n- If action is \"check\", \"uncheck\": Target a checkbox or radio element.\n- If action is \"select\": Target a combobox or listbox element.\n- If action is \"getText\" or null: Target any matching element.\n\nPRIORITY: getByTestId > getByRole > getByLabel > getByPlaceholder > getByAltText > getByTitle > getByText > locator(CSS)\nFor iframes: page.frameLocator('sel').getByRole(...)\nFor positional: .first() / .nth(n) / .last()\n\nReturn ONLY valid JSON.`;\n\nfunction buildMessages(payloadStr, query, action) {\n const actionHint = action\n ? `\\nAction: \"${action}\" (the locator MUST target an element appropriate for this action)`\n : '';\n\n return [\n { role: 'system', content: SYSTEM_PROMPT },\n {\n role: 'user',\n content: `Page:\\n${payloadStr}\\n\\nFind element described as: \"${query}\"${actionHint}\\n\\nIMPORTANT: Match the query to an ACTUAL element in the tree above. Do NOT use the query text as locator text.\\n\\nJSON: { \"strategy\":\"\u2026\", \"locatorString\":\"page.getBy\u2026()\", \"isInFrame\":false, \"frameSelector\":null, \"confidence\":0.95, \"reasoning\":\"\u2026\" }`\n }\n ];\n}\n\nfunction buildBatchMessages(payloadStr, queries) {\n const queriesList = queries.map((q, i) => `${i + 1}. \"${q}\"`).join('\\n');\n\n return [\n { role: 'system', content: SYSTEM_PROMPT },\n {\n role: 'user',\n content: `Page:\\n${payloadStr}\\n\\nFind locators for ALL (match each query to ACTUAL elements in the tree, do NOT echo query text):\\n${queriesList}\\n\\nReturn JSON array:\\n[{ \"query\":\"\u2026\", \"strategy\":\"\u2026\", \"locatorString\":\"page.getBy\u2026()\", \"isInFrame\":false, \"frameSelector\":null, \"confidence\":0.95, \"reasoning\":\"\u2026\" }]`\n }\n ];\n}\n\nexport { SYSTEM_PROMPT, buildMessages, buildBatchMessages };", "function parseJsonResponse(raw) {\n let text = raw.trim();\n if (text.startsWith('```')) {\n text = text.replace(/```json?\\n?/g, '').replace(/```\\n?$/g, '');\n }\n return JSON.parse(text);\n}\n\nfunction createPlaywrightLocator(page, locatorString, isInFrame, frameSelector) {\n let code = locatorString.replace(/^page\\./, '');\n let context = page;\n if (isInFrame && frameSelector) {\n context = page.frameLocator(frameSelector);\n code = code.replace(/^frameLocator\\([^)]+\\)\\./, '');\n }\n return evalLocator(context, code);\n}\n\nfunction parseInlineOptions(str) {\n if (!str) return {};\n const opts = {};\n const nameRegex = str.match(/name:\\s*\\/([^/]+)\\/([gimsuy]*)/);\n const nameStr = str.match(/name:\\s*'([^']+)'/);\n const exact = str.match(/exact:\\s*(true|false)/);\n if (nameRegex) opts.name = new RegExp(nameRegex[1], nameRegex[2] || undefined);\n else if (nameStr) opts.name = nameStr[1];\n if (exact) opts.exact = exact[1] === 'true';\n return opts;\n}\n\nfunction parseTextArg(quoted, regexBody, regexFlags) {\n if (quoted) return quoted;\n if (regexBody) return new RegExp(regexBody, regexFlags || undefined);\n return null;\n}\n\nfunction parseFilterOptions(str) {\n if (!str) return {};\n const opts = {};\n const hasText = str.match(/hasText:\\s*(?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))/);\n const hasNotText = str.match(/hasNotText:\\s*(?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))/);\n if (hasText) opts.hasText = hasText[1] || new RegExp(hasText[2], hasText[3] || undefined);\n if (hasNotText) opts.hasNotText = hasNotText[1] || new RegExp(hasNotText[2], hasNotText[3] || undefined);\n return opts;\n}\n\nfunction evalLocator(context, code) {\n const patterns = [\n {\n regex: /getByRole\\('([^']+)'(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const opts = parseInlineOptions(m[2]);\n return applyChain(context.getByRole(m[1], opts), m[3]);\n }\n },\n {\n regex: /getByTestId\\('([^']+)'\\)(.*)/,\n handler: (m) => applyChain(context.getByTestId(m[1]), m[2])\n },\n {\n regex: /getByLabel\\((?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const t = parseTextArg(m[1], m[2], m[3]);\n const opts = parseInlineOptions(m[4]);\n return applyChain(context.getByLabel(t, opts), m[5]);\n }\n },\n {\n regex: /getByPlaceholder\\((?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const t = parseTextArg(m[1], m[2], m[3]);\n const opts = parseInlineOptions(m[4]);\n return applyChain(context.getByPlaceholder(t, opts), m[5]);\n }\n },\n {\n regex: /getByText\\((?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const t = parseTextArg(m[1], m[2], m[3]);\n const opts = parseInlineOptions(m[4]);\n return applyChain(context.getByText(t, opts), m[5]);\n }\n },\n {\n regex: /getByAltText\\((?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const t = parseTextArg(m[1], m[2], m[3]);\n const opts = parseInlineOptions(m[4]);\n return applyChain(context.getByAltText(t, opts), m[5]);\n }\n },\n {\n regex: /getByTitle\\((?:'([^']+)'|\\/([^/]+)\\/([gimsuy]*))(?:,\\s*({[^}]+}))?\\)(.*)/,\n handler: (m) => {\n const t = parseTextArg(m[1], m[2], m[3]);\n const opts = parseInlineOptions(m[4]);\n return applyChain(context.getByTitle(t, opts), m[5]);\n }\n },\n {\n regex: /locator\\('([^']+)'\\)(.*)/,\n handler: (m) => applyChain(context.locator(m[1]), m[2])\n }\n ];\n\n for (const p of patterns) {\n const match = code.match(p.regex);\n if (match) return p.handler(match);\n }\n throw new Error(`Unsupported locator pattern: ${code}`);\n}\n\nfunction applyChain(loc, chain) {\n if (!chain?.trim()) return loc;\n if (chain.includes('.first()')) { loc = loc.first(); chain = chain.replace('.first()', ''); }\n if (chain.includes('.last()')) { loc = loc.last(); chain = chain.replace('.last()', ''); }\n const n = chain.match(/\\.nth\\((\\d+)\\)/);\n if (n) loc = loc.nth(parseInt(n[1]));\n const f = chain.match(/\\.filter\\(({[^}]+})\\)/);\n if (f) loc = loc.filter(parseFilterOptions(f[1]));\n return loc;\n}\n\nasync function validateLocator(locator, timeoutMs = 3000) {\n try {\n await locator.waitFor({ state: 'attached', timeout: timeoutMs });\n return true;\n } catch {\n return false;\n }\n}\n\nexport { parseJsonResponse, createPlaywrightLocator, evalLocator, applyChain, validateLocator };", "import fs from 'fs';\nimport path from 'path';\n\nconst DEBUG = process.env.LLM_LOCATOR_DEBUG === 'true';\nconst CACHE_FILE = process.env.LOCATOR_CACHE_FILE || '.locator-cache.json';\n\nlet diskCache = null;\n\nfunction loadDiskCache() {\n if (diskCache !== null) return diskCache;\n const filePath = path.resolve(CACHE_FILE);\n try {\n if (fs.existsSync(filePath)) {\n diskCache = JSON.parse(fs.readFileSync(filePath, 'utf-8'));\n if (DEBUG) console.log(`[Disk Cache] Loaded ${Object.keys(diskCache).length} entries from ${CACHE_FILE}`);\n } else {\n diskCache = {};\n }\n } catch (e) {\n console.warn(`[Disk Cache] Failed to read ${CACHE_FILE}:`, e.message);\n diskCache = {};\n }\n return diskCache;\n}\n\nfunction saveDiskCache() {\n const filePath = path.resolve(CACHE_FILE);\n try {\n fs.writeFileSync(filePath, JSON.stringify(diskCache, null, 2), 'utf-8');\n } catch (e) {\n console.warn(`[Disk Cache] Failed to write ${CACHE_FILE}:`, e.message);\n }\n}\n\nfunction makeCacheKey(urlOrPage, query, action) {\n let urlPath;\n if (typeof urlOrPage === 'string') {\n try { urlPath = new URL(urlOrPage).pathname; } catch { urlPath = urlOrPage; }\n } else {\n try { urlPath = new URL(urlOrPage.url()).pathname; } catch { urlPath = urlOrPage.url(); }\n }\n return `${urlPath}::${(action || 'any').toLowerCase()}::${query.toLowerCase().trim()}`;\n}\n\nfunction getDiskEntry(url, query, action) {\n const cache = loadDiskCache();\n return cache[makeCacheKey(url, query, action)] || null;\n}\n\nfunction setDiskEntry(url, query, action, entry) {\n const cache = loadDiskCache();\n cache[makeCacheKey(url, query, action)] = {\n locatorString: entry.locatorString,\n strategy: entry.strategy,\n isInFrame: entry.isInFrame || false,\n frameSelector: entry.frameSelector || null,\n confidence: entry.confidence,\n reasoning: entry.reasoning,\n createdAt: new Date().toISOString(),\n hitCount: 0\n };\n saveDiskCache();\n}\n\nfunction invalidateDiskEntry(url, query, action) {\n const cache = loadDiskCache();\n const key = makeCacheKey(url, query, action);\n if (cache[key]) {\n delete cache[key];\n saveDiskCache();\n return true;\n }\n return false;\n}\n\nfunction bumpHitCount(url, query, action) {\n const cache = loadDiskCache();\n const key = makeCacheKey(url, query, action);\n if (cache[key]) {\n cache[key].hitCount = (cache[key].hitCount || 0) + 1;\n cache[key].lastUsed = new Date().toISOString();\n saveDiskCache();\n }\n}\n\nfunction clearDiskCache() {\n diskCache = {};\n saveDiskCache();\n}\n\nexport {\n loadDiskCache, getDiskEntry, setDiskEntry,\n invalidateDiskEntry, bumpHitCount, clearDiskCache, makeCacheKey\n};", "const memCache = new Map();\nlet structureCache = { url: null, timestamp: 0, data: null };\nconst STRUCTURE_TTL = 8000;\n\nfunction getMemKey(url, query, action) {\n return `${url}::${(action || 'any').toLowerCase()}::${query.toLowerCase().trim()}`;\n}\n\nfunction getMemEntry(url, query, action) {\n return memCache.get(getMemKey(url, query, action)) || null;\n}\n\nfunction setMemEntry(url, query, action, entry) {\n memCache.set(getMemKey(url, query, action), entry);\n}\n\nfunction deleteMemEntry(url, query, action) {\n memCache.delete(getMemKey(url, query, action));\n}\n\nfunction getStructureCache() {\n return structureCache;\n}\n\nfunction setStructureCache(url, data) {\n structureCache = { url, timestamp: Date.now(), data };\n}\n\nfunction isStructureCacheValid(url) {\n return (\n structureCache.url === url &&\n (Date.now() - structureCache.timestamp) < STRUCTURE_TTL &&\n structureCache.data\n );\n}\n\nfunction clearStructureCache() {\n structureCache = { url: null, timestamp: 0, data: null };\n}\n\nfunction clearMemoryCache() {\n memCache.clear();\n clearStructureCache();\n}\n\nexport {\n getMemKey, getMemEntry, setMemEntry, deleteMemEntry,\n getStructureCache, setStructureCache, isStructureCacheValid, clearStructureCache,\n clearMemoryCache, STRUCTURE_TTL\n};", "import { isStructureCacheValid, getStructureCache, setStructureCache } from './cache/memory-cache.js';\n\nconst DEBUG = process.env.LLM_LOCATOR_DEBUG === 'true';\n\nasync function getPageStructure(page, forceRefresh = false) {\n const url = page.url();\n\n if (!forceRefresh && isStructureCacheValid(url)) {\n if (DEBUG) console.log('[Page Structure] Using cached');\n return getStructureCache().data;\n }\n\n const structure = { mainFrame: await getFrameStructure(page), frames: [] };\n\n for (const frame of page.frames()) {\n if (frame === page.mainFrame()) continue;\n try {\n const frameElement = await frame.frameElement();\n const frameInfo = await page.evaluate((el) => ({\n id: el.id || null,\n name: el.name || null,\n selector: el.id ? `#${el.id}` :\n el.name ? `iframe[name=\"${el.name}\"]` :\n el.title ? `iframe[title=\"${el.title}\"]` : 'iframe'\n }), frameElement);\n structure.frames.push({ ...frameInfo, content: await getFrameStructure(frame) });\n } catch (e) { /* detached */ }\n }\n\n setStructureCache(url, structure);\n return structure;\n}\n\nasync function getFrameStructure(pageOrFrame) {\n let ariaTree = null;\n let specialElements = [];\n\n const [ariaResult, domResult] = await Promise.allSettled([\n pageOrFrame.locator('body').ariaSnapshot({ timeout: 5000 }),\n pageOrFrame.evaluate(() => {\n const els = [];\n for (const el of document.querySelectorAll(\n '[data-testid], [data-test-id], [data-test], [data-qa], [data-cy], ' +\n '[placeholder], [alt], [aria-label]'\n )) {\n const e = {\n tag: el.tagName.toLowerCase(),\n testId: el.getAttribute('data-testid') || el.getAttribute('data-test-id') ||\n el.getAttribute('data-test') || el.getAttribute('data-qa') ||\n el.getAttribute('data-cy') || null,\n placeholder: el.getAttribute('placeholder') || null,\n alt: el.getAttribute('alt') || null,\n ariaLabel: el.getAttribute('aria-label') || null\n };\n if (e.testId || e.placeholder || e.alt || e.ariaLabel) els.push(e);\n }\n return els;\n })\n ]);\n\n if (ariaResult.status === 'fulfilled') ariaTree = ariaResult.value;\n else {\n try {\n if (typeof pageOrFrame.mainFrame === 'function') {\n const snap = await pageOrFrame.accessibility.snapshot();\n if (snap) ariaTree = JSON.stringify(simplifyAriaTree(snap));\n }\n } catch (e) { /* */ }\n }\n\n if (domResult.status === 'fulfilled') specialElements = domResult.value;\n return { ariaTree, specialElements };\n}\n\nfunction simplifyAriaTree(node, depth = 0) {\n if (!node || depth > 8) return null;\n const s = {};\n if (node.role) s.role = node.role;\n if (node.name) s.name = node.name;\n if (node.children?.length) {\n s.children = node.children.map(c => simplifyAriaTree(c, depth + 1)).filter(Boolean);\n }\n return s;\n}\n\nfunction trimSnapshotForQuery(ariaYaml, query, maxLines = 150) {\n if (!ariaYaml || typeof ariaYaml !== 'string') return ariaYaml;\n\n const lines = ariaYaml.split('\\n');\n if (lines.length <= maxLines) return ariaYaml;\n\n const queryTokens = query.toLowerCase().replace(/[^a-z0-9\\s]/g, '').split(/\\s+/).filter(Boolean);\n\n const scoredLines = lines.map((line, idx) => {\n const lower = line.toLowerCase();\n let score = 0;\n for (const token of queryTokens) {\n if (lower.includes(token)) score += 10;\n }\n if (/button|link|textbox|searchbox|combobox|checkbox|tab\\b/.test(lower)) score += 3;\n if (/heading|navigation|banner|main|form/.test(lower)) score += 2;\n return { line, idx, score };\n });\n\n const relevant = new Set();\n\n for (const { idx, score } of scoredLines) {\n if (score > 0) {\n const contextStart = Math.max(0, idx - 3);\n const contextEnd = Math.min(lines.length - 1, idx + 2);\n for (let i = contextStart; i <= contextEnd; i++) relevant.add(i);\n }\n }\n\n for (let i = 0; i < Math.min(15, lines.length); i++) relevant.add(i);\n\n if (relevant.size < maxLines) {\n const interactive = scoredLines\n .filter(s => s.score >= 3 && !relevant.has(s.idx))\n .sort((a, b) => b.score - a.score);\n for (const { idx } of interactive) {\n if (relevant.size >= maxLines) break;\n relevant.add(idx);\n if (idx > 0) relevant.add(idx - 1);\n }\n }\n\n const sorted = [...relevant].sort((a, b) => a - b);\n const result = [];\n let lastIdx = -1;\n for (const idx of sorted) {\n if (lastIdx !== -1 && idx - lastIdx > 1) result.push(' ...');\n result.push(lines[idx]);\n lastIdx = idx;\n }\n\n return result.join('\\n');\n}\n\nexport { getPageStructure, getFrameStructure, trimSnapshotForQuery };", "import { chatCompletion } from './llm/client.js';\nimport { buildMessages, buildBatchMessages } from './llm/prompt.js';\nimport { parseJsonResponse, createPlaywrightLocator, validateLocator } from './llm/parser.js';\nimport { getDiskEntry, setDiskEntry, invalidateDiskEntry, bumpHitCount } from './cache/disk-cache.js';\nimport { getMemEntry, setMemEntry, deleteMemEntry, clearStructureCache } from './cache/memory-cache.js';\nimport { getPageStructure, trimSnapshotForQuery } from './page-structure.js';\n\nconst DEBUG = process.env.LLM_LOCATOR_DEBUG === 'true';\n\nfunction buildPayload(pageStructure, query) {\n const trimmedAria = trimSnapshotForQuery(pageStructure.mainFrame.ariaTree, query);\n\n const payload = {\n ariaTree: trimmedAria,\n specialElements: pageStructure.mainFrame.specialElements,\n frames: pageStructure.frames.length > 0 ? pageStructure.frames.map(f => ({\n selector: f.selector,\n ariaTree: trimSnapshotForQuery(f.content?.ariaTree, query, 50),\n specialElements: f.content?.specialElements || []\n })) : undefined\n };\n\n let payloadStr = JSON.stringify(payload, null, 2);\n if (payloadStr.length > 15000) payloadStr = payloadStr.substring(0, 15000) + '\\n...(truncated)';\n return payloadStr;\n}\n\nasync function queryLLM(pageStructure, query, options = {}) {\n const { action = null } = options;\n const payloadStr = buildPayload(pageStructure, query);\n\n if (DEBUG) console.log('[Resolver] Payload size:', payloadStr.length, 'chars');\n\n const messages = buildMessages(payloadStr, query, action);\n const raw = await chatCompletion(messages, options);\n return parseJsonResponse(raw);\n}\n\nasync function resolveLocator(page, query, options = {}) {\n const shouldDebug = DEBUG || options.debug;\n const action = options.action || null;\n const url = page.url();\n\n const memHit = getMemEntry(url, query, action);\n if (memHit) {\n if (shouldDebug) console.log(`[Memory Cache Hit] \"${query}\" \u2192 ${memHit.locatorString}`);\n return memHit;\n }\n\n const diskHit = getDiskEntry(url, query, action);\n if (diskHit) {\n if (shouldDebug) console.log(`[Disk Cache Hit] \"${query}\" \u2192 ${diskHit.locatorString} (hits: ${diskHit.hitCount || 0})`);\n const result = {\n found: true,\n strategy: diskHit.strategy,\n locatorString: diskHit.locatorString,\n isInFrame: diskHit.isInFrame || false,\n frameSelector: diskHit.frameSelector || null,\n confidence: diskHit.confidence,\n reasoning: diskHit.reasoning,\n source: 'disk'\n };\n setMemEntry(url, query, action, result);\n return result;\n }\n\n if (shouldDebug) console.log(`[LLM] Querying: \"${query}\" (action: ${action || 'any'})`);\n const t0 = Date.now();\n\n const pageStructure = await getPageStructure(page);\n\n try {\n const parsed = await queryLLM(pageStructure, query, options);\n\n const result = {\n found: parsed.confidence > 0.5,\n strategy: parsed.strategy,\n locatorString: parsed.locatorString,\n isInFrame: parsed.isInFrame || false,\n frameSelector: parsed.frameSelector || null,\n confidence: parsed.confidence,\n reasoning: parsed.reasoning,\n fallbackLocators: parsed.fallbackLocators || [],\n source: 'llm'\n };\n\n if (shouldDebug) console.log(`[LLM] \"${query}\" \u2192 ${result.locatorString} (${Date.now() - t0}ms)`);\n\n if (result.found) {\n setMemEntry(url, query, action, result);\n setDiskEntry(url, query, action, result);\n }\n\n return result;\n } catch (error) {\n console.error('LLM locator error:', error.message);\n return { found: false, confidence: 0, error: error.message, source: 'llm' };\n }\n}\n\nasync function getLocator(page, query, options = {}) {\n const shouldDebug = DEBUG || options.debug;\n const action = options.action || null;\n const url = page.url();\n\n const result = await resolveLocator(page, query, options);\n if (!result.found) throw new Error(`Could not find element: ${query}. ${result.error || ''}`);\n\n const locator = createPlaywrightLocator(page, result.locatorString, result.isInFrame, result.frameSelector);\n\n if (result.source === 'disk') {\n const valid = await validateLocator(locator);\n if (valid) {\n bumpHitCount(url, query, action);\n return { locator, result };\n }\n\n if (shouldDebug) console.log(`[Stale Cache] \"${query}\" \u2192 ${result.locatorString} no longer valid, re-querying LLM...`);\n invalidateDiskEntry(url, query, action);\n deleteMemEntry(url, query, action);\n clearStructureCache();\n\n const freshResult = await resolveLocator(page, query, options);\n if (!freshResult.found) throw new Error(`Could not find element after retry: ${query}. ${freshResult.error || ''}`);\n\n const freshLocator = createPlaywrightLocator(page, freshResult.locatorString, freshResult.isInFrame, freshResult.frameSelector);\n return { locator: freshLocator, result: freshResult };\n }\n\n return { locator, result };\n}\n\nasync function resolveLocatorsBatch(page, queries, options = {}) {\n const shouldDebug = DEBUG || options.debug;\n const url = page.url();\n const results = new Map();\n const uncached = [];\n\n for (const q of queries) {\n const memHit = getMemEntry(url, q, null);\n if (memHit) { results.set(q, memHit); continue; }\n const diskHit = getDiskEntry(url, q, null);\n if (diskHit) {\n const r = {\n found: true, strategy: diskHit.strategy, locatorString: diskHit.locatorString,\n isInFrame: diskHit.isInFrame || false, frameSelector: diskHit.frameSelector || null,\n confidence: diskHit.confidence, reasoning: diskHit.reasoning, source: 'disk'\n };\n setMemEntry(url, q, null, r);\n results.set(q, r);\n } else {\n uncached.push(q);\n }\n }\n\n if (uncached.length === 0) return results;\n\n if (shouldDebug) console.log(`[Batch] Resolving ${uncached.length} queries in 1 call`);\n const t0 = Date.now();\n\n const pageStructure = await getPageStructure(page);\n let payloadStr = buildPayload(pageStructure, uncached.join(' '));\n if (payloadStr.length > 20000) payloadStr = payloadStr.substring(0, 20000) + '\\n...(truncated)';\n\n try {\n const messages = buildBatchMessages(payloadStr, uncached);\n const raw = await chatCompletion(messages, options);\n const parsed = parseJsonResponse(raw);\n\n if (shouldDebug) console.log(`[Batch] ${parsed.length} results in ${Date.now() - t0}ms`);\n\n for (let i = 0; i < uncached.length && i < parsed.length; i++) {\n const p = parsed[i];\n const result = {\n found: p.confidence > 0.5,\n strategy: p.strategy,\n locatorString: p.locatorString,\n isInFrame: p.isInFrame || false,\n frameSelector: p.frameSelector || null,\n confidence: p.confidence,\n reasoning: p.reasoning,\n source: 'llm'\n };\n results.set(uncached[i], result);\n if (result.found) {\n setMemEntry(url, uncached[i], null, result);\n setDiskEntry(url, uncached[i], null, result);\n }\n }\n } catch (error) {\n console.error('Batch LLM error:', error.message);\n for (const q of uncached) {\n if (!results.has(q)) results.set(q, { found: false, confidence: 0, error: error.message });\n }\n }\n\n return results;\n}\n\nexport { resolveLocator, getLocator, resolveLocatorsBatch };", "const DEBUG = process.env.LLM_LOCATOR_DEBUG === 'true';\n\nclass SmartAction {\n #locator;\n #result;\n #query;\n\n constructor(locator, result, query) {\n this.#locator = locator;\n this.#result = result;\n this.#query = query;\n }\n\n get rawLocator() { return this.#locator; }\n get result() { return this.#result; }\n get query() { return this.#query; }\n\n async click(options) { return this.#locator.click(options); }\n async dblclick(options) { return this.#locator.dblclick(options); }\n async tap(options) { return this.#locator.tap(options); }\n async hover(options) { return this.#locator.hover(options); }\n async focus() { return this.#locator.focus(); }\n async blur() { return this.#locator.blur(); }\n\n async fill(value, options) { return this.#locator.fill(value, options); }\n async type(text, options) { return this.#locator.type(text, options); }\n async press(key, options) { return this.#locator.press(key, options); }\n async pressSequentially(text, options) { return this.#locator.pressSequentially(text, options); }\n async clear(options) { return this.#locator.clear(options); }\n async setInputFiles(files, options) { return this.#locator.setInputFiles(files, options); }\n async selectOption(values, options) { return this.#locator.selectOption(values, options); }\n async selectText(options) { return this.#locator.selectText(options); }\n\n async check(options) { return this.#locator.check(options); }\n async uncheck(options) { return this.#locator.uncheck(options); }\n async setChecked(checked, options) { return this.#locator.setChecked(checked, options); }\n\n async scrollIntoViewIfNeeded(options) { return this.#locator.scrollIntoViewIfNeeded(options); }\n async screenshot(options) { return this.#locator.screenshot(options); }\n\n async dragTo(target, options) {\n const dest = target instanceof SmartAction ? target.rawLocator : target;\n return this.#locator.dragTo(dest, options);\n }\n\n async waitFor(options) { return this.#locator.waitFor(options); }\n async waitForVisible(timeout = 30000) { return this.#locator.waitFor({ state: 'visible', timeout }); }\n async waitForHidden(timeout = 30000) { return this.#locator.waitFor({ state: 'hidden', timeout }); }\n async waitForAttached(timeout = 30000) { return this.#locator.waitFor({ state: 'attached', timeout }); }\n async waitForDetached(timeout = 30000) { return this.#locator.waitFor({ state: 'detached', timeout }); }\n\n async isVisible() { return this.#locator.isVisible(); }\n async isHidden() { return this.#locator.isHidden(); }\n async isEnabled() { return this.#locator.isEnabled(); }\n async isDisabled() { return this.#locator.isDisabled(); }\n async isChecked() { return this.#locator.isChecked(); }\n async isEditable() { return this.#locator.isEditable(); }\n\n async textContent() { return this.#locator.textContent(); }\n async innerText() { return this.#locator.innerText(); }\n async innerHTML() { return this.#locator.innerHTML(); }\n async inputValue(options) { return this.#locator.inputValue(options); }\n async getAttribute(name) { return this.#locator.getAttribute(name); }\n async boundingBox() { return this.#locator.boundingBox(); }\n async count() { return this.#locator.count(); }\n async allTextContents() { return this.#locator.allTextContents(); }\n async allInnerTexts() { return this.#locator.allInnerTexts(); }\n async all() { return this.#locator.all(); }\n\n async evaluate(pageFunction, arg) { return this.#locator.evaluate(pageFunction, arg); }\n async evaluateAll(pageFunction, arg) { return this.#locator.evaluateAll(pageFunction, arg); }\n async evaluateHandle(pageFunction, arg) { return this.#locator.evaluateHandle(pageFunction, arg); }\n\n first() { return this.#locator.first(); }\n last() { return this.#locator.last(); }\n nth(index) { return this.#locator.nth(index); }\n filter(options) { return this.#locator.filter(options); }\n getByRole(role, options) { return this.#locator.getByRole(role, options); }\n getByText(text, options) { return this.#locator.getByText(text, options); }\n getByLabel(text, options) { return this.#locator.getByLabel(text, options); }\n getByPlaceholder(text, options) { return this.#locator.getByPlaceholder(text, options); }\n getByTestId(testId) { return this.#locator.getByTestId(testId); }\n locator(selectorOrLocator, options) { return this.#locator.locator(selectorOrLocator, options); }\n\n async highlight() { return this.#locator.highlight(); }\n\n async exists() { return (await this.#locator.count()) > 0; }\n\n async getValue() {\n try { return await this.#locator.inputValue(); }\n catch { return await this.#locator.textContent(); }\n }\n\n async getClasses() {\n const cls = await this.#locator.getAttribute('class');\n return cls ? cls.split(/\\s+/).filter(Boolean) : [];\n }\n\n async hasClass(className) {\n return (await this.getClasses()).includes(className);\n }\n\n async getCssProperty(property) {\n return this.#locator.evaluate(\n (el, prop) => window.getComputedStyle(el).getPropertyValue(prop),\n property\n );\n }\n\n toString() {\n return `SmartAction(\"${this.#query}\" \u2192 ${this.#result?.locatorString || 'unknown'})`;\n }\n}\n\nexport { SmartAction };", "import { getLocator, resolveLocatorsBatch } from './resolver.js';\nimport { clearMemoryCache } from './cache/memory-cache.js';\nimport { clearDiskCache } from './cache/disk-cache.js';\nimport { SmartAction } from './actions.js';\n\nfunction clearCache() {\n clearMemoryCache();\n}\n\nfunction clearAllCaches() {\n clearMemoryCache();\n clearDiskCache();\n}\n\nfunction createSmartLocator(page, options = {}) {\n const { verbose = false } = options;\n\n async function resolve(query, action) {\n const { locator, result } = await getLocator(page, query, { ...options, action });\n if (verbose) console.log(`[Smart Locator] ${action || 'locate'}(\"${query}\") \u2192 ${result.locatorString} (${result.source})`);\n return new SmartAction(locator, result, query);\n }\n\n return {\n async prefetch(...queries) {\n const t0 = Date.now();\n const results = await resolveLocatorsBatch(page, queries, options);\n if (verbose) console.log(`[Smart Locator] Prefetched ${results.size} locators in ${Date.now() - t0}ms`);\n return results;\n },\n\n async locate(query, action) {\n return resolve(query, action || null);\n },\n\n async click(query, clickOptions) {\n const el = await resolve(query, 'click');\n await el.click(clickOptions);\n return el;\n },\n\n async dblclick(query, clickOptions) {\n const el = await resolve(query, 'click');\n await el.dblclick(clickOptions);\n return el;\n },\n\n async fill(query, value, fillOptions) {\n const el = await resolve(query, 'fill');\n await el.fill(value, fillOptions);\n return el;\n },\n\n async type(query, text, typeOptions) {\n const el = await resolve(query, 'fill');\n await el.type(text, typeOptions);\n return el;\n },\n\n async pressSequentially(query, text, pressOptions) {\n const el = await resolve(query, 'fill');\n await el.pressSequentially(text, pressOptions);\n return el;\n },\n\n async clear(query) {\n const el = await resolve(query, 'fill');\n await el.clear();\n return el;\n },\n\n async press(query, key, pressOptions) {\n const el = await resolve(query, 'fill');\n await el.press(key, pressOptions);\n return el;\n },\n\n async check(query, checkOptions) {\n const el = await resolve(query, 'check');\n await el.check(checkOptions);\n return el;\n },\n\n async uncheck(query, uncheckOptions) {\n const el = await resolve(query, 'uncheck');\n await el.uncheck(uncheckOptions);\n return el;\n },\n\n async setChecked(query, checked, checkOptions) {\n const el = await resolve(query, checked ? 'check' : 'uncheck');\n await el.setChecked(checked, checkOptions);\n return el;\n },\n\n async select(query, values, selectOptions) {\n const el = await resolve(query, 'select');\n await el.selectOption(values, selectOptions);\n return el;\n },\n\n async hover(query, hoverOptions) {\n const el = await resolve(query, 'hover');\n await el.hover(hoverOptions);\n return el;\n },\n\n async focus(query) {\n const el = await resolve(query, 'click');\n await el.focus();\n return el;\n },\n\n async tap(query, tapOptions) {\n const el = await resolve(query, 'click');\n await el.tap(tapOptions);\n return el;\n },\n\n async setInputFiles(query, files, fileOptions) {\n const el = await resolve(query, 'fill');\n await el.setInputFiles(files, fileOptions);\n return el;\n },\n\n async dragTo(srcQuery, destQuery, dragOptions) {\n const src = await resolve(srcQuery, 'click');\n const dest = await resolve(destQuery, 'click');\n await src.dragTo(dest, dragOptions);\n return { source: src, target: dest };\n },\n\n async selectText(query) {\n const el = await resolve(query, 'click');\n await el.selectText();\n return el;\n },\n\n async scrollIntoView(query) {\n const el = await resolve(query, null);\n await el.scrollIntoViewIfNeeded();\n return el;\n },\n\n async screenshot(query, screenshotOptions) {\n const el = await resolve(query, null);\n return el.screenshot(screenshotOptions);\n },\n\n async highlight(query) {\n const el = await resolve(query, null);\n await el.highlight();\n return el;\n },\n\n async waitFor(query, waitOptions) {\n const el = await resolve(query, null);\n await el.waitFor(waitOptions);\n return el;\n },\n\n async waitForVisible(query, timeout) {\n const el = await resolve(query, null);\n await el.waitForVisible(timeout);\n return el;\n },\n\n async waitForHidden(query, timeout) {\n const el = await resolve(query, null);\n await el.waitForHidden(timeout);\n return el;\n },\n\n async waitForAttached(query, timeout) {\n const el = await resolve(query, null);\n await el.waitForAttached(timeout);\n return el;\n },\n\n async waitForDetached(query, timeout) {\n const el = await resolve(query, null);\n await el.waitForDetached(timeout);\n return el;\n },\n\n async isVisible(query) {\n try { const el = await resolve(query, null); return await el.isVisible(); }\n catch { return false; }\n },\n\n async isHidden(query) {\n try { const el = await resolve(query, null); return await el.isHidden(); }\n catch { return true; }\n },\n\n async isEnabled(query) {\n try { const el = await resolve(query, null); return await el.isEnabled(); }\n catch { return false; }\n },\n\n async isDisabled(query) {\n try { const el = await resolve(query, null); return await el.isDisabled(); }\n catch { return true; }\n },\n\n async isChecked(query) {\n try { const el = await resolve(query, null); return await el.isChecked(); }\n catch { return false; }\n },\n\n async isEditable(query) {\n try { const el = await resolve(query, null); return await el.isEditable(); }\n catch { return false; }\n },\n\n async exists(query) {\n try { const el = await resolve(query, null); return await el.exists(); }\n catch { return false; }\n },\n\n async getText(query) {\n const el = await resolve(query, 'getText');\n return el.textContent();\n },\n\n async getInnerText(query) {\n const el = await resolve(query, 'getText');\n return el.innerText();\n },\n\n async getInnerHTML(query) {\n const el = await resolve(query, 'getText');\n return el.innerHTML();\n },\n\n async getInputValue(query) {\n const el = await resolve(query, 'fill');\n return el.inputValue();\n },\n\n async getAttribute(query, attr) {\n const el = await resolve(query, null);\n return el.getAttribute(attr);\n },\n\n async getBoundingBox(query) {\n const el = await resolve(query, null);\n return el.boundingBox();\n },\n\n async count(query) {\n const el = await resolve(query, null);\n return el.count();\n },\n\n clearCache() { clearCache(); },\n clearAllCaches() { clearAllCaches(); }\n };\n}\n\nexport { createSmartLocator, clearCache, clearAllCaches };", "export { getLocator, resolveLocator } from './resolver.js';\nexport { createSmartLocator, clearCache, clearAllCaches } from './smart-locator.js';\nexport { getPageStructure } from './page-structure.js';\nexport { loadDiskCache, invalidateDiskEntry } from './cache/disk-cache.js';\nexport { chatCompletion, getConfig } from './llm/client.js';\nexport { SmartAction } from './actions.js';\nimport { getLocator } from './resolver.js';\n\nasync function findLocator(page, query, options = {}) {\n try {\n const { result } = await getLocator(page, query, options);\n return {\n found: true, strategy: result.strategy, locatorString: result.locatorString,\n locatorType: result.strategy, confidence: result.confidence,\n fullLocatorString: result.locatorString, reasoning: result.reasoning,\n isInFrame: result.isInFrame, frameSelector: result.frameSelector,\n fallbackLocators: result.fallbackLocators || [], element: { strategy: result.strategy }\n };\n } catch (e) {\n return { found: false, locatorString: null, confidence: 0, error: e.message };\n }\n}\n\nasync function findAllMatches(page, query, options = {}) {\n try {\n const { result } = await getLocator(page, query, options);\n return result.found ? [result] : [];\n } catch { return []; }\n}\n\nexport { findLocator, findAllMatches };"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["OpenAI", "DEBUG", "path", "fs", "DEBUG", "DEBUG", "DEBUG"]
|
|
7
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for playwright-nlp-locator
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Page, Locator } from 'playwright';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Configuration options for NLP Locator
|
|
9
|
+
*/
|
|
10
|
+
export interface NLPLocatorConfig {
|
|
11
|
+
/** Maximum number of elements to include in context (default: 100) */
|
|
12
|
+
maxElements?: number;
|
|
13
|
+
/** Order of preference for locator types */
|
|
14
|
+
preferredLocatorOrder?: ('role' | 'text' | 'testId' | 'css' | 'xpath')[];
|
|
15
|
+
/** Whether to include hidden elements in analysis (default: false) */
|
|
16
|
+
includeHiddenElements?: boolean;
|
|
17
|
+
/** Minimum confidence threshold for accepting a match (default: 0.5) */
|
|
18
|
+
confidenceThreshold?: number;
|
|
19
|
+
/** LLM model to use (default: 'claude-3-5-sonnet') */
|
|
20
|
+
model?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Locator type returned by the library
|
|
25
|
+
*/
|
|
26
|
+
export type LocatorType = 'role' | 'text' | 'testId' | 'css' | 'xpath' | 'label' | 'placeholder' | 'alternative';
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Alternative locator suggestion
|
|
30
|
+
*/
|
|
31
|
+
export interface AlternativeLocator {
|
|
32
|
+
/** The locator string */
|
|
33
|
+
locator: string;
|
|
34
|
+
/** Confidence score (0-1) */
|
|
35
|
+
confidence: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Result from findLocator function
|
|
40
|
+
*/
|
|
41
|
+
export interface FindLocatorResult {
|
|
42
|
+
/** Whether an element was found */
|
|
43
|
+
found: boolean;
|
|
44
|
+
/** The Playwright locator string */
|
|
45
|
+
locator: string | null;
|
|
46
|
+
/** Type of locator returned */
|
|
47
|
+
locatorType?: LocatorType;
|
|
48
|
+
/** Confidence score (0-1) */
|
|
49
|
+
confidence: number;
|
|
50
|
+
/** Explanation of why this element matches */
|
|
51
|
+
explanation?: string;
|
|
52
|
+
/** Alternative locator suggestions */
|
|
53
|
+
alternatives?: AlternativeLocator[];
|
|
54
|
+
/** Index of matched element in the DOM elements array */
|
|
55
|
+
elementIndex?: number;
|
|
56
|
+
/** Error message if not found */
|
|
57
|
+
error?: string;
|
|
58
|
+
/** Warning message (e.g., low confidence) */
|
|
59
|
+
warning?: string;
|
|
60
|
+
/** Raw LLM response (for debugging) */
|
|
61
|
+
rawResponse?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Result from getLocator function
|
|
66
|
+
*/
|
|
67
|
+
export interface GetLocatorResult {
|
|
68
|
+
/** Playwright Locator object ready for interaction */
|
|
69
|
+
locator: Locator;
|
|
70
|
+
/** Full result from findLocator */
|
|
71
|
+
result: FindLocatorResult;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Match result for findAllLocators
|
|
76
|
+
*/
|
|
77
|
+
export interface LocatorMatch {
|
|
78
|
+
/** The locator string */
|
|
79
|
+
locator: string;
|
|
80
|
+
/** Confidence score (0-1) */
|
|
81
|
+
confidence: number;
|
|
82
|
+
/** Type of locator */
|
|
83
|
+
type: LocatorType;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* DOM element information extracted from the page
|
|
88
|
+
*/
|
|
89
|
+
export interface DOMElementInfo {
|
|
90
|
+
index: number;
|
|
91
|
+
tagName: string;
|
|
92
|
+
role: string;
|
|
93
|
+
ariaLabel: string | null;
|
|
94
|
+
ariaLabelledBy: string | null;
|
|
95
|
+
text: string;
|
|
96
|
+
value: string | null;
|
|
97
|
+
placeholder: string | null;
|
|
98
|
+
name: string | null;
|
|
99
|
+
id: string | null;
|
|
100
|
+
className: string | null;
|
|
101
|
+
type: string | null;
|
|
102
|
+
href: string | null;
|
|
103
|
+
title: string | null;
|
|
104
|
+
alt: string | null;
|
|
105
|
+
testId: string | null;
|
|
106
|
+
cssSelector: string;
|
|
107
|
+
isVisible: boolean;
|
|
108
|
+
position: {
|
|
109
|
+
x: number;
|
|
110
|
+
y: number;
|
|
111
|
+
width: number;
|
|
112
|
+
height: number;
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* NLP Helper interface for natural language automation
|
|
118
|
+
*/
|
|
119
|
+
export interface NLPHelper {
|
|
120
|
+
/**
|
|
121
|
+
* Click an element using natural language description
|
|
122
|
+
* @param description - Natural language description of the element
|
|
123
|
+
* @param clickOptions - Optional Playwright click options
|
|
124
|
+
* @returns The locator that was clicked
|
|
125
|
+
*/
|
|
126
|
+
click(description: string, clickOptions?: object): Promise<Locator>;
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Type into an element using natural language description
|
|
130
|
+
* @param description - Natural language description of the element
|
|
131
|
+
* @param text - Text to type
|
|
132
|
+
* @param typeOptions - Optional Playwright fill options
|
|
133
|
+
* @returns The locator that was typed into
|
|
134
|
+
*/
|
|
135
|
+
type(description: string, text: string, typeOptions?: object): Promise<Locator>;
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Get text from an element using natural language description
|
|
139
|
+
* @param description - Natural language description of the element
|
|
140
|
+
* @returns Text content of the element
|
|
141
|
+
*/
|
|
142
|
+
getText(description: string): Promise<string | null>;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Check if element exists using natural language description
|
|
146
|
+
* @param description - Natural language description of the element
|
|
147
|
+
* @returns Whether the element exists
|
|
148
|
+
*/
|
|
149
|
+
exists(description: string): Promise<boolean>;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Wait for element using natural language description
|
|
153
|
+
* @param description - Natural language description of the element
|
|
154
|
+
* @param waitOptions - Optional Playwright wait options
|
|
155
|
+
* @returns The locator when visible
|
|
156
|
+
*/
|
|
157
|
+
waitFor(description: string, waitOptions?: object): Promise<Locator>;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Hover over element using natural language description
|
|
161
|
+
* @param description - Natural language description of the element
|
|
162
|
+
* @returns The locator that was hovered
|
|
163
|
+
*/
|
|
164
|
+
hover(description: string): Promise<Locator>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Select option using natural language description
|
|
168
|
+
* @param description - Natural language description of the element
|
|
169
|
+
* @param value - Value to select
|
|
170
|
+
* @returns The locator that was selected
|
|
171
|
+
*/
|
|
172
|
+
select(description: string, value: string | string[]): Promise<Locator>;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the locator for an element using natural language
|
|
176
|
+
* @param description - Natural language description of the element
|
|
177
|
+
* @returns Object containing the locator and full result
|
|
178
|
+
*/
|
|
179
|
+
find(description: string): Promise<GetLocatorResult>;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Find a Playwright locator using natural language description
|
|
184
|
+
* @param page - Playwright page object
|
|
185
|
+
* @param description - Natural language description of the element
|
|
186
|
+
* @param options - Optional configuration
|
|
187
|
+
* @returns Result containing the locator string and confidence score
|
|
188
|
+
*/
|
|
189
|
+
export function findLocator(
|
|
190
|
+
page: Page,
|
|
191
|
+
description: string,
|
|
192
|
+
options?: NLPLocatorConfig
|
|
193
|
+
): Promise<FindLocatorResult>;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Find and return a Playwright Locator object ready for interaction
|
|
197
|
+
* @param page - Playwright page object
|
|
198
|
+
* @param description - Natural language description of the element
|
|
199
|
+
* @param options - Optional configuration
|
|
200
|
+
* @returns Object containing the Playwright Locator and full result
|
|
201
|
+
*/
|
|
202
|
+
export function getLocator(
|
|
203
|
+
page: Page,
|
|
204
|
+
description: string,
|
|
205
|
+
options?: NLPLocatorConfig
|
|
206
|
+
): Promise<GetLocatorResult>;
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Find multiple matching elements for a description
|
|
210
|
+
* @param page - Playwright page object
|
|
211
|
+
* @param description - Natural language description of the element
|
|
212
|
+
* @param options - Optional configuration
|
|
213
|
+
* @returns Array of matching locators with confidence scores
|
|
214
|
+
*/
|
|
215
|
+
export function findAllLocators(
|
|
216
|
+
page: Page,
|
|
217
|
+
description: string,
|
|
218
|
+
options?: NLPLocatorConfig
|
|
219
|
+
): Promise<LocatorMatch[]>;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Create a natural language automation helper
|
|
223
|
+
* @param page - Playwright page object
|
|
224
|
+
* @param options - Optional configuration
|
|
225
|
+
* @returns Helper object with natural language methods
|
|
226
|
+
*/
|
|
227
|
+
export function createNLPHelper(
|
|
228
|
+
page: Page,
|
|
229
|
+
options?: NLPLocatorConfig
|
|
230
|
+
): NLPHelper;
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Extract DOM elements with relevant attributes
|
|
234
|
+
* @param page - Playwright page object
|
|
235
|
+
* @param config - Optional configuration
|
|
236
|
+
* @returns Array of element information
|
|
237
|
+
*/
|
|
238
|
+
export function extractDOMElements(
|
|
239
|
+
page: Page,
|
|
240
|
+
config?: NLPLocatorConfig
|
|
241
|
+
): Promise<DOMElementInfo[]>;
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Extract accessibility tree information from the page
|
|
245
|
+
* @param page - Playwright page object
|
|
246
|
+
* @returns Accessibility tree snapshot
|
|
247
|
+
*/
|
|
248
|
+
export function getAccessibilityTree(page: Page): Promise<object | null>;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Default configuration values
|
|
252
|
+
*/
|
|
253
|
+
export const DEFAULT_CONFIG: Required<NLPLocatorConfig>;
|