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/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": ["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": ["DEBUG", "DEBUG", "DEBUG", "DEBUG"]
|
|
7
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "playwright-genie",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Find and interact with Playwright elements using natural language descriptions powered by LLM",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.cjs",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "node scripts/build.js",
|
|
23
|
+
"prepublishOnly": "npm run build",
|
|
24
|
+
"test": "playwright test",
|
|
25
|
+
"test:llm": "playwright test tests/llm-locator.spec.js --headed"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"playwright",
|
|
29
|
+
"locator",
|
|
30
|
+
"genie",
|
|
31
|
+
"nlp",
|
|
32
|
+
"natural-language",
|
|
33
|
+
"testing",
|
|
34
|
+
"automation",
|
|
35
|
+
"llm",
|
|
36
|
+
"ai",
|
|
37
|
+
"e2e"
|
|
38
|
+
],
|
|
39
|
+
"author": "Your Name",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/yourname/playwright-genie.git"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/yourname/playwright-genie#readme",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/yourname/playwright-genie/issues"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@playwright/test": ">=1.40.0",
|
|
51
|
+
"playwright": ">=1.40.0"
|
|
52
|
+
},
|
|
53
|
+
"peerDependenciesMeta": {
|
|
54
|
+
"@playwright/test": {
|
|
55
|
+
"optional": true
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"dotenv": "^17.3.1",
|
|
60
|
+
"openai": "^4.104.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@playwright/test": "^1.57.0",
|
|
64
|
+
"esbuild": "^0.25.12",
|
|
65
|
+
"playwright": "^1.57.0"
|
|
66
|
+
},
|
|
67
|
+
"engines": {
|
|
68
|
+
"node": ">=18.0.0"
|
|
69
|
+
}
|
|
70
|
+
}
|