@immense/vue-pom-generator 1.0.3

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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../method-generation.ts","../compiler/ast-guards.ts","../routing/to-directive.ts","../utils.ts","../router-introspection.ts","../class-generation/index.ts","../plugin/support/build-plugin.ts","../click-instrumentation.ts","../transform.ts","../plugin/support/dev-plugin.ts","../manifest-generator.ts","../plugin/support/virtual-modules.ts","../plugin/support-plugins.ts","../compiler-metadata-utils.ts","../compiler-wrapper.ts","../plugin/vue-plugin.ts","../plugin/logger.ts","../plugin/create-vue-pom-generator-plugins.ts"],"sourcesContent":["// Method content generation helpers.\n//\n// These are shared between transform-time codegen (building dependencies.methodsContent)\n// and class-generation tests. This module is intentionally dependency-free to avoid\n// circular imports between `utils` and `class-generation`.\n\nconst INDENT = \" \";\nconst INDENT2 = `${INDENT}${INDENT}`;\nconst INDENT3 = `${INDENT2}${INDENT}`;\n\nfunction upperFirst(value: string): string {\n if (!value) {\n return value;\n }\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nfunction hasParam(params: Record<string, string>, name: string) {\n return Object.prototype.hasOwnProperty.call(params, name);\n}\n\nfunction formatParams(params: Record<string, string>) {\n const entries = Object.entries(params);\n if (!entries.length) {\n return \"\";\n }\n return entries.map(([n, t]) => `${n}: ${t}`).join(\", \");\n}\n\nfunction removeByKeySegment(value: string): string {\n const idx = value.lastIndexOf(\"ByKey\");\n if (idx < 0) {\n return value;\n }\n return value.slice(0, idx) + value.slice(idx + \"ByKey\".length);\n}\n\nfunction uniqueAlternates(primary: string, alternates: string[] | undefined): string[] {\n const out: string[] = [];\n const seen = new Set<string>();\n seen.add(primary);\n for (const a of alternates ?? []) {\n if (!a) {\n continue;\n }\n if (seen.has(a)) {\n continue;\n }\n seen.add(a);\n out.push(a);\n }\n return out;\n}\n\nfunction testIdExpression(formattedDataTestId: string): string {\n return formattedDataTestId.includes(\"${\") ? `\\`${formattedDataTestId}\\`` : JSON.stringify(formattedDataTestId);\n}\n\nfunction generateClickMethod(methodName: string, formattedDataTestId: string, alternateFormattedDataTestIds: string[] | undefined, params: Record<string, string>) {\n let content: string;\n const name = `click${methodName}`;\n const paramBlock = formatParams(params);\n const paramBlockWithWait = paramBlock ? `${paramBlock}, wait: boolean = true` : \"wait: boolean = true\";\n\n const alternates = uniqueAlternates(formattedDataTestId, alternateFormattedDataTestIds);\n if (alternates.length > 0) {\n const candidatesExpr = [formattedDataTestId, ...alternates].map(testIdExpression).join(\", \");\n const waitSignature = hasParam(params, \"key\") ? paramBlockWithWait : \"wait: boolean = true\";\n const waitArg = \"wait\";\n\n content = `${INDENT}async ${name}(${waitSignature}) {\\n`\n + `${INDENT2}const candidates = [${candidatesExpr}] as const;\\n`\n + `${INDENT2}let lastError: unknown;\\n`\n + `${INDENT2}for (const testId of candidates) {\\n`\n + `${INDENT3}const locator = this.locatorByTestId(testId);\\n`\n + `${INDENT3}try {\\n`\n + `${INDENT3}${INDENT}if (await locator.count()) {\\n`\n + `${INDENT3}${INDENT2}await this.clickLocator(locator, \"\", ${waitArg});\\n`\n + `${INDENT3}${INDENT2}return;\\n`\n + `${INDENT3}${INDENT}}\\n`\n + `${INDENT3}} catch (e) {\\n`\n + `${INDENT3}${INDENT}lastError = e;\\n`\n + `${INDENT3}}\\n`\n + `${INDENT2}}\\n`\n + `${INDENT2}throw (lastError instanceof Error) ? lastError : new Error(\"[pom] Failed to click any candidate locator for ${name}.\");\\n`\n + `${INDENT}}\\n`;\n return content;\n }\n\n if (hasParam(params, \"key\")) {\n content = `${INDENT}async ${name}(${paramBlockWithWait}) {\\n`\n + `${INDENT2}await this.clickByTestId(\\`${formattedDataTestId}\\`, \"\", wait);\\n`\n + `${INDENT}}\\n`;\n }\n else {\n content = `${INDENT}async ${name}(wait: boolean = true) {\\n`\n + `${INDENT2}await this.clickByTestId(\"${formattedDataTestId}\", \"\", wait);\\n`\n + `${INDENT}}\\n`;\n }\n return content;\n}\n\nfunction generateRadioMethod(methodName: string, formattedDataTestId: string) {\n const name = `select${methodName}`;\n const hasKey = formattedDataTestId.includes(\"${key}\");\n if (hasKey) {\n return `${INDENT}async ${name}(key: string, annotationText: string = \"\") {\\n`\n + `${INDENT2}await this.clickByTestId(\\`${formattedDataTestId}\\`, annotationText);\\n`\n + `${INDENT}}\\n`;\n }\n return `${INDENT}async ${name}(annotationText: string = \"\") {\\n`\n + `${INDENT2}await this.clickByTestId(\"${formattedDataTestId}\", annotationText);\\n`\n + `${INDENT}}\\n`;\n}\n\nfunction generateSelectMethod(methodName: string, formattedDataTestId: string) {\n const name = `select${methodName}`;\n const needsKey = formattedDataTestId.includes(\"${key}\");\n const selectorExpr = needsKey\n ? `this.selectorForTestId(\\`${formattedDataTestId}\\`)`\n : `this.selectorForTestId(\"${formattedDataTestId}\")`;\n\n const content: string = `${INDENT}async ${name}(value: string, annotationText: string = \"\") {\\n`\n + `${INDENT2}const selector = ${selectorExpr};\\n`\n + `${INDENT2}await this.animateCursorToElement(selector, false, 500, annotationText);\\n`\n + `${INDENT2}await this.page.selectOption(selector, value);\\n`\n + `${INDENT}}\\n\\n`;\n return content;\n}\n\nfunction generateVSelectMethod(methodName: string, formattedDataTestId: string) {\n const name = `select${methodName}`;\n const content = [\n `${INDENT}async ${name}(value: string, timeOut = 500, annotationText: string = \"\") {\\n`,\n `${INDENT2}await this.selectVSelectByTestId(\"${formattedDataTestId}\", value, timeOut, annotationText);\\n`,\n `${INDENT}}\\n`,\n ].join(\"\");\n return content;\n}\n\nfunction generateTypeMethod(methodName: string, formattedDataTestId: string) {\n const name = `type${methodName}`;\n const content: string = `${INDENT}async ${name}(text: string, annotationText: string = \"\") {\\n`\n + `${INDENT2}await this.fillInputByTestId(\"${formattedDataTestId}\", text, annotationText);\\n`\n + `${INDENT}}\\n`;\n return content;\n}\n\nfunction generateGetElementByDataTestId(\n methodName: string,\n nativeRole: string,\n formattedDataTestId: string,\n alternateFormattedDataTestIds: string[] | undefined,\n getterNameOverride: string | undefined,\n params: Record<string, string>,\n) {\n // Avoid duplicate accessors when the same base name exists for different roles.\n // Example: \"PackageHash\" can exist as both \"-input\" and \"-button\".\n const roleSuffix = upperFirst(nativeRole || \"Element\");\n const baseName = upperFirst(methodName);\n const hasRoleSuffix = baseName.endsWith(roleSuffix) || new RegExp(`^${roleSuffix}\\\\d+$`).test(baseName);\n const propertyName = hasRoleSuffix ? `${baseName}` : `${baseName}${roleSuffix}`;\n const needsKey = hasParam(params, \"key\") || formattedDataTestId.includes(\"${key}\");\n\n if (needsKey) {\n const keyType = params.key || \"string\";\n // For keyed getters, expose an indexable property (Proxy) so callers can do:\n // expect(pom.SaveButton[myKey]).toBeVisible();\n // When method names include the \"ByKey\" segment, we remove it in the exposed property\n // name so `FooByKeyButton` becomes `FooButton[key]`.\n const keyedPropertyName = getterNameOverride ?? removeByKeySegment(propertyName);\n return `${INDENT}get ${keyedPropertyName}() {\\n`\n + `${INDENT2}return this.keyedLocators((key: ${keyType}) => this.locatorByTestId(\\`${formattedDataTestId}\\`));\\n`\n + `${INDENT}}\\n\\n`;\n }\n\n const finalPropertyName = getterNameOverride ?? propertyName;\n\n const alternates = uniqueAlternates(formattedDataTestId, alternateFormattedDataTestIds);\n if (alternates.length > 0) {\n const all = [formattedDataTestId, ...alternates];\n const locatorExpr = all\n .map((id) => `this.locatorByTestId(${testIdExpression(id)})`)\n .reduce((acc, next) => `${acc}.or(${next})`);\n\n return `${INDENT}get ${finalPropertyName}() {\\n`\n + `${INDENT2}return ${locatorExpr};\\n`\n + `${INDENT}}\\n\\n`;\n }\n\n return `${INDENT}get ${finalPropertyName}() {\\n`\n + `${INDENT2}return this.locatorByTestId(\"${formattedDataTestId}\");\\n`\n + `${INDENT}}\\n\\n`;\n}\n\nfunction generateNavigationMethod(args: {\n targetPageObjectModelClass: string;\n /** Method name derived from data-testid parts (already PascalCase). */\n baseMethodName: string;\n /** data-testid string (may include `${key}` placeholder). */\n formattedDataTestId: string;\n /** Alternative data-testid strings that represent the same navigation action. */\n alternateFormattedDataTestIds?: string[];\n /** Method param name->type dictionary (e.g. { key: \"string\" }). */\n params: Record<string, string>;\n}) {\n const { targetPageObjectModelClass: target, baseMethodName, formattedDataTestId, alternateFormattedDataTestIds, params } = args;\n\n // IMPORTANT:\n // Navigation method names must be derived from the element's semantic name (data-testid parts)\n // rather than only from the target page class. Multiple elements often navigate to the same\n // target (e.g. NewBranding + EditBranding -> BrandingDetailsPage). If we name methods by\n // target only, we emit duplicate implementations and vue-tsc fails.\n const methodName = baseMethodName\n ? `goTo${upperFirst(baseMethodName)}`\n : `goTo${target.endsWith(\"Page\") ? target.slice(0, -\"Page\".length) : target}`;\n\n const signature = `public ${methodName}(${formatParams(params)}): Fluent<${target}>`;\n const alternates = uniqueAlternates(formattedDataTestId, alternateFormattedDataTestIds);\n const candidatesExpr = [formattedDataTestId, ...alternates].map(testIdExpression).join(\", \");\n\n if (alternates.length > 0) {\n return `${INDENT}${signature} {\\n`\n + `${INDENT2}return this.fluent(async () => {\\n`\n + `${INDENT3}const candidates = [${candidatesExpr}] as const;\\n`\n + `${INDENT3}let lastError: unknown;\\n`\n + `${INDENT3}for (const testId of candidates) {\\n`\n + `${INDENT3}${INDENT}const locator = this.locatorByTestId(testId);\\n`\n + `${INDENT3}${INDENT}try {\\n`\n + `${INDENT3}${INDENT2}if (await locator.count()) {\\n`\n + `${INDENT3}${INDENT3}await this.clickLocator(locator);\\n`\n + `${INDENT3}${INDENT3}return new ${target}(this.page);\\n`\n + `${INDENT3}${INDENT2}}\\n`\n + `${INDENT3}${INDENT}} catch (e) {\\n`\n + `${INDENT3}${INDENT2}lastError = e;\\n`\n + `${INDENT3}${INDENT}}\\n`\n + `${INDENT3}}\\n`\n + `${INDENT3}throw (lastError instanceof Error) ? lastError : new Error(\"[pom] Failed to navigate using any candidate locator for ${methodName}.\");\\n`\n + `${INDENT2}});\\n`\n + `${INDENT}}\\n`;\n }\n\n const clickExpr = `\\`${formattedDataTestId}\\``;\n return `${INDENT}${signature} {\\n`\n + `${INDENT2}return this.fluent(async () => {\\n`\n + `${INDENT3}await this.clickByTestId(${clickExpr});\\n`\n + `${INDENT3}return new ${target}(this.page);\\n`\n + `${INDENT2}});\\n`\n + `${INDENT}}\\n`;\n}\n\nexport function generateViewObjectModelMethodContent(\n targetPageObjectModelClass: string | undefined,\n methodName: string,\n nativeRole: string,\n formattedDataTestId: string,\n alternateFormattedDataTestIds: string[] | undefined,\n getterNameOverride: string | undefined,\n params: Record<string, string>,\n) {\n const baseMethodName = (nativeRole === \"radio\")\n ? (methodName || \"Radio\")\n : methodName;\n\n const getElementMethod = generateGetElementByDataTestId(baseMethodName, nativeRole, formattedDataTestId, alternateFormattedDataTestIds, getterNameOverride, params);\n\n if (targetPageObjectModelClass) {\n return getElementMethod + generateNavigationMethod({\n targetPageObjectModelClass,\n baseMethodName,\n formattedDataTestId,\n alternateFormattedDataTestIds,\n params,\n });\n }\n\n if (nativeRole === \"select\") {\n return getElementMethod + generateSelectMethod(baseMethodName, formattedDataTestId);\n }\n if (nativeRole === \"vselect\") {\n return getElementMethod + generateVSelectMethod(baseMethodName, formattedDataTestId);\n }\n if (nativeRole === \"input\") {\n return getElementMethod + generateTypeMethod(baseMethodName, formattedDataTestId);\n }\n if (nativeRole === \"radio\") {\n return getElementMethod + generateRadioMethod(baseMethodName || \"Radio\", formattedDataTestId);\n }\n\n return getElementMethod + generateClickMethod(baseMethodName, formattedDataTestId, alternateFormattedDataTestIds, params);\n}\n","import type { SimpleExpressionNode } from \"@vue/compiler-core\";\nimport { NodeTypes } from \"@vue/compiler-core\";\n\n/**\n * Type guard for Vue compiler-core SimpleExpressionNode.\n *\n * We accept `object | null` (instead of `unknown`) to satisfy the repo lint rule\n * against `: unknown` annotations while still being safe at runtime.\n */\nexport function isSimpleExpressionNode(value: object | null): value is SimpleExpressionNode {\n return value !== null\n && \"type\" in value\n && (value as { type: number }).type === NodeTypes.SIMPLE_EXPRESSION;\n}\n","import type { DirectiveNode } from \"@vue/compiler-core\";\nimport { stringifyExpression } from \"@vue/compiler-core\";\nimport { parseExpression } from \"@babel/parser\";\n\ninterface RouteLocationLike {\n name?: string;\n path?: string;\n params?: Record<string, string | number>;\n}\n\ntype ResolveToComponentNameFn = (to: RouteLocationLike | string) => string | null;\n\nfunction toPascalCaseRouteKey(value: string): string {\n // Local, minimal PascalCase conversion for route names.\n // Avoids string.match/replace/split (restricted in this package).\n let out = \"\";\n let newWord = true;\n for (let i = 0; i < value.length; i++) {\n const ch = value[i];\n const code = ch.charCodeAt(0);\n\n const isDigit = code >= 48 && code <= 57;\n const isUpper = code >= 65 && code <= 90;\n const isLower = code >= 97 && code <= 122;\n const isAlphaNum = isDigit || isUpper || isLower;\n\n if (!isAlphaNum) {\n newWord = true;\n continue;\n }\n\n if (newWord) {\n out += isLower ? ch.toUpperCase() : ch;\n newWord = false;\n continue;\n }\n\n out += ch;\n }\n return out;\n}\n\n// Router-backed route name -> component name map.\n//\n// Populated once per Vite build by the plugin runtime (see `vite-plugins/vue-pom-generator/index.ts`).\n// The transform phase uses this to turn `:to` directives into POM return types.\nlet routeNameToComponentName: Map<string, string> | null = null;\nlet resolveToComponentName: ResolveToComponentNameFn | null = null;\n\nexport function setRouteNameToComponentNameMap(map: Map<string, string> | null) {\n routeNameToComponentName = map;\n}\n\nexport function setResolveToComponentNameFn(fn: ResolveToComponentNameFn | null) {\n resolveToComponentName = fn;\n}\n\nfunction buildPlaceholderParams(keys: string[]): Record<string, string> {\n const params: Record<string, string> = {};\n for (const k of keys)\n params[k] = \"__placeholder__\";\n return params;\n}\n\nfunction getRouteLocationLikeFromToDirective(toDirective: DirectiveNode): RouteLocationLike | string | null {\n if (!toDirective.exp)\n return null;\n\n // Parse the JS expression with Babel and extract supported shapes.\n const exp = toDirective.exp;\n const rawSource = stringifyExpression(exp).trim();\n\n let expr: object;\n try {\n expr = parseExpression(rawSource, { plugins: [\"typescript\"] });\n }\n catch {\n return null;\n }\n\n const isNodeType = (node: object | null, type: string): node is { type: string } => {\n return node !== null && (node as { type?: string }).type === type;\n };\n const isStringLiteralNode = (node: object | null): node is { type: \"StringLiteral\"; value: string } => {\n return isNodeType(node, \"StringLiteral\") && typeof (node as { value?: string }).value === \"string\";\n };\n const isIdentifierNode = (node: object | null): node is { type: \"Identifier\"; name: string } => {\n return isNodeType(node, \"Identifier\") && typeof (node as { name?: string }).name === \"string\";\n };\n const isObjectPropertyNode = (node: object | null): node is { type: \"ObjectProperty\"; key: object; value: object } => {\n if (!isNodeType(node, \"ObjectProperty\"))\n return false;\n const n = node as { key?: object; value?: object };\n return typeof n.key === \"object\" && n.key !== null && typeof n.value === \"object\" && n.value !== null;\n };\n const isObjectExpressionNode = (node: object | null): node is { type: \"ObjectExpression\"; properties: object[] } => {\n if (!isNodeType(node, \"ObjectExpression\"))\n return false;\n const n = node as { properties?: object[] };\n return Array.isArray(n.properties);\n };\n\n if (isStringLiteralNode(expr)) {\n // :to=\"'/some/path'\"\n return expr.value;\n }\n\n if (!isObjectExpressionNode(expr)) {\n return null;\n }\n\n const getStringField = (fieldName: \"name\" | \"path\") => {\n const prop = expr.properties.find((p) => {\n if (!isObjectPropertyNode(p))\n return false;\n const key = p.key as object;\n return (isIdentifierNode(key) && key.name === fieldName) || (isStringLiteralNode(key) && key.value === fieldName);\n });\n if (!prop || !isObjectPropertyNode(prop) || !isStringLiteralNode(prop.value as object))\n return null;\n return (prop.value as { value: string }).value;\n };\n\n const name = getStringField(\"name\");\n const path = getStringField(\"path\");\n\n const paramsProp = expr.properties.find((p) => {\n if (!isObjectPropertyNode(p))\n return false;\n const key = p.key as object;\n return (isIdentifierNode(key) && key.name === \"params\") || (isStringLiteralNode(key) && key.value === \"params\");\n });\n\n let params: Record<string, string> | undefined;\n if (paramsProp && isObjectPropertyNode(paramsProp) && isObjectExpressionNode(paramsProp.value as object)) {\n const keys: string[] = [];\n for (const prop of (paramsProp.value as { properties: object[] }).properties) {\n if (!isObjectPropertyNode(prop))\n continue;\n const key = prop.key as object;\n if (isIdentifierNode(key))\n keys.push(key.name);\n else if (isStringLiteralNode(key))\n keys.push(key.value);\n }\n if (keys.length) {\n params = buildPlaceholderParams(Array.from(new Set(keys)));\n }\n }\n\n if (name) {\n // Keep the router-facing name as-is (spaces etc). Normalization is only for codegen naming.\n return { name, params };\n }\n if (path) {\n return { path, params };\n }\n return null;\n}\n\nfunction toDirectiveObjectFieldNameValue(toDirective: DirectiveNode): string | null {\n const to = getRouteLocationLikeFromToDirective(toDirective);\n if (!to || typeof to === \"string\")\n return null;\n\n const name = to.name;\n if (typeof name !== \"string\")\n return null;\n\n const trimmed = name.trim();\n if (!trimmed.length)\n return null;\n\n return toPascalCaseRouteKey(trimmed);\n}\n\n/**\n * Attempts to extract a *stable* route name key from a `:to` directive.\n *\n * Supported (best-effort):\n * - :to=\"{ name: 'Tenant Details', params: { ... } }\"\n * - :to=\"someVar\" (cannot be resolved statically; returns null)\n */\nexport function getRouteNameKeyFromToDirective(toDirective: DirectiveNode): string | null {\n // Prefer object-literal `name: '...'` parsing.\n const objectName = toDirectiveObjectFieldNameValue(toDirective);\n if (objectName)\n return objectName;\n\n // If Vue provided an AST, we can sometimes detect { name: '...' } without regex.\n // Currently we keep this conservative: if it isn't a literal object with name, return null.\n return null;\n}\n\n/**\n * Given a `:to` directive, try to resolve the target view/page component name.\n *\n * Returns the Vue component identifier (e.g. `TenantDetailsPage`) when available.\n */\nexport function tryResolveToDirectiveTargetComponentName(toDirective: DirectiveNode): string | null {\n // Prefer router.resolve (more accurate; can handle path or name + placeholder params).\n const to = getRouteLocationLikeFromToDirective(toDirective);\n if (to && resolveToComponentName) {\n const resolved = resolveToComponentName(to);\n if (resolved)\n return resolved;\n }\n\n // Fallback: route name -> component map (best-effort)\n const key = getRouteNameKeyFromToDirective(toDirective);\n if (!key || !routeNameToComponentName)\n return null;\n\n return routeNameToComponentName.get(key) ?? null;\n}\n","import type {\n AttributeNode,\n CompoundExpressionNode,\n DirectiveNode,\n ElementNode,\n SimpleExpressionNode,\n TextNode,\n TransformContext,\n} from \"@vue/compiler-core\";\nimport {\n createSimpleExpression,\n ConstantTypes,\n NodeTypes,\n stringifyExpression,\n} from \"@vue/compiler-core\";\nimport type {\n ArrayExpression,\n File,\n MemberExpression,\n Node as BabelNode,\n OptionalMemberExpression,\n Program,\n TemplateLiteral,\n ObjectExpression,\n ObjectProperty\n} from \"@babel/types\";\nimport {\n VISITOR_KEYS,\n isArrayExpression,\n isArrowFunctionExpression,\n isAssignmentExpression,\n isBlockStatement,\n isCallExpression,\n isConditionalExpression,\n isExpressionStatement,\n isFile,\n isIdentifier,\n isLogicalExpression,\n isMemberExpression,\n isObjectExpression,\n isObjectProperty,\n isOptionalCallExpression,\n isOptionalMemberExpression,\n isProgram,\n isSequenceExpression,\n isStringLiteral,\n isTemplateLiteral,\n} from \"@babel/types\";\nimport { parse, parseExpression } from \"@babel/parser\";\n\nexport { isSimpleExpressionNode } from \"./compiler/ast-guards\";\nexport {\n getRouteNameKeyFromToDirective,\n setResolveToComponentNameFn,\n setRouteNameToComponentNameMap,\n tryResolveToDirectiveTargetComponentName,\n} from \"./routing/to-directive\";\n\nfunction getDataTestIdFromGroupOption(text: string) {\n // eslint-disable-next-line no-restricted-syntax\n return text.replace(/[-_]/g, \" \").split(\" \").filter(a => a).map((str: string) => {\n if (str.length > 1) {\n return str[0].toUpperCase() + str.slice(1);\n }\n return str.toUpperCase();\n }).join(\"\");\n};\n\nexport function upperFirst(value: string): string {\n if (!value) {\n return value;\n }\n return value.charAt(0).toUpperCase() + value.slice(1);\n}\n\nexport type NativeRole = 'button' | 'input' | 'select' | 'vselect' | 'checkbox' | 'toggle' | 'radio'\n// In this plugin, the hierarchy map stores: key = child element, value = parent element (or null for root).\nexport type Child = ElementNode;\nexport type Parent = ElementNode | null;\nexport type HierarchyMap = Map<Child, Parent>\nexport interface NativeWrappersMap {\n [component: string]: {\n role: NativeRole\n valueAttribute?: string\n requiresOptionDataTestIdPrefix?: boolean\n }\n}\n\nexport type AttributeValue =\n | { kind: \"static\"; value: string }\n | { kind: \"template\"; template: string };\n\nexport function staticAttributeValue(value: string): AttributeValue {\n return { kind: \"static\", value };\n}\n\nexport function templateAttributeValue(template: string): AttributeValue {\n return { kind: \"template\", template };\n}\n\nexport function getAttributeValueText(value: AttributeValue): string {\n return value.kind === \"static\" ? value.value : value.template;\n}\n\n/**\n * Converts a string to PascalCase.\n *\n * This is used for generating method/class names, so it is resilient to punctuation\n * and common template remnants.\n */\nexport function toPascalCase(str: string): string {\n // Normalize to identifier-ish tokens. This is used for generating method names,\n // so we need to be resilient to punctuation such as \"?\", \"[0]\", \"${...}\" remnants, etc.\n // eslint-disable-next-line no-restricted-syntax\n const cleaned = (str ?? \"\")\n // eslint-disable-next-line no-restricted-syntax\n .replace(/\\$\\{[^}]*\\}/g, \" \")\n // eslint-disable-next-line no-restricted-syntax\n .replace(/[^a-z0-9]+/gi, \" \")\n .trim();\n\n if (!cleaned) {\n return \"\";\n }\n\n // eslint-disable-next-line no-restricted-syntax\n return cleaned\n // eslint-disable-next-line no-restricted-syntax\n .split(/\\s+/)\n .filter(Boolean)\n .map((word) => {\n // If the token already appears to be camelCase/PascalCase (e.g. NewBranding),\n // preserve its internal capitalization rather than forcing the tail to lowercase.\n // This keeps generated identifiers closer to the source intent.\n // eslint-disable-next-line no-restricted-syntax\n const preserveInternalCaps = /[a-z][A-Z]/.test(word);\n return preserveInternalCaps\n ? upperFirst(word)\n : upperFirst(word.toLowerCase());\n })\n .join(\"\");\n}\n\n\n/**\n * Finds a regular attribute by key name (non-directive)\n * Equivalent to findAttributeByKey in utils\n */\nfunction findAttributeByKey(node: ElementNode, keyName: string): AttributeNode | undefined {\n return node.props.find((attr): attr is AttributeNode => {\n return attr.type === NodeTypes.ATTRIBUTE && attr.name === keyName;\n });\n}\n\n/**\n * Finds a directive by name and optional argument\n * e.g., findDirectiveByName(element, \"bind\", \"key\") finds :key\n */\nfunction findDirectiveByName(node: ElementNode, directiveName: string, argumentName?: string): DirectiveNode | undefined {\n return node.props.find((attr): attr is DirectiveNode => {\n if (attr.type !== NodeTypes.DIRECTIVE) {\n return false;\n }\n const directive = attr as DirectiveNode;\n const matchesDirective = directive.name === directiveName;\n\n if (argumentName) {\n return matchesDirective\n && directive.arg?.type === NodeTypes.SIMPLE_EXPRESSION\n && (directive.arg as SimpleExpressionNode).content === argumentName;\n }\n return matchesDirective;\n }) as DirectiveNode | undefined;\n}\n\n/**\n * Checks if a prop/attribute is a @click directive\n *\n * @internal\n */\nfunction isClickDirective(prop: AttributeNode | DirectiveNode): boolean {\n if (prop.type !== NodeTypes.DIRECTIVE) {\n return false;\n }\n\n const directive = prop as DirectiveNode;\n return directive.name === \"on\"\n && directive.arg?.type === NodeTypes.SIMPLE_EXPRESSION\n && (directive.arg as SimpleExpressionNode).content === \"click\";\n}\n\n/**\n * Returns the @click / v-on:click directive if present.\n *\n * Prefer this over re-scanning node.props in multiple places.\n */\nexport function tryGetClickDirective(node: ElementNode): DirectiveNode | undefined {\n return node.props.find((p): p is DirectiveNode => isClickDirective(p as AttributeNode | DirectiveNode)) as DirectiveNode | undefined;\n}\n\n/**\n * Checks if a node has an @click or v-on:click directive\n * Helper function that uses isClickDirective\n *\n * @internal\n */\nexport function nodeHasClickDirective(node: ElementNode): boolean {\n return tryGetClickDirective(node) !== undefined;\n}\n\n/**\n * Checks if a node is a <template> element with slot scope data\n *\n * This detects template elements with v-slot directives that have parameters,\n * such as <template #item=\"{ data }\"> or <template v-slot=\"item\">\n *\n * Returns true if the template has a slot scope with at least one parameter\n *\n * @internal\n */\nfunction isTemplateWithData(node: ElementNode): boolean {\n if (node.tag !== \"template\") {\n return false;\n }\n\n return node.props.some((prop) => {\n if (prop.type !== NodeTypes.DIRECTIVE) {\n return false;\n }\n\n const directive = prop as DirectiveNode;\n\n // Check for v-slot directive (name === \"slot\")\n // The Vue compiler normalizes both v-slot and # syntax to name: \"slot\"\n if (directive.name !== \"slot\") {\n return false;\n }\n\n // Check if the directive has an expression (the slot scope parameters)\n // COMPOUND_EXPRESSION: destructuring like { data } or complex expressions\n // SIMPLE_EXPRESSION: simple identifiers like \"item\"\n return (\n directive.exp !== undefined &&\n (directive.exp.type === NodeTypes.SIMPLE_EXPRESSION ||\n directive.exp.type === NodeTypes.COMPOUND_EXPRESSION)\n );\n });\n}\n\n/**\n * Checks if node has a :to directive (for router links)\n *\n * Returns the directive if found, undefined otherwise\n *\n * @internal\n */\nexport function nodeHasToDirective(node: ElementNode): DirectiveNode | undefined {\n const toDirective = findDirectiveByName(node, \"bind\", \"to\");\n\n // Check if the directive has an expression\n if (toDirective?.exp) {\n return toDirective;\n }\n\n return undefined;\n}\n\n/**\n * Checks if node has a v-for directive\n *\n * @internal\n */\nfunction nodeHasForDirective(node: ElementNode): boolean {\n return node.props.some(attr =>\n attr.type === NodeTypes.DIRECTIVE && (attr as DirectiveNode).name === \"for\",\n );\n}\n\n\n/**\n * Gets the :key directive from a node\n *\n * Returns the directive if found, null otherwise\n *\n * @internal\n */\nfunction getKeyDirective(node: ElementNode): DirectiveNode | null {\n return findDirectiveByName(node, \"bind\", \"key\") ?? null;\n}\n\n/**\n * Gets the value placeholder for a :key directive\n *\n * Returns a placeholder string if the element has a :key directive, null otherwise\n * This is used to indicate where a unique value should be interpolated\n *\n * @internal\n */\nexport function getKeyDirectiveValue(node: ElementNode, context: TransformContext | null = null): string | null {\n const keyDirective = getKeyDirective(node);\n let value = (keyDirective?.exp?.loc.source);\n if (value) {\n if (context) {\n value = stringifyExpression(keyDirective!.exp!);\n }\n return `\\${${value}}`;\n }\n return null;\n}\n\n/**\n * Gets both v-model and :model-value directive values in a single pass\n * Consolidates the previous getVModelDirectiveValue and getModelValueValue helpers\n *\n * @internal\n */\nfunction getModelBindingValues(node: ElementNode): { vModel: string; modelValue: string | null } {\n let vModel = \"\";\n const vModelDirective = findDirectiveByName(node, \"model\");\n\n if (vModelDirective?.exp?.loc.source) {\n vModel = toPascalCase(vModelDirective.exp.loc.source);\n }\n\n let modelValue: string | null = null;\n const modelValueDirective = findDirectiveByName(node, \"bind\", \"modelValue\");\n\n if (modelValueDirective?.exp?.ast) {\n const { name: mv } = getClickHandlerNameFromAst(modelValueDirective.exp.ast as BabelNode);\n modelValue = mv;\n }\n\n return { vModel, modelValue };\n}\n\n/**\n * Gets the key directive value for self-closing elements with v-for\n *\n * Returns the key placeholder if the element is self-closing and has v-for\n *\n * @internal\n */\nexport function getSelfClosingForDirectiveKeyAttrValue(node: ElementNode): string | null {\n // In Vue compiler AST, we check if isSelfClosing is true\n if (node.isSelfClosing) {\n const hasForDirective = nodeHasForDirective(node);\n\n if (hasForDirective) {\n return getKeyDirectiveValue(node);\n }\n }\n return null;\n}\n\n/**\n * Gets the id or name attribute value from a node\n *\n * Returns the identifier, converting dashes and underscores to PascalCase\n * Returns a placeholder if a dynamic :id is found\n *\n * @internal\n */\nexport function getIdOrName(node: ElementNode): string {\n // Get id or name attribute (static)\n let idAttr = findAttributeByKey(node, \"id\");\n if (!idAttr) {\n idAttr = findAttributeByKey(node, \"name\");\n }\n\n let identifier = idAttr?.value?.content ?? \"\";\n\n // If no static id or name attribute is found, check for a dynamic v-bind:id directive\n if (!identifier) {\n const dynamicIdAttr = findDirectiveByName(node, \"bind\", \"id\");\n if (dynamicIdAttr?.exp) {\n // TODO: Make sure this is still necessary and if so maybe pick a better name\n identifier = `\\${someUniqueValueToDifferentiateInstanceFromOthersOnPageUsuallyAnId}`;\n }\n }\n\n // Convert dashes and underscores to PascalCase\n if (identifier.includes(\"-\")) {\n // eslint-disable-next-line no-restricted-syntax\n identifier = identifier.split(\"-\").map(toPascalCase).join(\"\");\n }\n if (identifier.includes(\"_\")) {\n // eslint-disable-next-line no-restricted-syntax\n identifier = identifier.split(\"_\").map(toPascalCase).join(\"\");\n }\n\n return identifier;\n}\n\n// NOTE: insertBeforeLastUnderscore intentionally removed.\n// The only call site was simplified to conditionally interpolate the key directly into the testId.\n\n/**\n * Checks if a node is contained within a template element that has slot scope data\n *\n * Walks up the parent chain looking for a <template> element with v-slot or #default\n * that includes slot scope variables.\n *\n * @internal\n */\nexport function isNodeContainedInTemplateWithData(node: ElementNode, hierarchyMap: HierarchyMap): boolean {\n let parent = getParent(hierarchyMap, node);\n while (parent) {\n if (parent.type === NodeTypes.ELEMENT && parent.tag === \"template\") {\n if (isTemplateWithData(parent)) {\n return true;\n }\n }\n // Walk up the tree\n parent = getParent(hierarchyMap, parent);\n }\n return false;\n}\n\n/**\n * Extracts the key value expression from a v-for directive on a parent element\n *\n * If the node is within a v-for that has a :key directive, returns the key expression.\n *\n * @internal\n */\nexport function getContainedInVForDirectiveKeyValue(context: TransformContext, node: ElementNode, hierarchyMap: HierarchyMap): string | null {\n // Check if we're in a v-for scope\n if (!context.scopes.vFor || context.scopes.vFor === 0) {\n return null;\n }\n\n // Walk up to find the parent element with v-for\n let parent = getParent(hierarchyMap, node);\n while (parent) {\n if (parent.type === NodeTypes.ELEMENT) {\n const forDirective = findDirectiveByName(parent as ElementNode, \"for\");\n if (forDirective) {\n // Found the v-for element, now look for :key\n const keyValue = getKeyDirectiveValue(parent as ElementNode);\n return keyValue;\n }\n }\n parent = getParent(hierarchyMap, parent);\n }\n return null;\n}\n\n/**\n * If the current node is inside a v-for whose iterable is a static array literal,\n * returns the iterable's *string literal values*.\n *\n * Example:\n * - v-for=\"item in ['One', 'Two']\" => ['One', 'Two']\n */\nexport function tryGetContainedInStaticVForSourceLiteralValues(\n context: TransformContext,\n _node: ElementNode,\n _hierarchyMap: HierarchyMap,\n): string[] | null {\n // If we're not in v-for scope, don't waste time walking parents.\n if (!context.scopes.vFor || context.scopes.vFor === 0) {\n return null;\n }\n\n // In the Vue compiler AST, v-for is represented as a ForNode (NodeTypes.FOR)\n // whose `source` is the iterable expression.\n // When visiting the repeated element, its immediate parent is usually that ForNode.\n const parentObj = (context.parent && typeof context.parent === \"object\") ? context.parent as object : null;\n if (!parentObj || !(\"type\" in parentObj) || (parentObj as { type: number }).type !== NodeTypes.FOR) {\n // No direct ForNode parent; we don't currently attempt to walk further up.\n return null;\n }\n\n const sourceExp = (parentObj as { source?: object | null }).source;\n if (!sourceExp || typeof sourceExp !== \"object\") {\n return null;\n }\n\n // Mirror Vue compiler-core's own stability check (see `transformFor` in `vFor.ts`):\n // only a SIMPLE_EXPRESSION source participates in constType-based stability.\n if ((sourceExp as { type?: number }).type !== NodeTypes.SIMPLE_EXPRESSION) {\n return null;\n }\n\n const simpleSourceExp = sourceExp as SimpleExpressionNode;\n\n // Trust the Vue compiler's own const analysis first. If the source isn't\n // considered constant by Vue, we should not attempt to infer an enumerable\n // set of keys.\n if (simpleSourceExp.constType === ConstantTypes.NOT_CONSTANT) {\n return null;\n }\n\n const iterableRaw = (() => {\n try {\n return stringifyExpression(simpleSourceExp).trim();\n }\n catch {\n return (simpleSourceExp.loc?.source ?? \"\").trim();\n }\n })();\n\n if (!iterableRaw) {\n return null;\n }\n\n let iterableAst: BabelNode | null = null;\n try {\n iterableAst = parseExpression(iterableRaw, { plugins: [\"typescript\"] }) as BabelNode;\n }\n catch {\n iterableAst = null;\n }\n\n if (!iterableAst || !isArrayExpression(iterableAst)) {\n return null;\n }\n\n const values: string[] = [];\n for (const el of (iterableAst as ArrayExpression).elements ?? []) {\n if (!el) {\n return null;\n }\n if (isStringLiteral(el)) {\n if (!el.value.trim()) {\n continue;\n }\n values.push(el.value);\n continue;\n }\n if (isTemplateLiteral(el)) {\n if ((el.expressions ?? []).length > 0) {\n return null;\n }\n const v = (el.quasis ?? []).map(q => q.value?.cooked ?? \"\").join(\"\");\n if (!v.trim()) {\n continue;\n }\n values.push(v);\n continue;\n }\n // Non-literal values make the set non-enumerable.\n return null;\n }\n\n const distinct = Array.from(new Set(values));\n if (!distinct.length) {\n return null;\n }\n\n return distinct;\n}\n\nfunction getParent(hierarchyMap: HierarchyMap, node: ElementNode): ElementNode | null {\n return hierarchyMap.get(node) || null;\n}\n\n/**\n * Analyzes a :handler directive to extract the handler name\n *\n * Supports common patterns:\n * - Simple identifier: :handler=\"myHandler\"\n * - Member expression: :handler=\"obj.myHandler\"\n * - Arrow function: :handler=\"(x) => myHandler(x)\"\n *\n * Returns the handler name in PascalCase format, or null if not found.\n *\n * @internal\n */\nexport function nodeHandlerAttributeValue(node: ElementNode): string | null {\n return nodeHandlerAttributeInfo(node)?.semanticNameHint ?? null;\n}\n\nexport interface HandlerAttributeInfo {\n /** Stable semantic hint for method/property names (never derived by parsing data-testid). */\n semanticNameHint: string;\n /** Stable semantic merge key for converging identical handler actions. */\n mergeKey: string;\n}\n\n/**\n * Extracts semantic naming and merge identity from a :handler binding.\n *\n * IMPORTANT: This never parses/derives from the generated/author-provided data-testid.\n */\nexport function nodeHandlerAttributeInfo(node: ElementNode): HandlerAttributeInfo | null {\n const handlerDirective = findDirectiveByName(node, \"bind\", \"handler\");\n if (!handlerDirective?.exp) {\n return null;\n }\n\n const exp = handlerDirective.exp as SimpleExpressionNode | CompoundExpressionNode;\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n if (!source) {\n return null;\n }\n\n // Use a source-based key so identical handler expressions can converge.\n // NOTE: We intentionally do not normalize via regex/string parsing helpers in this package.\n const mergeKey = `handler:expr:${source}`;\n\n let expr: object;\n try {\n expr = parseExpression(source, { plugins: [\"typescript\", \"jsx\"] });\n }\n catch {\n // Even if parsing fails, still provide a merge identity.\n return null;\n }\n\n const isNodeType = (node: object | null, type: string): node is { type: string } => {\n return node !== null && (node as { type?: string }).type === type;\n };\n const isIdentifierNode = (node: object | null): node is { type: \"Identifier\"; name: string } => {\n return isNodeType(node, \"Identifier\") && typeof (node as { name?: string }).name === \"string\";\n };\n const isStringLiteralNode = (node: object | null): node is { type: \"StringLiteral\"; value: string } => {\n return isNodeType(node, \"StringLiteral\") && typeof (node as { value?: string }).value === \"string\";\n };\n const isBooleanLiteralNode = (node: object | null): node is { type: \"BooleanLiteral\"; value: boolean } => {\n return isNodeType(node, \"BooleanLiteral\") && typeof (node as { value?: boolean }).value === \"boolean\";\n };\n const isNumericLiteralNode = (node: object | null): node is { type: \"NumericLiteral\"; value: number } => {\n return isNodeType(node, \"NumericLiteral\") && typeof (node as { value?: number }).value === \"number\";\n };\n const isNullLiteralNode = (node: object | null): node is { type: \"NullLiteral\" } => {\n return isNodeType(node, \"NullLiteral\");\n };\n const isMemberExpressionNode = (node: object | null): node is { type: \"MemberExpression\"; computed: boolean; object: object; property: object } => {\n if (!isNodeType(node, \"MemberExpression\"))\n return false;\n const n = node as { computed?: boolean; object?: object; property?: object };\n return typeof n.computed === \"boolean\"\n && typeof n.object === \"object\" && n.object !== null\n && typeof n.property === \"object\" && n.property !== null;\n };\n const isCallExpressionNode = (node: object | null): node is { type: \"CallExpression\"; callee: object; arguments: object[] } => {\n if (!isNodeType(node, \"CallExpression\"))\n return false;\n const n = node as { callee?: object; arguments?: object[] };\n return typeof n.callee === \"object\" && n.callee !== null && Array.isArray(n.arguments);\n };\n const isAssignmentExpressionNode = (node: object | null): node is { type: \"AssignmentExpression\"; left: object; right: object } => {\n if (!isNodeType(node, \"AssignmentExpression\"))\n return false;\n const n = node as { left?: object; right?: object };\n return typeof n.left === \"object\" && n.left !== null && typeof n.right === \"object\" && n.right !== null;\n };\n const isArrowFunctionExpressionNode = (node: object | null): node is { type: \"ArrowFunctionExpression\"; body: object } => {\n if (!isNodeType(node, \"ArrowFunctionExpression\"))\n return false;\n const n = node as { body?: object };\n return typeof n.body === \"object\" && n.body !== null;\n };\n const isBlockStatementNode = (node: object | null): node is { type: \"BlockStatement\"; body: object[] } => {\n if (!isNodeType(node, \"BlockStatement\"))\n return false;\n const n = node as { body?: object[] };\n return Array.isArray(n.body);\n };\n const isExpressionStatementNode = (node: object | null): node is { type: \"ExpressionStatement\"; expression: object } => {\n if (!isNodeType(node, \"ExpressionStatement\"))\n return false;\n const n = node as { expression?: object };\n return typeof n.expression === \"object\" && n.expression !== null;\n };\n const isReturnStatementNode = (node: object | null): node is { type: \"ReturnStatement\"; argument: object | null } => {\n if (!isNodeType(node, \"ReturnStatement\"))\n return false;\n const n = node as { argument?: object | null };\n return typeof n.argument === \"object\" || n.argument === null;\n };\n const isObjectExpressionNode = (node: object | null): node is { type: \"ObjectExpression\"; properties: object[] } => {\n if (!isNodeType(node, \"ObjectExpression\"))\n return false;\n const n = node as { properties?: object[] };\n return Array.isArray(n.properties);\n };\n const isObjectPropertyNode = (node: object | null): node is { type: \"ObjectProperty\"; computed: boolean; key: object; value: object } => {\n if (!isNodeType(node, \"ObjectProperty\"))\n return false;\n const n = node as { computed?: boolean; key?: object; value?: object };\n return typeof n.computed === \"boolean\"\n && typeof n.key === \"object\" && n.key !== null\n && typeof n.value === \"object\" && n.value !== null;\n };\n\n const getLastIdentifierFromMemberChain = (node: object | null): string | null => {\n if (!node)\n return null;\n if (isIdentifierNode(node))\n return node.name;\n if (isMemberExpressionNode(node)) {\n const prop = node.property;\n\n // obj.myHandler\n if (node.computed === false) {\n if (isIdentifierNode(prop))\n return prop.name;\n }\n\n // obj['myHandler']\n // This is a stable, explicit name; allow it.\n if (node.computed === true) {\n if (isStringLiteralNode(prop))\n return prop.value;\n }\n }\n return null;\n };\n\n const getAssignmentTargetName = (lhs: object | null): string | null => {\n if (!lhs) {\n return null;\n }\n\n if (isIdentifierNode(lhs)) {\n return lhs.name;\n }\n\n if (isMemberExpressionNode(lhs)) {\n // Special-case Vue refs: something.value = true/false should derive from `something`.\n if (lhs.computed === false && isIdentifierNode(lhs.property) && lhs.property.name === \"value\") {\n return getLastIdentifierFromMemberChain(lhs.object);\n }\n\n return getLastIdentifierFromMemberChain(lhs);\n }\n\n return null;\n };\n\n const isTemplateLiteralNode = (node: object | null): node is { type: \"TemplateLiteral\"; expressions: object[]; quasis: Array<{ value?: { cooked?: string } }> } => {\n if (!isNodeType(node, \"TemplateLiteral\")) {\n return false;\n }\n const n = node as { expressions?: object[]; quasis?: Array<{ value?: { cooked?: string } }> };\n return Array.isArray(n.expressions) && Array.isArray(n.quasis);\n };\n\n const stableWordFromValue = (arg: object | null): string | null => {\n if (!arg) {\n return null;\n }\n\n if (isBooleanLiteralNode(arg)) {\n return arg.value ? \"True\" : \"False\";\n }\n\n if (isNumericLiteralNode(arg)) {\n return `Value${String(arg.value)}`;\n }\n\n if (isNullLiteralNode(arg)) {\n return \"Null\";\n }\n\n if (isStringLiteralNode(arg)) {\n const cleaned = (arg.value ?? \"\").trim();\n if (!cleaned) {\n return null;\n }\n return toPascalCase(cleaned.slice(0, 24));\n }\n\n // TemplateLiteral with no expressions is a stable, explicit string.\n if (isTemplateLiteralNode(arg)) {\n if ((arg.expressions ?? []).length > 0) {\n return null;\n }\n const v = (arg.quasis ?? []).map(q => q.value?.cooked ?? \"\").join(\"\").trim();\n if (!v) {\n return null;\n }\n return toPascalCase(v.slice(0, 24));\n }\n\n // Stable member-expression values are useful suffixes for enums/constants.\n // Avoid suffixing from typical lower-camel variable identifiers (e.g. x, assignmentId), since\n // that would explode API surface and reduce stability.\n if (isMemberExpressionNode(arg)) {\n const stableName = getLastIdentifierFromMemberChain(arg);\n if (stableName) {\n return toPascalCase(stableName.slice(0, 24));\n }\n }\n\n // Allow Identifier suffixes only when they look like constants (PascalCase/UPPER_CASE).\n if (isIdentifierNode(arg)) {\n const firstChar = arg.name.charAt(0);\n const isUpperAlpha = firstChar !== \"\" && firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase();\n if (isUpperAlpha) {\n return toPascalCase(arg.name.slice(0, 24));\n }\n }\n\n return null;\n };\n\n const getStableSuffixFromCall = (call: { arguments: object[] }): string | null => {\n const args = call.arguments ?? [];\n const first = (args.length > 0 ? args[0] : null) as object | null;\n\n // Preferred pattern: fn({ option: true/false, ... }) => OptionTrue...\n if (!isObjectExpressionNode(first)) {\n // Secondary pattern: fn('all') / fn(true) / fn(3) etc. Derive from first 1-2 literal args.\n const parts: string[] = [];\n for (const arg of args.slice(0, 2)) {\n const w = stableWordFromValue(arg ?? null);\n if (!w) {\n return null;\n }\n parts.push(w);\n }\n\n if (parts.length === 0) {\n return null;\n }\n\n return parts.join(\"\");\n }\n\n interface Part { key: string; value: string }\n const parts: Part[] = [];\n for (const prop of first.properties ?? []) {\n if (!isObjectPropertyNode(prop)) {\n continue;\n }\n if (prop.computed) {\n continue;\n }\n\n const keyName = isIdentifierNode(prop.key)\n ? prop.key.name\n : (isStringLiteralNode(prop.key) ? prop.key.value : null);\n if (!keyName) {\n continue;\n }\n\n let valueWord: string | null = null;\n if (isBooleanLiteralNode(prop.value)) {\n valueWord = prop.value.value ? \"True\" : \"False\";\n } else if (isStringLiteralNode(prop.value)) {\n const cleaned = (prop.value.value ?? \"\").trim();\n if (cleaned) {\n // Avoid generating unreasonably long names from large literals.\n valueWord = toPascalCase(cleaned.slice(0, 24));\n }\n } else if (isNumericLiteralNode(prop.value)) {\n valueWord = `Value${String(prop.value.value)}`;\n } else if (isNullLiteralNode(prop.value)) {\n valueWord = \"Null\";\n }\n\n if (!valueWord) {\n continue;\n }\n\n parts.push({ key: keyName, value: valueWord });\n }\n\n if (parts.length === 0) {\n return null;\n }\n\n // Sort for stability (property order differences should not rename the POM member).\n parts.sort((a, b) => a.key.localeCompare(b.key));\n\n // Limit suffix size.\n const limited = parts.slice(0, 2);\n return limited.map(p => `${toPascalCase(p.key)}${p.value}`).join(\"\");\n };\n\n // :handler=\"myHandler\" or :handler=\"obj.myHandler\"\n const direct = getLastIdentifierFromMemberChain(expr);\n if (direct) {\n return { semanticNameHint: toPascalCase(direct), mergeKey };\n }\n\n // :handler=\"(x) => myHandler(x)\" or :handler=\"() => obj.myHandler()\"\n if (isArrowFunctionExpressionNode(expr)) {\n const body = expr.body;\n\n const tryFromCallExpression = (call: object | null) => {\n if (!isCallExpressionNode(call)) {\n return null;\n }\n const name = getLastIdentifierFromMemberChain(call.callee);\n if (!name) {\n return null;\n }\n const suffix = getStableSuffixFromCall(call);\n const semanticNameHint = suffix\n ? `${toPascalCase(name)}${suffix}`\n : toPascalCase(name);\n return semanticNameHint;\n };\n\n // ArrowFunctionExpression with implicit return call: () => fn(...)\n const directCall = tryFromCallExpression(body);\n if (directCall) {\n return { semanticNameHint: directCall, mergeKey };\n }\n\n // ArrowFunctionExpression with assignment body: () => someFlag = true\n if (isAssignmentExpressionNode(body)) {\n const lhs = getAssignmentTargetName(body.left);\n if (lhs) {\n const rhs = stableWordFromValue(body.right);\n const semanticNameHint = `Set${toPascalCase(lhs)}${rhs ?? \"\"}`;\n return { semanticNameHint, mergeKey };\n }\n }\n\n // ArrowFunctionExpression block: () => { return fn(...) } or () => { fn(...) }\n if (isBlockStatementNode(body)) {\n const stmts = body.body ?? [];\n if (stmts.length > 0) {\n const firstStmt = stmts[0] as object;\n if (isReturnStatementNode(firstStmt)) {\n const fromReturn = tryFromCallExpression(firstStmt.argument ?? null);\n if (fromReturn) {\n return { semanticNameHint: fromReturn, mergeKey };\n }\n }\n if (isExpressionStatementNode(firstStmt)) {\n const fromExpr = tryFromCallExpression(firstStmt.expression ?? null);\n if (fromExpr) {\n return { semanticNameHint: fromExpr, mergeKey };\n }\n }\n }\n }\n\n // Fallback: () => myHandler\n const bodyName = getLastIdentifierFromMemberChain(body);\n if (bodyName) {\n return { semanticNameHint: toPascalCase(bodyName), mergeKey };\n }\n }\n\n return null;\n}\n\nexport interface NativeWrapperTransformInfo {\n /** data-testid for wrappers that can be derived from valueAttribute or v-model */\n nativeWrappersValue: AttributeValue | null;\n /** Value to assign to option-data-testid-prefix (when required by wrapper config) */\n optionDataTestIdPrefixValue: AttributeValue | null;\n\n /** Semantic naming hint for POM method generation (never derived by parsing data-testid). */\n semanticNameHint: string | null;\n}\n\n/**\n * Computes native-wrapper related transform info in a single pass.\n *\n * This consolidates:\n * - getNativeWrappersValue (data-testid from valueAttribute/v-model)\n * - assignOptionDataTestIdPrefix (option-data-testid-prefix + wrapper test id)\n *\n * NOTE: This function is pure (no AST mutation). Callers should apply attributes explicitly.\n */\nexport function getNativeWrapperTransformInfo(\n node: ElementNode,\n componentName: string,\n nativeWrappers: NativeWrappersMap,\n): NativeWrapperTransformInfo {\n // If not a configured wrapper, nothing to do.\n const wrapperConfig = nativeWrappers[node.tag];\n if (!wrapperConfig) {\n return { nativeWrappersValue: null, optionDataTestIdPrefixValue: null, semanticNameHint: null };\n }\n\n const { role, valueAttribute, requiresOptionDataTestIdPrefix } = wrapperConfig;\n\n // Some wrappers (notably checkbox/toggle/radio/select) can end up with synthetic click\n // listeners in the compiler output (via v-model expansion). Treat those as implementation\n // details and still prefer wrapper-derived ids.\n //\n // For button-like wrappers, an author-specified @click is meaningful and we prefer the\n // click-derived naming pipeline.\n if (nodeHasClickDirective(node) && role === \"button\") {\n return { nativeWrappersValue: null, optionDataTestIdPrefixValue: null, semanticNameHint: null };\n }\n\n // 1) The traditional native wrapper path (valueAttribute or v-model)\n if (valueAttribute) {\n const value = getDataTestIdValueFromValueAttribute(node, componentName, valueAttribute, role);\n\n // Derive a semantic name hint from the wrapper's value attribute.\n // This is intentionally based on the source expression/value, NOT by parsing the generated test id.\n const attrStatic = findAttributeByKey(node, valueAttribute);\n if (attrStatic?.value?.content) {\n return { nativeWrappersValue: value || null, optionDataTestIdPrefixValue: null, semanticNameHint: attrStatic.value.content };\n }\n\n const attrDynamic = findDirectiveByName(node, \"bind\", valueAttribute);\n if (attrDynamic && \"exp\" in attrDynamic && attrDynamic.exp && \"ast\" in attrDynamic.exp && attrDynamic.exp.ast) {\n const { name } = getClickHandlerNameFromAst(attrDynamic.exp.ast as BabelNode);\n if (name) {\n return { nativeWrappersValue: value || null, optionDataTestIdPrefixValue: null, semanticNameHint: name };\n }\n // Fall back to the raw expression source.\n const raw = (attrDynamic.exp as SimpleExpressionNode).loc?.source ?? \"\";\n return { nativeWrappersValue: value || null, optionDataTestIdPrefixValue: null, semanticNameHint: raw || null };\n }\n\n return { nativeWrappersValue: value || null, optionDataTestIdPrefixValue: null, semanticNameHint: null };\n }\n\n const { vModel, modelValue } = getModelBindingValues(node);\n if (vModel || modelValue) {\n const vmodelvalue = getDataTestIdFromGroupOption(vModel);\n const nativeWrappersValue = staticAttributeValue(`${componentName}-${modelValue || vmodelvalue}-${role}`);\n\n const semanticNameHint = modelValue || vModel || null;\n\n // 2) Some wrappers additionally require option-data-testid-prefix.\n if (requiresOptionDataTestIdPrefix) {\n const value = vmodelvalue || modelValue;\n return {\n nativeWrappersValue,\n optionDataTestIdPrefixValue: staticAttributeValue(`${componentName}-${value}`),\n semanticNameHint,\n };\n }\n\n return { nativeWrappersValue, optionDataTestIdPrefixValue: null, semanticNameHint };\n }\n\n return { nativeWrappersValue: null, optionDataTestIdPrefixValue: null, semanticNameHint: null };\n}\n\nfunction getDataTestIdValueFromValueAttribute(\n node: ElementNode,\n actualFileName: string,\n attributeKey: string,\n role: string,\n): AttributeValue | null {\n const attrStatic = findAttributeByKey(node, attributeKey);\n if (attrStatic) {\n const value = attrStatic.value?.content || \"\";\n return staticAttributeValue(`${actualFileName}-${value}-${role}`);\n }\n\n const attrDynamic = findDirectiveByName(node, \"bind\", attributeKey);\n if (attrDynamic && 'exp' in attrDynamic && attrDynamic.exp && 'ast' in attrDynamic.exp && attrDynamic.exp.ast) {\n let value = attrDynamic.exp.loc.source;\n\n if (attrDynamic.exp.ast?.type === \"MemberExpression\") {\n // eslint-disable-next-line no-restricted-syntax\n return staticAttributeValue(`${actualFileName}-${value.replaceAll(\".\", \"\")}-${role}`);\n }\n\n if (attrDynamic.exp.ast?.type === \"CallExpression\") {\n value = stringifyExpression(attrDynamic.exp);\n return templateAttributeValue(`${actualFileName}-\\${${value}}-${role}`);\n }\n return staticAttributeValue(`${actualFileName}-${value}-${role}`);\n }\n return null;\n}\n\nexport function generateToDirectiveDataTestId(componentName: string, node: ElementNode, toDirective: DirectiveNode, context: TransformContext, hierarchyMap: HierarchyMap, nativeWrappers: NativeWrappersMap): AttributeValue | null {\n const key = getKeyDirectiveValue(node, context) || getSelfClosingForDirectiveKeyAttrValue(node) || getContainedInVForDirectiveKeyValue(context, node, hierarchyMap);\n if (key) {\n return templateAttributeValue(`${componentName}-${key}-${formatTagName(node, nativeWrappers)}`);\n } else {\n let name = toDirectiveObjectFieldNameValue(toDirective);\n if (!name) {\n if (toDirective.exp == null) {\n return null;\n }\n\n const source = stringifyExpression(toDirective.exp);\n\n const toAst = toDirective.exp.ast;\n const interpolated = !(toAst == null || toAst === false || toAst) && isTemplateLiteral(toAst);\n return templateAttributeValue(`${componentName}-\\${${source}${interpolated ? \".replaceAll(' ', '')\" : \"?.name?.replaceAll(' ', '') ?? ''\"}}${formatTagName(node, nativeWrappers)}`);\n } else {\n const innerText = getInnerText(node);\n if (innerText && !name.includes(innerText)) {\n name += `-${innerText}`;\n }\n return staticAttributeValue(`${componentName}-${name}${formatTagName(node, nativeWrappers)}`);\n }\n }\n}\n\n// NOTE: We intentionally keep the underlying helper functions public so the transform can\n// compute decisions incrementally (instead of bundling all signals into one return object).\n\nexport function formatTagName(node: ElementNode, nativeWrappers: NativeWrappersMap): string {\n if (Object.keys(nativeWrappers).includes(node.tag)) {\n return `-${nativeWrappers[node.tag].role}`;\n }\n\n // eslint-disable-next-line no-restricted-syntax\n const nodeName = node.tag.replace(/-/g, \"\").toLowerCase();\n return `-${nodeName}`;\n}\n\n/**\n * Extracts the route name from a :to directive with an object value\n *\n * Parses patterns like:\n * - :to=\"{ name: 'routeName' }\"\n * - :to=\"{ name: 'routeName', params: {...} }\"\n *\n * Returns the route name in PascalCase, or null if not found.\n *\n * @internal\n */\nexport function toDirectiveObjectFieldNameValue(node: DirectiveNode): string | null {\n if (!node.exp || (node.exp.type !== NodeTypes.COMPOUND_EXPRESSION && node.exp.type !== NodeTypes.SIMPLE_EXPRESSION)) {\n return null;\n }\n\n const source = (node.exp as CompoundExpressionNode).loc.source.trim();\n try {\n const expr = parseExpression(source, { plugins: [\"typescript\"] }) as object;\n\n const isNodeType = (n: object | null, type: string): n is { type: string } => {\n return n !== null && (n as { type?: string }).type === type;\n };\n const isStringLiteralNode = (n: object | null): n is { type: \"StringLiteral\"; value: string } => {\n return isNodeType(n, \"StringLiteral\") && typeof (n as { value?: string }).value === \"string\";\n };\n const isIdentifierNode = (n: object | null): n is { type: \"Identifier\"; name: string } => {\n return isNodeType(n, \"Identifier\") && typeof (n as { name?: string }).name === \"string\";\n };\n const isObjectPropertyNode = (n: object | null): n is { type: \"ObjectProperty\"; key: object; value: object } => {\n if (!isNodeType(n, \"ObjectProperty\"))\n return false;\n const nn = n as { key?: object; value?: object };\n return typeof nn.key === \"object\" && nn.key !== null && typeof nn.value === \"object\" && nn.value !== null;\n };\n const isObjectExpressionNode = (n: object | null): n is { type: \"ObjectExpression\"; properties: object[] } => {\n if (!isNodeType(n, \"ObjectExpression\"))\n return false;\n const nn = n as { properties?: object[] };\n return Array.isArray(nn.properties);\n };\n\n if (!isObjectExpressionNode(expr))\n return null;\n\n const nameProp = (expr as { properties: object[] }).properties.find((p) => {\n if (!isObjectPropertyNode(p))\n return false;\n const key = p.key as object;\n return (isIdentifierNode(key) && key.name === \"name\") || (isStringLiteralNode(key) && key.value === \"name\");\n });\n if (!nameProp || !isObjectPropertyNode(nameProp) || !isStringLiteralNode(nameProp.value as object))\n return null;\n return toPascalCase((nameProp.value as { value: string }).value);\n }\n catch {\n return null;\n }\n}\n\nexport function addComponentTestIds(componentName: string, componentTestIds: Map<string, Set<string>>, desiredTestId: string) {\n if (!componentTestIds.has(componentName)) {\n componentTestIds.set(componentName, new Set<string>());\n }\n componentTestIds.get(componentName)?.add(desiredTestId);\n}\n\n// Helper function to generate test IDs //method name must start verb word\n// NOTE: generateTestId intentionally removed.\n// The transform now inlines the three primary code paths (handler/to/click) directly.\n\nexport function getComposedClickHandlerContent(\n node: ElementNode,\n _context: TransformContext,\n _innerText: string | null,\n clickDirective?: DirectiveNode,\n _options: { componentName?: string; contextFilename?: string } = {}\n): string {\n // Prefer caller-provided directive (so we don't re-scan props multiple times).\n const click = clickDirective ?? tryGetClickDirective(node);\n if (!click) {\n return \"\";\n }\n\n // Extract handler name from directive expression\n let handlerName = \"\";\n\n if (click.exp) {\n const exp = click.exp as SimpleExpressionNode | CompoundExpressionNode;\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n\n if (source) {\n const parsed = tryParseBabelAstFromHandlerSource(source);\n if (parsed) {\n const astName = getStableClickHandlerNameFromAst(parsed as BabelNode);\n if (astName) {\n handlerName = astName;\n }\n }\n }\n }\n\n handlerName = normalizeHandlerName(handlerName);\n\n // Normalize handler names for codegen:\n // - innerText comes in kebab-ish already (via getInnerText)\n // - handler names are typically camelCase; convert to PascalCase for readability/stability\n const normalizedHandlerSegment = handlerName ? `-${toPascalCase(handlerName)}` : \"\";\n const result = normalizedHandlerSegment;\n\n // eslint-disable-next-line no-restricted-syntax\n return result.replace(/[^a-z-]/gi, \"\");\n}\n\nfunction tryParseBabelAstFromHandlerSource(source: string): object | null {\n const trimmed = source.trim();\n if (!trimmed)\n return null;\n\n // Most handlers are expression-shaped; parse that first.\n try {\n return parseExpression(trimmed, { plugins: [\"typescript\", \"jsx\"] }) as object;\n }\n catch {\n // Handlers can also be statement-shaped (e.g. `a(); b()` or `if (...) ...`). Parse as a file.\n }\n\n try {\n return parse(trimmed, { sourceType: \"module\", plugins: [\"typescript\", \"jsx\"] }) as object;\n }\n catch {\n return null;\n }\n}\n\nfunction extractEmittedEventNameFromAst(ast: BabelNode): string {\n\n // Vue may give us:\n // - Expression (most common)\n // - ExpressionStatement wrapper\n // - Program (v-on with `;` => statements parse mode)\n // - File (depending on who parsed it)\n // This helper makes emit('$event') discoverable across those shapes.\n\n const root: BabelNode = isFile(ast) ? (ast as File).program : ast;\n\n const found = walkForEmittedEventName(root);\n return found || \"\";\n}\n\nfunction walkForEmittedEventName(node: object | null): string | null {\n if (!node)\n return null;\n\n const n = node as BabelNode;\n\n // Handle calls: emit('event') / $emit('event')\n if (isCallExpression(n) || isOptionalCallExpression(n)) {\n const callee = n.callee;\n if (isIdentifier(callee) && (callee.name === \"emit\" || callee.name === \"$emit\")) {\n const firstArg = n.arguments[0];\n if (firstArg && isStringLiteral(firstArg)) {\n return firstArg.value;\n }\n }\n }\n\n // Special-case Program so we don't depend on VISITOR_KEYS for top-level.\n if (isProgram(n)) {\n for (const stmt of (n as Program).body) {\n const hit = walkForEmittedEventName(stmt);\n if (hit)\n return hit;\n }\n return null;\n }\n\n const keys = VISITOR_KEYS[n.type] as readonly string[] | undefined;\n if (!keys)\n return null;\n\n type NodeChild = BabelNode | BabelNode[] | null | undefined | string | number | boolean;\n for (const key of keys) {\n const child = Reflect.get(n as object, key) as NodeChild;\n if (!child)\n continue;\n\n if (Array.isArray(child)) {\n for (const item of child) {\n // Only recurse into object nodes\n if (item && typeof item === \"object\") {\n const hit = walkForEmittedEventName(item);\n if (hit)\n return hit;\n }\n }\n continue;\n }\n\n if (typeof child === \"object\") {\n const hit = walkForEmittedEventName(child);\n if (hit)\n return hit;\n }\n }\n\n return null;\n}\n\nfunction getStableClickHandlerNameFromAst(ast: BabelNode | null): string {\n if (!ast)\n return \"\";\n\n // First, try to find emitted event names anywhere in the handler AST.\n // This covers:\n // - @click=\"emit('clicked')\"\n // - @click=\"a(); emit('clicked')\" (Program)\n // - @click=\"if (x) emit('clicked')\" (statement-shaped)\n const emitted = extractEmittedEventNameFromAst(ast);\n if (emitted)\n return emitted;\n\n // Vue's expression AST sometimes wraps as ExpressionStatement.\n if (isExpressionStatement(ast)) {\n return getStableClickHandlerNameFromExpression(ast.expression);\n }\n\n // Most often it's already an Expression.\n return getStableClickHandlerNameFromExpression(ast);\n}\n\nfunction getStableClickHandlerNameFromExpression(exp: BabelNode | null | undefined): string {\n if (!exp)\n return \"\";\n\n // Arrow wrapper: () => selectCommand(...)\n if (isArrowFunctionExpression(exp)) {\n const body = exp.body;\n // Body can be an Expression or a BlockStatement. We only support expression bodies here.\n if (body && !isBlockStatement(body)) {\n return getStableClickHandlerNameFromExpression(body);\n }\n return \"\";\n }\n\n // emit('event') / $emit('event') calls\n if (isCallExpression(exp) || isOptionalCallExpression(exp)) {\n const callee = exp.callee;\n\n // Vue compiler may wrap handlers for modifiers: withModifiers(fn, ['prevent']).\n // Prefer the underlying handler identity.\n if (isIdentifier(callee) && (callee.name === \"withModifiers\" || callee.name === \"_withModifiers\")) {\n const firstArg = exp.arguments[0];\n return getStableClickHandlerNameFromExpression(firstArg as BabelNode);\n }\n\n if (isIdentifier(callee) && callee.name === \"emit\") {\n const firstArg = exp.arguments[0];\n if (firstArg && isStringLiteral(firstArg)) {\n return firstArg.value;\n }\n }\n if (isIdentifier(callee) && callee.name === \"$emit\") {\n const firstArg = exp.arguments[0];\n if (firstArg && isStringLiteral(firstArg)) {\n return firstArg.value;\n }\n }\n return extractNameFromCallee(callee);\n }\n\n if (isAssignmentExpression(exp)) {\n // Best-effort: stable semantic name from the LHS.\n const left = exp.left;\n if (isIdentifier(left))\n return left.name;\n if (isMemberExpression(left) || isOptionalMemberExpression(left))\n return extractMemberPropertyName(left);\n return \"\";\n }\n\n // Optional chaining: foo?.bar / foo?.bar()\n if (isOptionalMemberExpression(exp)) {\n return extractMemberPropertyName(exp);\n }\n\n if (isMemberExpression(exp)) {\n return extractMemberPropertyName(exp);\n }\n\n if (isIdentifier(exp)) {\n return exp.name;\n }\n\n // clickGuard && doThing()\n if (isLogicalExpression(exp)) {\n return getStableClickHandlerNameFromExpression(exp.right);\n }\n\n // cond ? a() : b()\n if (isConditionalExpression(exp)) {\n // Prefer a stable name if both branches resolve identically.\n const cons = getStableClickHandlerNameFromExpression(exp.consequent);\n const alt = getStableClickHandlerNameFromExpression(exp.alternate);\n if (cons && cons === alt)\n return cons;\n return cons || alt;\n }\n\n // (a(), doThing())\n if (isSequenceExpression(exp)) {\n const last = exp.expressions[exp.expressions.length - 1];\n return getStableClickHandlerNameFromExpression(last);\n }\n\n return \"\";\n}\n\nfunction getClickHandlerNameFromAst(ast: BabelNode | undefined): { name: string; isAssignment: boolean } {\n if (!ast) {\n return { name: \"\", isAssignment: false };\n }\n\n if (isAssignmentExpression(ast)) {\n // Best-effort: treat simple assignment as a stable semantic name derived from the LHS.\n // Examples:\n // - showAdvanced = !showAdvanced -> showAdvanced\n // - model.semanticVersion = suggested -> semanticVersion\n const left = ast.left;\n if (isIdentifier(left)) {\n return { name: left.name, isAssignment: true };\n }\n if (isMemberExpression(left)) {\n return { name: extractMemberPropertyName(left), isAssignment: true };\n }\n return { name: \"\", isAssignment: true };\n }\n\n if (isCallExpression(ast)) {\n return { name: extractNameFromCallee(ast.callee), isAssignment: false };\n }\n\n if (isMemberExpression(ast)) {\n return { name: extractMemberPropertyName(ast), isAssignment: false };\n }\n\n if (isIdentifier(ast)) {\n return { name: ast.name, isAssignment: false };\n }\n\n return { name: \"\", isAssignment: false };\n}\n\nfunction extractNameFromCallee(callee: BabelNode): string {\n if (isIdentifier(callee)) {\n return callee.name;\n }\n\n if (isMemberExpression(callee)) {\n return extractMemberPropertyName(callee);\n }\n\n if (isOptionalMemberExpression(callee)) {\n return extractMemberPropertyName(callee);\n }\n\n return \"\";\n}\n\nfunction extractMemberPropertyName(member: MemberExpression | OptionalMemberExpression): string {\n if (member.computed) {\n return \"\";\n }\n\n const prop = member.property;\n if (isIdentifier(prop)) {\n return prop.name;\n }\n\n return \"\";\n}\n\nfunction normalizeHandlerName(name: string): string {\n if (!name) {\n return \"\";\n }\n\n const sanitized = name.toLowerCase().startsWith(\"on\") ? name.slice(2) : name;\n return sanitized;\n}\n\nexport function getInnerText(node: ElementNode): string {\n // Use Vue compiler AST: children can be VText, Interpolation, or other nodes\n // eslint-disable-next-line no-restricted-syntax\n const innerText = (node.children || [])\n .filter((child): child is TextNode =>\n child.type === NodeTypes.TEXT\n && Boolean(child.content?.trim())\n )\n .map(child => child.content.trim())\n .join(\" \")\n // eslint-disable-next-line no-restricted-syntax\n .replace(/\\([^)]*\\)/g, \"\") // Remove everything in ( )\n // eslint-disable-next-line no-restricted-syntax\n .replace(/[\"'`;:.,!?_—\\-\\\\/]/g, \"\") // Remove quotes, punctuation, forward/back slashes\n // eslint-disable-next-line no-restricted-syntax\n .replace(/[^a-z\\s]/gi, \"\") // Remove non-alphabetic characters\n // eslint-disable-next-line no-restricted-syntax\n .replace(/\\s+/g, \"-\");\n\n return innerText || \"\";\n}\n\n\n/**\n * Finds an existing test id attribute (static or bound).\n */\nexport function findTestIdAttribute(element: ElementNode, attributeName: string): AttributeNode | DirectiveNode | null {\n const staticAttr = findAttributeByKey(element, attributeName);\n if (staticAttr)\n return staticAttr;\n\n return findDirectiveByName(element, \"bind\", attributeName) ?? null;\n}\n\n/**\n * Finds an existing data-testid attribute.\n *\n * @deprecated Prefer `findTestIdAttribute(element, attributeName)`.\n */\nexport function findDataTestIdAttribute(element: ElementNode): AttributeNode | DirectiveNode | null {\n return findTestIdAttribute(element, \"data-testid\");\n}\n\n/**\n * Upserts a test id attribute (static or bound) on an element.\n * Removes existing matches before adding the new value.\n */\nexport function upsertAttribute(\n element: ElementNode,\n attributeName: string,\n value: AttributeValue,\n): void {\n element.props = element.props.filter((prop) => {\n // Remove static attribute: data-testid=\"...\"\n if (prop.type === NodeTypes.ATTRIBUTE && prop.name === attributeName) {\n return false;\n }\n\n // Remove dynamic directive: :data-testid=\"...\" or v-bind:data-testid=\"...\"\n if (\n prop.type === NodeTypes.DIRECTIVE\n && prop.name === \"bind\"\n && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION\n && prop.arg.content === attributeName\n ) {\n return false;\n }\n\n return true;\n });\n\n if (value.kind === \"template\") {\n // Dynamic binding: :data-testid=\"`ComponentName_tag_${key}`\"\n element.props.push({\n type: NodeTypes.DIRECTIVE,\n name: \"bind\",\n arg: {\n type: NodeTypes.SIMPLE_EXPRESSION,\n content: attributeName,\n isStatic: true,\n constType: 0,\n loc: element.loc,\n },\n exp: createSimpleExpression(`\\`${value.template}\\``, false, element.loc),\n modifiers: [],\n loc: element.loc,\n } as DirectiveNode);\n }\n else {\n // Static attribute: data-testid=\"ComponentName_tag_button\"\n element.props.push({\n type: NodeTypes.ATTRIBUTE,\n name: attributeName,\n value: {\n type: NodeTypes.TEXT,\n content: value.value,\n loc: element.loc,\n },\n loc: element.loc,\n } as AttributeNode);\n }\n}\n\nexport interface ExistingElementDataTestIdInfo {\n value: string;\n /** Whether the provided test id is clearly dynamic (e.g. template literal with expressions). */\n isDynamic: boolean;\n /** Whether the value is a statically-known literal (safe to join). */\n isStaticLiteral: boolean;\n\n /** When the binding is a template literal, the unwrapped template text (without backticks). */\n template?: string;\n /** Number of interpolations in the template literal, if known. */\n templateExpressionCount?: number;\n /** For non-template dynamic bindings, the raw expression string (identifier/call/etc). */\n rawExpression?: string;\n}\n\n/**\n * Extracts existing data-testid info from an element.\n *\n * Supports:\n * - data-testid=\"literal\"\n * - :data-testid=\"`Foo-${bar}`\" (TemplateLiteral)\n * - :data-testid=\"'foo'\" (StringLiteral)\n *\n * Unknown expressions are treated as dynamic/unknown.\n */\nexport function tryGetExistingElementDataTestId(node: ElementNode, attributeName: string = \"data-testid\"): ExistingElementDataTestIdInfo | null {\n const existing = findTestIdAttribute(node, attributeName);\n if (!existing) {\n return null;\n }\n\n if (existing.type === NodeTypes.ATTRIBUTE) {\n const value = existing.value?.content ?? null;\n if (!value) {\n return null;\n }\n // A static attribute is always treated as a literal string.\n // (If it contains \"${\" it's still just characters, not interpolation.)\n return { value, isDynamic: false, isStaticLiteral: true };\n }\n\n // :data-testid=\"...\" / v-bind:data-testid=\"...\"\n const directive = existing as DirectiveNode;\n const exp = directive.exp;\n if (!exp || exp.type !== NodeTypes.SIMPLE_EXPRESSION) {\n return null;\n }\n\n // Prefer AST-based detection when available.\n // Vue's compiler attaches Babel AST to SimpleExpressionNode.exp.ast.\n const simpleExp = exp as SimpleExpressionNode;\n const ast = simpleExp.ast;\n\n // Template literal: :data-testid=\"`Foo-${bar}`\"\n // - If it has zero expressions, it's effectively a static string.\n // - If it has expressions, it's dynamic.\n if (ast && typeof ast === \"object\" && \"type\" in ast && (ast as { type: string }).type === \"TemplateLiteral\") {\n const tl = ast as { quasis: Array<{ value?: { cooked?: string } }>; expressions: unknown[] };\n const cooked = (tl.quasis ?? []).map(q => q.value?.cooked ?? \"\").join(\"\");\n const expressionCount = (tl.expressions ?? []).length;\n const isStatic = expressionCount === 0;\n\n // Prefer the raw template (so callers can validate placeholders / preserve interpolation),\n // but fall back to cooked content when we can't confidently unwrap.\n const raw = (simpleExp.content ?? \"\").trim();\n const unwrappedTemplate = (raw.startsWith(\"`\") && raw.endsWith(\"`\") && raw.length >= 2)\n ? raw.slice(1, -1)\n : cooked;\n\n if (isStatic) {\n return { value: unwrappedTemplate, isDynamic: false, isStaticLiteral: true };\n }\n\n return {\n value: unwrappedTemplate,\n isDynamic: true,\n isStaticLiteral: false,\n template: unwrappedTemplate,\n templateExpressionCount: expressionCount,\n };\n }\n\n // String literal: :data-testid=\"'foo'\"\n if (ast && typeof ast === \"object\" && \"type\" in ast && (ast as { type: string }).type === \"StringLiteral\") {\n const sl = ast as { value?: string };\n const value = sl.value ?? \"\";\n if (!value) {\n return null;\n }\n return { value, isDynamic: false, isStaticLiteral: true };\n }\n\n // Fallback: we have no parseable AST shape (identifier/call/etc).\n // Treat as dynamic/unknown to avoid false positives.\n const raw = (simpleExp.content ?? \"\").trim();\n if (!raw) {\n return null;\n }\n\n return { value: raw, isDynamic: true, isStaticLiteral: false, rawExpression: raw };\n}\n\nfunction isTemplatePlaceholder(part: string) {\n // Avoid regex literals here; this only needs to detect the simple `${...}` wrapper.\n return part.startsWith(\"${\") && part.endsWith(\"}\") && part.length >= 3;\n}\n\nfunction isAllCapsOrDigits(value: string): boolean {\n if (value.length <= 1) {\n return false;\n }\n for (let i = 0; i < value.length; i++) {\n const c = value.charCodeAt(i);\n const isUpper = c >= 65 && c <= 90;\n const isDigit = c >= 48 && c <= 57;\n if (!isUpper && !isDigit) {\n return false;\n }\n }\n return true;\n}\n\nfunction startsWithDigit(value: string): boolean {\n if (!value.length) {\n return false;\n }\n const c = value.charCodeAt(0);\n return c >= 48 && c <= 57;\n}\n\nfunction stripNonIdentifierChars(value: string): string {\n let out = \"\";\n for (let i = 0; i < value.length; i++) {\n const c = value.charCodeAt(i);\n const isUpper = c >= 65 && c <= 90;\n const isLower = c >= 97 && c <= 122;\n const isDigit = c >= 48 && c <= 57;\n const isUnderscore = c === 95;\n if (isUpper || isLower || isDigit || isUnderscore) {\n out += value[i];\n }\n }\n return out;\n}\n\nfunction safeMethodNameFromParts(parts: string[]) {\n const toPascalCasePreserveAcronyms = (p: string) => {\n // Preserve all-caps identifiers (e.g. DEPLOY, HTTP, ID) so we don't\n // collapse them into the same name as title-cased variants.\n const trimmed = p.trim();\n if (isAllCapsOrDigits(trimmed)) {\n return trimmed;\n }\n return toPascalCase(trimmed);\n };\n\n const cleaned = parts\n .map(p => p.trim())\n .filter(p => p.length > 0)\n // Drop any dynamic placeholders from method names; they map to the `key` param.\n .filter(p => !isTemplatePlaceholder(p));\n\n const rawName = cleaned.map(toPascalCasePreserveAcronyms).join(\"\");\n const name = stripNonIdentifierChars(rawName);\n if (!name.length) {\n return \"Element\";\n }\n // Identifiers cannot start with a digit.\n if (startsWithDigit(name)) {\n return `Value${name}`;\n }\n return name;\n}\n\n/**\n * Replaces any `${...}` interpolation in a template string with the stable placeholder `${key}`.\n *\n * IMPORTANT: This function does NOT attempt to parse the template expression(s). It is a\n * best-effort scanner that preserves literal text and normalizes interpolation slots.\n */\nfunction replaceAllTemplateExpressionsWithKey(template: string): string {\n let out = \"\";\n let i = 0;\n while (i < template.length) {\n const start = template.indexOf(\"${\", i);\n if (start < 0) {\n out += template.slice(i);\n break;\n }\n out += template.slice(i, start);\n // Find the closing brace, accounting for nested braces within the interpolation.\n let depth = 1;\n let j = start + 2;\n while (j < template.length && depth > 0) {\n if (template[j] === \"{\") {\n depth++;\n } else if (template[j] === \"}\") {\n depth--;\n }\n j++;\n }\n const end = depth === 0 ? j - 1 : -1;\n if (end < 0) {\n // Malformed; append rest and stop.\n out += template.slice(start);\n break;\n }\n out += \"${key}\";\n i = end + 1;\n }\n return out;\n}\n\n// Internal exports for unit testing (not part of the public plugin API).\nexport const __internal = {\n safeMethodNameFromParts,\n replaceAllTemplateExpressionsWithKey,\n};\n\n/**\n * Resolve/apply a data-testid for an element, record it into dependencies, and append generated POM method content.\n *\n * This respects author-provided data-testid attributes and enforces v-for uniqueness rules when a key placeholder is present.\n */\nexport function applyResolvedDataTestId(args: {\n element: ElementNode;\n componentName: string;\n parentComponentName: string;\n context?: TransformContext | null;\n contextFilename?: string;\n dependencies: IComponentDependencies;\n generatedMethodContentByComponent: Map<string, Set<string>>;\n nativeRole: string;\n preferredGeneratedValue: AttributeValue;\n bestKeyPlaceholder: string | null;\n /** Optional enumerable key values (e.g. derived from v-for=\"item in ['One','Two']\"). */\n keyValuesOverride?: string[] | null;\n entryOverrides?: Partial<IDataTestId>;\n /**\n * Semantic naming hint used for generating method/property names.\n *\n * IMPORTANT: This exists so we do NOT need to parse the `data-testid` value to\n * derive POM API surface.\n */\n semanticNameHint?: string;\n\n /**\n * Optional fallback semantic hints to use when the primary hint would cause a member-name collision.\n *\n * These are still derived from the Vue template/AST (e.g. static inner text, id/name attributes),\n * never by parsing the data-testid value.\n */\n semanticNameHintAlternates?: string[];\n\n /**\n * Optional semantic merge key for grouping multiple elements into a single POM action.\n *\n * Examples:\n * - click handler identity (e.g. `click:cancel(item.key)`)\n * - navigation target identity (e.g. `to:name:EditIntegrationType`)\n */\n pomMergeKey?: string;\n addHtmlAttribute?: boolean;\n /** Attribute name to use for injection and parsing. Defaults to data-testid. */\n testIdAttribute?: string;\n /**\n * How to handle an author-provided existing test id attribute when we encounter one.\n *\n * - \"preserve\": keep the existing value (default)\n * - \"overwrite\": replace it with the generated value\n * - \"error\": throw to force cleanup/migration\n */\n existingIdBehavior?: \"preserve\" | \"overwrite\" | \"error\";\n\n /**\n * Controls what happens when the generator would emit duplicate POM member names within the same class.\n * - \"error\": throw and fail compilation\n * - \"warn\": warn and append a suffix\n * - \"suffix\": append a suffix silently (default)\n */\n nameCollisionBehavior?: \"error\" | \"warn\" | \"suffix\";\n\n /** Optional warning sink (typically the shared generator logger). */\n warn?: (message: string) => void;\n}): void {\n const addHtmlAttribute = args.addHtmlAttribute ?? true;\n const entryOverrides = args.entryOverrides ?? {};\n const testIdAttribute = args.testIdAttribute ?? \"data-testid\";\n const existingIdBehavior = args.existingIdBehavior ?? \"preserve\";\n const nameCollisionBehavior = args.nameCollisionBehavior ?? \"suffix\";\n const warn = args.warn;\n\n // 1) Resolve effective data-testid (respecting any existing attribute).\n let dataTestId = args.preferredGeneratedValue;\n let fromExisting = false;\n\n const existing = tryGetExistingElementDataTestId(args.element, testIdAttribute);\n if (existing) {\n const loc = args.element.loc?.start;\n const locationHint = loc ? `${loc.line}:${loc.column}` : \"unknown\";\n const file = args.contextFilename ?? \"unknown\";\n const attrLabel = testIdAttribute || \"data-testid\";\n\n if (existingIdBehavior === \"error\") {\n throw new Error(\n `[vue-pom-generator] Found existing ${attrLabel} while existingIdBehavior=\"error\".\\n`\n + `Component: ${args.componentName}\\n`\n + `File: ${file}:${locationHint}\\n`\n + `Existing ${attrLabel}: ${JSON.stringify(existing.value)}\\n\\n`\n + `Fix: remove the explicit ${attrLabel}, or change existingIdBehavior to \"preserve\" or \"overwrite\".`,\n );\n }\n\n if (existingIdBehavior === \"preserve\") {\n // Preserve only when the existing id can be used as a stable selector at test runtime.\n // - Static literals are always OK.\n // - Template literals are ONLY allowed when they contain exactly one interpolation and\n // that interpolation is the v-for key placeholder we inferred (when present).\n // - All other dynamic expressions are rejected (they would serialize to e.g. \"__props.name\").\n\n if (existing.isDynamic) {\n if (existing.template) {\n if ((existing.templateExpressionCount ?? 0) !== 1) {\n throw new Error(\n `[vue-pom-generator] Existing ${attrLabel} is a template literal with multiple interpolations and cannot be preserved safely.\\n`\n + `Component: ${args.componentName}\\n`\n + `File: ${file}:${locationHint}\\n`\n + `Existing ${attrLabel}: ${JSON.stringify(existing.value)}\\n\\n`\n + `Fix: reduce the template to a single key-based interpolation, or remove the explicit ${attrLabel} so it can be auto-generated.`,\n );\n }\n\n if (args.bestKeyPlaceholder && !existing.template.includes(args.bestKeyPlaceholder)) {\n throw new Error(\n `[vue-pom-generator] Existing ${attrLabel} appears to be missing the key placeholder needed to keep it unique.\\n`\n + `Component: ${args.componentName}\\n`\n + `File: ${file}:${locationHint}\\n`\n + `Existing ${attrLabel}: ${JSON.stringify(existing.value)}\\n`\n + `Required placeholder: ${JSON.stringify(args.bestKeyPlaceholder)}\\n\\n`\n + `Fix: either (1) include ${args.bestKeyPlaceholder} in your :${attrLabel} template literal, or (2) remove the explicit ${attrLabel} so it can be auto-generated.`,\n );\n }\n\n dataTestId = templateAttributeValue(existing.template);\n fromExisting = true;\n }\n else {\n throw new Error(\n `[vue-pom-generator] Existing ${attrLabel} is dynamic and cannot be preserved as a stable runtime selector.\\n`\n + `Component: ${args.componentName}\\n`\n + `File: ${file}:${locationHint}\\n`\n + `Existing ${attrLabel} expression: ${JSON.stringify(existing.rawExpression ?? existing.value)}\\n\\n`\n + `Fix: change it to a string literal (e.g. ${attrLabel}=\"foo\" or :${attrLabel}=\"'foo'\") or remove the explicit ${attrLabel} so it can be auto-generated.\\n`\n + `If you really need a computed id, do not set existingIdBehavior=\"preserve\".`,\n );\n }\n }\n else {\n if (args.bestKeyPlaceholder && existing.isStaticLiteral) {\n throw new Error(\n `[vue-pom-generator] Existing ${attrLabel} appears to be missing the key placeholder needed to keep it unique.\\n`\n + `Component: ${args.componentName}\\n`\n + `File: ${file}:${locationHint}\\n`\n + `Existing ${attrLabel}: ${JSON.stringify(existing.value)}\\n`\n + `Required placeholder: ${JSON.stringify(args.bestKeyPlaceholder)}\\n\\n`\n + `Fix: either (1) include ${args.bestKeyPlaceholder} in your :${attrLabel} template literal, or (2) remove the explicit ${attrLabel} so it can be auto-generated.`,\n );\n }\n\n dataTestId = staticAttributeValue(existing.value);\n fromExisting = true;\n }\n }\n // existingIdBehavior === \"overwrite\": ignore existing and proceed with generated id.\n }\n\n // 2) Derive method naming/params WITHOUT parsing the data-testid string.\n //\n // We only ever use the data-testid value as *data* (the selector string).\n // POM *shape* (method names, params) comes from semantic hints + Vue/Babel AST-derived\n // signals collected during the transform phase.\n\n const getKeyTypeFromValues = (values: string[] | null | undefined) => {\n if (!values || values.length === 0) {\n return \"string\";\n }\n return values.map(v => JSON.stringify(v)).join(\" | \");\n };\n\n const keyTypeFromValues = getKeyTypeFromValues(args.keyValuesOverride ?? null);\n\n const normalizeNativeRole = (value: string): NativeRole | undefined => {\n const role = (value || \"\").toLowerCase();\n switch (role) {\n case \"button\":\n case \"input\":\n case \"select\":\n case \"vselect\":\n case \"checkbox\":\n case \"toggle\":\n case \"radio\":\n return role;\n default:\n return undefined;\n }\n };\n\n const normalizedRole: NativeRole = normalizeNativeRole(args.nativeRole) ?? \"button\";\n\n // NOTE: `targetPageObjectModelClass` is used to decide whether we emit `goToX`.\n // It can be provided via entryOverrides (e.g. router-link :to resolution).\n const targetPageObjectModelClass = entryOverrides.targetPageObjectModelClass;\n\n // Keyed-ness is represented in the selector pattern, not derived by parsing the test id.\n const formattedDataTestIdForPom = dataTestId.kind === \"template\"\n ? replaceAllTemplateExpressionsWithKey(dataTestId.template)\n : dataTestId.value;\n\n const isKeyed = formattedDataTestIdForPom.includes(\"${key}\");\n\n const deriveBaseMethodNameFromHint = (hint: string | undefined) => {\n const hintRaw = (hint ?? \"\").trim();\n const trimEdgeSeparators = (value: string): string => {\n if (!value) {\n return \"\";\n }\n let start = 0;\n let end = value.length;\n const isSep = (ch: string) => ch === \"-\" || ch === \"_\" || ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\";\n while (start < end && isSep(value[start])) {\n start += 1;\n }\n while (end > start && isSep(value[end - 1])) {\n end -= 1;\n }\n return value.slice(start, end);\n };\n\n const hintClean = trimEdgeSeparators(hintRaw);\n\n // If we have no hint, fall back to a role-based name.\n if (!hintClean) {\n const roleName = upperFirst(toPascalCase(normalizedRole));\n return roleName || \"Element\";\n }\n\n // Convert to a safe identifier-ish PascalCase.\n // We intentionally do NOT split/interpret `data-testid` values here.\n const name = toPascalCase(hintClean);\n const safe = safeMethodNameFromParts([name]);\n return safe || \"Element\";\n };\n\n const deriveBaseMethodName = () => {\n return deriveBaseMethodNameFromHint(args.semanticNameHint);\n };\n\n // Ensure the primary method name is unique within the class.\n // IMPORTANT: We do NOT parse data-testid values to generate names. When collisions occur\n // (common for role-based fallbacks like \"Button\"), we append a numeric suffix.\n const removeByKeySegment = (value: string): string => {\n const idx = value.lastIndexOf(\"ByKey\");\n if (idx < 0) {\n return value;\n }\n return value.slice(0, idx) + value.slice(idx + \"ByKey\".length);\n };\n\n const hasRoleSuffix = (baseName: string, roleSuffix: string) => {\n if (baseName.endsWith(roleSuffix)) {\n return true;\n }\n // Treat role + numeric suffix as already-suffixed to avoid awkward names like Button2Button.\n // Example: baseName=Button2, roleSuffix=Button => property should be Button2.\n // eslint-disable-next-line no-restricted-syntax\n const re = new RegExp(`^${roleSuffix}\\\\d+$`);\n return re.test(baseName);\n };\n\n const getPrimaryGetterName = (primaryMethodName: string): string => {\n const roleSuffix = upperFirst(normalizedRole || \"Element\");\n const baseName = upperFirst(primaryMethodName);\n const propertyName = hasRoleSuffix(baseName, roleSuffix) ? baseName : `${baseName}${roleSuffix}`;\n // Keep behavior aligned with TS emitter: keyed getters expose `Foo[key]` by removing `ByKey`.\n return isKeyed ? removeByKeySegment(propertyName) : propertyName;\n };\n\n const getPrimaryGetterNameCandidates = (primaryMethodName: string): { primary: string; alternate?: string } => {\n const roleSuffix = upperFirst(normalizedRole || \"Element\");\n const baseName = upperFirst(primaryMethodName);\n const propertyName = hasRoleSuffix(baseName, roleSuffix) ? baseName : `${baseName}${roleSuffix}`;\n\n if (!isKeyed) {\n return { primary: propertyName };\n }\n\n const stripped = removeByKeySegment(propertyName);\n const kept = propertyName;\n return stripped === kept ? { primary: stripped } : { primary: stripped, alternate: kept };\n };\n\n const getPrimaryActionMethodName = (primaryMethodName: string): string => {\n const methodNameUpper = upperFirst(primaryMethodName);\n const radioMethodNameUpper = upperFirst(primaryMethodName || \"Radio\");\n const isNavigation = !!targetPageObjectModelClass;\n\n if (isNavigation) {\n return `goTo${methodNameUpper}`;\n }\n\n switch (normalizedRole) {\n case \"input\":\n return `type${methodNameUpper}`;\n case \"select\":\n case \"vselect\":\n return `select${methodNameUpper}`;\n case \"radio\":\n return `select${radioMethodNameUpper}`;\n default:\n return `click${methodNameUpper}`;\n }\n };\n\n args.dependencies.reservedPomMemberNames ??= new Set<string>();\n const reservedMembers = args.dependencies.reservedPomMemberNames;\n\n // Internal maps used for merge-by-handler/target.\n args.dependencies.__pomPrimaryByActionName ??= new Map<string, IDataTestId>();\n args.dependencies.__pomPrimaryByGetterName ??= new Map<string, IDataTestId>();\n const primaryByActionName = args.dependencies.__pomPrimaryByActionName;\n\n const hintCandidates = (() => {\n // Keep the existing behavior stable: in warn/suffix modes we suffix based on the primary hint.\n // In error mode, we try provided alternates (typically id/name/label text) before throwing.\n const baseHints: Array<string | undefined> = [args.semanticNameHint];\n if (nameCollisionBehavior === \"error\") {\n baseHints.push(...(args.semanticNameHintAlternates ?? []));\n }\n // De-dupe while preserving order.\n const out: string[] = [];\n const seen = new Set<string>();\n for (const h of baseHints) {\n const v = (h ?? \"\").trim();\n if (!v) {\n continue;\n }\n if (seen.has(v)) {\n continue;\n }\n seen.add(v);\n out.push(v);\n }\n // If we have no usable hints, allow the role-based fallback path.\n if (!out.length) {\n out.push(\"\");\n }\n return out;\n })();\n\n const tryMergeWithExistingPrimary = (candidateActionName: string): boolean => {\n const mergeKey = (args.pomMergeKey ?? \"\").trim();\n if (!mergeKey) {\n return false;\n }\n\n // For keyed selectors we intentionally do NOT merge: the semantics are ambiguous\n // and merged locators would require additional runtime branching.\n if (isKeyed) {\n return false;\n }\n\n const existingEntry = primaryByActionName.get(candidateActionName);\n const existingPom = existingEntry?.pom;\n if (!existingEntry || !existingPom) {\n return false;\n }\n\n if ((existingPom.mergeKey ?? \"\").trim() !== mergeKey) {\n return false;\n }\n\n // Only merge when the semantic behavior matches.\n if (existingPom.nativeRole !== normalizedRole) {\n return false;\n }\n if ((existingEntry.targetPageObjectModelClass ?? null) !== (targetPageObjectModelClass ?? null)) {\n return false;\n }\n\n // Merge the selector(s) into the existing primary.\n if (existingPom.formattedDataTestId !== formattedDataTestIdForPom) {\n existingPom.alternateFormattedDataTestIds ??= [];\n if (!existingPom.alternateFormattedDataTestIds.includes(formattedDataTestIdForPom)) {\n existingPom.alternateFormattedDataTestIds.push(formattedDataTestIdForPom);\n }\n }\n\n return true;\n };\n\n let methodName = \"\";\n let getterNameOverride: string | undefined;\n let mergedIntoExisting = false;\n let collisionDetails: { getterName: string; actionName: string } | null = null;\n let collisionHint: string | null = null;\n\n // Try each hint candidate. In error mode, we only try suffix=1 for each hint.\n for (const hint of hintCandidates) {\n const base = hint ? deriveBaseMethodNameFromHint(hint) : deriveBaseMethodName();\n let suffix = 1;\n\n while (true) {\n const baseWithSuffix = suffix === 1 ? base : `${base}${suffix}`;\n // Keep the ByKey segment at the end so downstream logic (and keyed getter naming)\n // can reliably strip it when needed.\n const candidate = isKeyed ? `${baseWithSuffix}ByKey` : baseWithSuffix;\n\n const actionName = getPrimaryActionMethodName(candidate);\n\n const getterCandidates = getPrimaryGetterNameCandidates(candidate);\n let chosenGetterName = getterCandidates.primary;\n let chosenGetterOverride: string | undefined;\n\n const hasConflicts = (getter: string) => reservedMembers.has(getter)\n || reservedMembers.has(actionName)\n || (args.dependencies.generatedMethods?.has(actionName) ?? false);\n\n let conflicts = hasConflicts(chosenGetterName);\n\n // Edge-case: keyed getter name (FooButton[key]) can collide with a non-keyed FooButton.\n // When that happens, keep the ByKey segment on the keyed getter name.\n if (conflicts && getterCandidates.alternate) {\n const alt = getterCandidates.alternate;\n const altConflicts = hasConflicts(alt);\n if (!altConflicts) {\n chosenGetterName = alt;\n chosenGetterOverride = alt;\n conflicts = false;\n }\n }\n\n // In strict mode (error), prefer trying role-suffixed candidates over hint alternates.\n // This prevents common collisions where different roles share the same semantic hint\n // (e.g. a select + radio bound to the same v-model path), causing actionName clashes\n // like `selectFoo` vs `selectFoo` with different signatures.\n if (conflicts && nameCollisionBehavior === \"error\") {\n const roleSuffix = upperFirst(normalizedRole || \"Element\");\n const baseNameUpper = upperFirst(baseWithSuffix);\n\n // Only try role-suffixing when the base name isn't already role-suffixed.\n if (!hasRoleSuffix(baseNameUpper, roleSuffix)) {\n const baseWithRoleSuffix = `${baseWithSuffix}${roleSuffix}`;\n const candidateWithRoleSuffix = isKeyed ? `${baseWithRoleSuffix}ByKey` : baseWithRoleSuffix;\n const actionNameWithRoleSuffix = getPrimaryActionMethodName(candidateWithRoleSuffix);\n\n const getterCandidatesWithRoleSuffix = getPrimaryGetterNameCandidates(candidateWithRoleSuffix);\n let chosenGetterNameWithRoleSuffix = getterCandidatesWithRoleSuffix.primary;\n let chosenGetterOverrideWithRoleSuffix: string | undefined;\n\n const hasConflictsWithRoleSuffix = (getter: string) => reservedMembers.has(getter)\n || reservedMembers.has(actionNameWithRoleSuffix)\n || (args.dependencies.generatedMethods?.has(actionNameWithRoleSuffix) ?? false);\n\n let conflictsWithRoleSuffix = hasConflictsWithRoleSuffix(chosenGetterNameWithRoleSuffix);\n\n // Preserve keyed edge-case behavior: allow keeping ByKey segment on the getter.\n if (conflictsWithRoleSuffix && getterCandidatesWithRoleSuffix.alternate) {\n const alt = getterCandidatesWithRoleSuffix.alternate;\n const altConflicts = hasConflictsWithRoleSuffix(alt);\n if (!altConflicts) {\n chosenGetterNameWithRoleSuffix = alt;\n chosenGetterOverrideWithRoleSuffix = alt;\n conflictsWithRoleSuffix = false;\n }\n }\n\n if (!conflictsWithRoleSuffix) {\n methodName = candidateWithRoleSuffix;\n getterNameOverride = chosenGetterOverrideWithRoleSuffix;\n reservedMembers.add(chosenGetterNameWithRoleSuffix);\n reservedMembers.add(actionNameWithRoleSuffix);\n break;\n }\n }\n }\n\n if (!conflicts) {\n methodName = candidate;\n getterNameOverride = chosenGetterOverride;\n\n if (collisionDetails && nameCollisionBehavior === \"warn\") {\n const loc = args.element.loc?.start;\n const locationHint = loc ? `${loc.line}:${loc.column}` : \"unknown\";\n const file = args.contextFilename ?? args.dependencies.filePath ?? \"unknown\";\n const hintLabel = (args.semanticNameHint ?? \"\").trim() || \"<none>\";\n (warn ?? ((m) => console.warn(`[vue-pom-generator] ${m}`)))(\n `[pom] member-name collision in ${args.parentComponentName} (${file}:${locationHint}). `\n + `role=${normalizedRole}, semanticNameHint=${JSON.stringify(hintLabel)}. `\n + `Conflicts: getter=${collisionDetails.getterName}, method=${collisionDetails.actionName}. `\n + `Using suffixed name: ${candidate}.`,\n );\n }\n\n reservedMembers.add(chosenGetterName);\n reservedMembers.add(actionName);\n break;\n }\n\n // Merge-by-handler/target: when we would otherwise throw in error mode, allow\n // multiple elements that share the same semantic action to converge on a single\n // POM member (getter/action). The primary spec is mutated to include alternate\n // test id candidates.\n if (nameCollisionBehavior === \"error\" && tryMergeWithExistingPrimary(actionName)) {\n methodName = candidate;\n mergedIntoExisting = true;\n break;\n }\n\n if (!collisionDetails) {\n collisionDetails = { getterName: chosenGetterName, actionName };\n collisionHint = hint || (args.semanticNameHint ?? \"\").trim() || null;\n }\n\n // In error mode, do not suffix; instead, try the next hint candidate.\n if (nameCollisionBehavior === \"error\") {\n break;\n }\n\n suffix += 1;\n }\n\n if (methodName) {\n break;\n }\n }\n\n if (!methodName) {\n const loc = args.element.loc?.start;\n const locationHint = loc ? `${loc.line}:${loc.column}` : \"unknown\";\n const file = args.contextFilename ?? args.dependencies.filePath ?? \"unknown\";\n const hint = (collisionHint ?? \"<none>\").trim() || \"<none>\";\n const last = collisionDetails ?? { getterName: \"<unknown>\", actionName: \"<unknown>\" };\n\n throw new Error(\n `[vue-pom-generator] POM member-name collision in ${args.parentComponentName} (${file}:${locationHint}).\\n`\n + `role=${normalizedRole}, semanticNameHint=${JSON.stringify(hint)}\\n`\n + `Conflicts: getter=${last.getterName}, method=${last.actionName}\\n\\n`\n + `Fix: make the element identifiable (e.g. add id/name/inner text or use a more specific click handler name), `\n + `or switch generation.nameCollisionBehavior to \\\"warn\\\"/\\\"suffix\\\".`,\n );\n }\n\n const params: Record<string, string> = {};\n if (isKeyed) {\n params.key = keyTypeFromValues;\n }\n\n switch (normalizedRole) {\n case \"input\":\n params.text = \"string\";\n params.annotationText = \"string = \\\"\\\"\";\n delete params.key;\n break;\n case \"select\":\n params.value = \"string\";\n params.annotationText = \"string = \\\"\\\"\";\n delete params.key;\n break;\n case \"vselect\":\n params.value = \"string\";\n params.timeOut = \"number = 500\";\n params.annotationText = \"string = \\\"\\\"\";\n delete params.key;\n break;\n case \"radio\":\n // radio can be keyed (e.g. `${key}` option ids) or not.\n params.annotationText = \"string = \\\"\\\"\";\n break;\n default:\n break;\n }\n\n // If the caller provided enumerable key values (e.g. derived from a static v-for list),\n // propagate a literal-union type into the underlying keyed locator method signature.\n if (keyTypeFromValues !== \"string\" && Object.prototype.hasOwnProperty.call(params, \"key\")) {\n params.key = keyTypeFromValues;\n }\n\n // 3) Apply attribute (only when we generated it) and register for POM generation.\n if (addHtmlAttribute && !fromExisting) {\n upsertAttribute(args.element, testIdAttribute, dataTestId);\n }\n\n const childComponentName = args.element.tag;\n const dataTestIdEntry: IDataTestId = {\n value: getAttributeValueText(dataTestId),\n templateLiteral: undefined,\n ...entryOverrides,\n };\n\n // Store the primary POM spec so emitters can generate POMs for multiple languages.\n // Some special cases will mark emitPrimary=false and instead add extra methods.\n dataTestIdEntry.pom = {\n nativeRole: normalizedRole,\n methodName,\n getterNameOverride,\n formattedDataTestId: formattedDataTestIdForPom,\n alternateFormattedDataTestIds: undefined,\n mergeKey: args.pomMergeKey,\n params,\n keyValuesOverride: args.keyValuesOverride ?? null,\n // emitPrimary defaults to true; special cases (including merge) may set it to false below.\n };\n\n if (mergedIntoExisting && dataTestIdEntry.pom) {\n dataTestIdEntry.pom.emitPrimary = false;\n }\n\n args.dependencies.childrenComponentSet.add(childComponentName);\n args.dependencies.usedComponentSet.add(childComponentName);\n args.dependencies.dataTestIdSet.add(dataTestIdEntry);\n\n const getGeneratedMethodName = () => {\n const role = normalizedRole;\n const isNavigation = !!dataTestIdEntry.targetPageObjectModelClass;\n\n const methodNameUpper = upperFirst(methodName);\n const radioMethodNameUpper = upperFirst(methodName || \"Radio\");\n\n if (isNavigation) {\n return `goTo${methodNameUpper}`;\n }\n\n switch (role) {\n case \"input\":\n return `type${methodNameUpper}`;\n case \"select\":\n case \"vselect\":\n return `select${methodNameUpper}`;\n case \"radio\":\n return `select${radioMethodNameUpper}`;\n default:\n return `click${methodNameUpper}`;\n }\n };\n\n const getSignatureForGeneratedMethod = () => {\n const role = normalizedRole;\n const isNavigation = !!dataTestIdEntry.targetPageObjectModelClass;\n const needsKey = Object.prototype.hasOwnProperty.call(params, \"key\");\n const keyType = keyTypeFromValues;\n\n if (isNavigation) {\n if (needsKey) {\n return { params: `key: ${keyType}`, argNames: [\"key\"] };\n }\n return { params: \"\", argNames: [] };\n }\n\n switch (role) {\n case \"input\":\n return { params: \"text: string, annotationText: string = \\\"\\\"\", argNames: [\"text\", \"annotationText\"] };\n case \"select\":\n return { params: \"value: string, annotationText: string = \\\"\\\"\", argNames: [\"value\", \"annotationText\"] };\n case \"vselect\":\n return { params: \"value: string, timeOut = 500\", argNames: [\"value\", \"timeOut\"] };\n case \"radio\":\n return needsKey\n ? { params: `key: ${keyType}, annotationText: string = \"\"`, argNames: [\"key\", \"annotationText\"] }\n : { params: \"annotationText: string = \\\"\\\"\", argNames: [\"annotationText\"] };\n default:\n if (needsKey) {\n return { params: `key: ${keyType}`, argNames: [\"key\"] };\n }\n return { params: \"\", argNames: [] };\n }\n };\n\n const registerPrimaryOnce = (pom: PomPrimarySpec) => {\n const stableParams = pom.params\n ? Object.fromEntries(Object.entries(pom.params).sort((a, b) => a[0].localeCompare(b[0])))\n : undefined;\n\n const alternates = (pom.alternateFormattedDataTestIds ?? []).slice().sort();\n\n // Deduplicate by a stable key rather than by emitted code strings.\n const key = JSON.stringify({\n kind: \"primary\",\n role: pom.nativeRole,\n methodName: pom.methodName,\n getterNameOverride: pom.getterNameOverride ?? null,\n formattedDataTestId: pom.formattedDataTestId,\n alternateFormattedDataTestIds: alternates.length ? alternates : undefined,\n params: stableParams,\n target: dataTestIdEntry.targetPageObjectModelClass ?? null,\n emitPrimary: pom.emitPrimary ?? true,\n });\n\n const seen = args.generatedMethodContentByComponent.get(args.parentComponentName) ?? new Set<string>();\n if (!args.generatedMethodContentByComponent.has(args.parentComponentName)) {\n args.generatedMethodContentByComponent.set(args.parentComponentName, seen);\n }\n if (!seen.has(key)) {\n seen.add(key);\n dataTestIdEntry.pom = pom;\n }\n };\n\n const addExtraClickMethod = (spec: PomExtraClickMethodSpec): boolean => {\n const stableParams = spec.params\n ? Object.fromEntries(Object.entries(spec.params).sort((a, b) => a[0].localeCompare(b[0])))\n : undefined;\n\n // IMPORTANT:\n // De-dupe based on semantic identity (testId+params+keyLiteral), not the emitted method name.\n // This prevents repeated passes over the same element from generating new unique names\n // (e.g. selectFoo -> selectFoo2) and growing the output.\n const key = JSON.stringify({ kind: spec.kind, testId: spec.formattedDataTestId, keyLiteral: spec.keyLiteral ?? null, params: stableParams });\n const seen = args.generatedMethodContentByComponent.get(args.parentComponentName) ?? new Set<string>();\n if (!args.generatedMethodContentByComponent.has(args.parentComponentName)) {\n args.generatedMethodContentByComponent.set(args.parentComponentName, seen);\n }\n if (seen.has(key)) {\n return false;\n }\n seen.add(key);\n args.dependencies.pomExtraMethods ??= [];\n args.dependencies.pomExtraMethods.push(spec);\n return true;\n };\n\n const registerGeneratedMethodSignature = (name: string, signature: { params: string; argNames: string[] } | null) => {\n args.dependencies.generatedMethods ??= new Map<string, { params: string; argNames: string[] } | null>();\n const prev = args.dependencies.generatedMethods.get(name);\n if (prev === undefined) {\n args.dependencies.generatedMethods.set(name, signature);\n return;\n }\n if (prev === null) {\n return;\n }\n if (signature === null || prev.params !== signature.params) {\n args.dependencies.generatedMethods.set(name, null);\n }\n };\n\n const reservedGeneratedNames = new Set<string>();\n const ensureUniqueGeneratedName = (baseName: string) => {\n let candidate = baseName;\n let i = 2;\n while (\n reservedGeneratedNames.has(candidate)\n || (args.dependencies.generatedMethods?.has(candidate) ?? false)\n ) {\n candidate = `${baseName}${i}`;\n i += 1;\n }\n reservedGeneratedNames.add(candidate);\n return candidate;\n };\n\n const tryGetDirectiveExpressionAst = (dir: DirectiveNode): BabelNode | null => {\n const exp = dir.exp;\n if (!exp) {\n return null;\n }\n\n // Prefer Vue-populated `exp.ast` when present.\n if (exp.type === NodeTypes.SIMPLE_EXPRESSION) {\n const simple = exp as SimpleExpressionNode;\n const ast = simple.ast as object | null;\n if (ast && \"type\" in ast) {\n return ast as BabelNode;\n }\n }\n\n // Fallback: parse the expression source.\n try {\n const raw = args.context ? stringifyExpression(exp) : exp.loc.source;\n return parseExpression(raw, { plugins: [\"typescript\"] }) as BabelNode;\n }\n catch {\n return null;\n }\n };\n\n const tryGetStaticStringFromBabel = (node: BabelNode | null): string | null => {\n if (!node) {\n return null;\n }\n if (isStringLiteral(node)) {\n return node.value;\n }\n if (isTemplateLiteral(node)) {\n // Only treat template literals with no expressions as static.\n if ((node.expressions ?? []).length > 0) {\n return null;\n }\n return (node.quasis ?? []).map(q => q.value?.cooked ?? \"\").join(\"\");\n }\n return null;\n };\n\n const tryExtractStaticOptionLabelsFromOptionsAst = (optionsAst: BabelNode): string[] | null => {\n if (!isArrayExpression(optionsAst)) {\n return null;\n }\n\n const arr = optionsAst as ArrayExpression;\n const out: string[] = [];\n\n for (const el of (arr.elements ?? [])) {\n if (!el) {\n continue;\n }\n\n // Allow array-of-strings: [\"A\", \"B\"]\n const literal = tryGetStaticStringFromBabel(el as BabelNode);\n if (literal !== null) {\n if (literal.trim()) {\n out.push(literal);\n }\n continue;\n }\n\n // Allow array-of-objects: [{ text: \"A\" }, { label: \"B\" }]\n if (!isObjectExpression(el as BabelNode)) {\n return null;\n }\n const obj = el as ObjectExpression;\n\n const labelKeys = new Set([\"text\", \"label\", \"name\", \"title\"]);\n const props = (obj.properties ?? []) as unknown[];\n\n const findProp = () => {\n for (const p of props) {\n if (!p || typeof p !== \"object\") {\n continue;\n }\n const prop = p as BabelNode;\n if (!isObjectProperty(prop)) {\n continue;\n }\n const op = prop as ObjectProperty;\n const keyNode = op.key;\n const keyName = isIdentifier(keyNode)\n ? keyNode.name\n : (isStringLiteral(keyNode) ? keyNode.value : \"\");\n if (!labelKeys.has(keyName)) {\n continue;\n }\n return op;\n }\n return null;\n };\n\n const labelProp = findProp();\n if (!labelProp) {\n return null;\n }\n\n const label = tryGetStaticStringFromBabel(labelProp.value as BabelNode);\n if (label === null || !label.trim()) {\n return null;\n }\n out.push(label);\n }\n\n return out.length ? out : null;\n };\n\n // Special handling for option-driven wrappers.\n // If an element has an `:options` directive and represents a radio-group-like wrapper,\n // attempt to generate more ergonomic per-option methods.\n const roleForOptions = normalizedRole;\n const optionsDirective = findDirectiveByName(args.element, \"bind\", \"options\");\n const canHandleOptions = roleForOptions === \"radio\" && !!optionsDirective?.exp;\n\n if (canHandleOptions) {\n // The wrapper data-testid is typically: `${prefix}-radio`.\n // The option data-testid is typically: `${prefix}_${OptionText}_radio`.\n const wrapperTestId = formattedDataTestIdForPom;\n const prefix = wrapperTestId.endsWith(\"-radio\")\n ? wrapperTestId.slice(0, -\"-radio\".length)\n : wrapperTestId;\n\n const optionsAst = optionsDirective ? tryGetDirectiveExpressionAst(optionsDirective) : null;\n const staticLabels = optionsAst ? tryExtractStaticOptionLabelsFromOptionsAst(optionsAst) : null;\n\n // We derive the base method name from the existing methodName, but strip the \"Radio\" suffix\n // so option methods read like `selectFooBarBaz()` instead of `selectFooBarRadioBaz()`.\n const base = methodName.endsWith(\"Radio\") ? methodName.slice(0, -\"Radio\".length) : methodName;\n const baseUpper = upperFirst(base || \"Radio\");\n\n if (staticLabels && staticLabels.length) {\n // Match legacy behavior: when we can enumerate static options, we only generate per-option\n // helpers and skip the generic select/click method for the wrapper.\n if (dataTestIdEntry.pom) {\n dataTestIdEntry.pom.emitPrimary = false;\n registerPrimaryOnce(dataTestIdEntry.pom);\n }\n for (const label of staticLabels) {\n const optionPart = getDataTestIdFromGroupOption(label);\n if (!optionPart) {\n continue;\n }\n\n const optionTestId = `${prefix}_${optionPart}_radio`;\n const safeOptionSuffix = toPascalCase(label) || optionPart;\n const generatedName = ensureUniqueGeneratedName(`select${baseUpper}${safeOptionSuffix}`);\n\n const added = addExtraClickMethod({\n kind: \"click\",\n name: generatedName,\n formattedDataTestId: optionTestId,\n params: { annotationText: `string = \"\"` },\n });\n\n if (added) {\n registerGeneratedMethodSignature(generatedName, { params: `annotationText: string = \"\"`, argNames: [\"annotationText\"] });\n }\n }\n\n // For statically-known options, we intentionally do NOT generate the generic parameterized method.\n return;\n }\n\n // Dynamic options expression: generate a single method that accepts an option string.\n // We build the option test id using the provided value directly.\n const generatedName = ensureUniqueGeneratedName(`select${upperFirst(methodName || \"Radio\")}`);\n\n if (dataTestIdEntry.pom) {\n dataTestIdEntry.pom.emitPrimary = false;\n registerPrimaryOnce(dataTestIdEntry.pom);\n }\n\n // Dynamic options expression: generate a single method that accepts an option string.\n const added = addExtraClickMethod({\n kind: \"click\",\n name: generatedName,\n formattedDataTestId: `${prefix}_${\"${value}\"}_radio`,\n params: { value: \"string\", annotationText: `string = \"\"` },\n });\n\n if (added) {\n registerGeneratedMethodSignature(generatedName, { params: `value: string, annotationText: string = \"\"`, argNames: [\"value\", \"annotationText\"] });\n }\n return;\n }\n\n // Special handling for v-for driven by a static literal list.\n // When we can enumerate the keys (e.g. ['One','Two']), prefer emitting separate\n // methods like `clickOneButton()` / `clickTwoButton()` instead of a single\n // `click*ByKey(key: ...)`.\n //\n // This keeps the POM ergonomic and avoids pushing key plumbing into tests.\n const staticKeyValues = (args.keyValuesOverride ?? null);\n const needsKey = Object.prototype.hasOwnProperty.call(params, \"key\")\n && typeof formattedDataTestIdForPom === \"string\"\n && formattedDataTestIdForPom.includes(\"${key}\");\n const isNavigation = !!dataTestIdEntry.targetPageObjectModelClass;\n\n if (\n staticKeyValues\n && staticKeyValues.length > 0\n && needsKey\n && !isNavigation\n && normalizedRole !== \"input\"\n && normalizedRole !== \"select\"\n && normalizedRole !== \"vselect\"\n && normalizedRole !== \"radio\"\n ) {\n if (dataTestIdEntry.pom) {\n dataTestIdEntry.pom.emitPrimary = false;\n registerPrimaryOnce(dataTestIdEntry.pom);\n }\n\n const roleSuffix = upperFirst(toPascalCase(args.nativeRole || \"Element\"));\n\n for (const rawValue of staticKeyValues) {\n const valueName = toPascalCase(rawValue);\n if (!valueName) {\n continue;\n }\n\n const generatedName = ensureUniqueGeneratedName(`click${valueName}${roleSuffix}`);\n\n const added = addExtraClickMethod({\n kind: \"click\",\n name: generatedName,\n formattedDataTestId: formattedDataTestIdForPom,\n keyLiteral: rawValue,\n params: { wait: \"boolean = true\" },\n });\n\n if (added) {\n registerGeneratedMethodSignature(generatedName, { params: `wait: boolean = true`, argNames: [\"wait\"] });\n }\n }\n\n // For statically-known keys, we intentionally do NOT emit the generic keyed method.\n return;\n }\n\n // Default/legacy behavior: emit the primary method+locator for this element.\n if (dataTestIdEntry.pom) {\n // Register merge lookup only for emitted primaries.\n if (dataTestIdEntry.pom.emitPrimary !== false) {\n const actionName = getGeneratedMethodName();\n primaryByActionName.set(actionName, dataTestIdEntry);\n const getterName = dataTestIdEntry.pom.getterNameOverride ?? getPrimaryGetterName(methodName);\n args.dependencies.__pomPrimaryByGetterName?.set(getterName, dataTestIdEntry);\n }\n\n registerPrimaryOnce(dataTestIdEntry.pom);\n const signature = getSignatureForGeneratedMethod();\n const generatedName = getGeneratedMethodName();\n registerGeneratedMethodSignature(generatedName, signature);\n }\n}\n\nexport interface IDataTestId {\n value: string;\n\n /** Optional parsed/constructed template literal for AST-based formatting in codegen. */\n templateLiteral?: TemplateLiteral;\n /** When the element is a router-link-like navigation, the resolved target page class name (e.g. TenantDetailsPage). */\n targetPageObjectModelClass?: string;\n\n /**\n * Generator-provided Page Object Model info for this element.\n *\n * IMPORTANT: This exists so emitters (TS/C#) can generate the POM API without\n * ever needing to parse the `data-testid` string itself.\n */\n pom?: PomPrimarySpec;\n}\n\n/**\n * Structured representation of a generated element for POM emission.\n *\n * - `formattedDataTestId` may contain the placeholder `${key}` when keyed.\n * - `params` is TypeScript-flavored today because TS is our reference emitter;\n * C# emission maps these params to C# types.\n */\nexport interface PomPrimarySpec {\n nativeRole: NativeRole;\n /** Base semantic name (PascalCase). Verb prefixes are added by emitters. */\n methodName: string;\n /** Optional override for the generated locator getter name (used for edge-case collision avoidance). */\n getterNameOverride?: string;\n /** Test id pattern used by generated POM methods (may include `${key}` placeholder). */\n formattedDataTestId: string;\n /** Additional test id patterns that should be treated as equivalent to formattedDataTestId (merge-by-action). */\n alternateFormattedDataTestIds?: string[];\n\n /** Optional key used to decide whether distinct elements should be merged into one POM member. */\n mergeKey?: string;\n /** TypeScript param blocks used by the TS emitter (and signature metadata). */\n params: Record<string, string>;\n /** Optional enum values for key when derived from a static v-for list. */\n keyValuesOverride?: string[] | null;\n\n /** When false, emitters should NOT emit the primary method/locator for this entry. */\n emitPrimary?: boolean;\n}\n\n/**\n * Extra generated methods that are not a 1:1 mapping of an element's primary role.\n *\n * Examples:\n * - per-option radio helpers (selectFooBarBaz)\n * - per-key v-for helpers (clickOneButton/clickTwoButton)\n */\nexport interface PomExtraClickMethodSpec {\n kind: \"click\";\n name: string;\n /** Static or keyed test id; keyed uses `${key}` placeholder. */\n formattedDataTestId: string;\n /** Optional fixed key to substitute into `${key}` in the method body. */\n keyLiteral?: string;\n params: Record<string, string>;\n}\n\nexport interface IComponentDependencies {\n filePath: string;\n childrenComponentSet: Set<string>; // all child components used in this component\n /**\n * All component-like tags encountered in the template (PascalCase or kebab-case).\n *\n * Unlike childrenComponentSet, this is NOT gated by whether a data-testid was generated\n * for that element.\n */\n usedComponentSet: Set<string>;\n dataTestIdSet: Set<IDataTestId>; // all data-testid values used in this component\n /** Optional cached codegen output so buildEnd can skip re-deriving method strings. */\n methodsContent?: string;\n /**\n * Structured metadata about generated methods.\n *\n * Used by aggregated stub generation to safely emit pass-through methods\n * (e.g. NewTenantPage.typeTenantName delegates to TenantDetailsEditForm.typeTenantName)\n * without re-parsing the generated TypeScript.\n *\n * - key: method name\n * - value: { params, argNames } when the signature is known and consistent\n * null when multiple distinct signatures were observed for the same name\n */\n generatedMethods?: Map<string, { params: string; argNames: string[] } | null>;\n isView?: boolean;\n\n /**\n * Extra methods emitted for this component/view (beyond the primary per-element methods).\n * These are stored as structured specs so additional language emitters can mirror behavior.\n */\n pomExtraMethods?: PomExtraClickMethodSpec[];\n\n /**\n * Internal: names reserved for generated members (getters + methods) to avoid collisions.\n *\n * This is populated during transform-time collection so the generator never needs to\n * parse `data-testid` values to disambiguate names.\n */\n reservedPomMemberNames?: Set<string>;\n\n /**\n * Internal: lookup of already-emitted primaries by their generated action method name.\n * Used to merge multiple elements with the same click handler / navigation target.\n */\n __pomPrimaryByActionName?: Map<string, IDataTestId>;\n\n /** Internal: lookup of already-emitted primaries by their generated getter name. */\n __pomPrimaryByGetterName?: Map<string, IDataTestId>;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { pathToFileURL } from \"node:url\";\nimport { toPascalCase } from \"./utils\";\nimport type { Router, RouteLocationNormalizedLoaded, RouteRecordNormalized } from \"vue-router\";\nimport { JSDOM } from \"jsdom\";\nimport type { Plugin as VitePlugin } from \"vite\";\n\n// Router introspection spins up a short-lived Vite SSR server and installs a global DOM shim.\n// When called concurrently (e.g. multiple Vitest files running in parallel), those operations can\n// interfere with each other and lead to hangs/timeouts. Serialize calls within a single process.\nlet routerIntrospectionQueue: Promise<void> = Promise.resolve();\n\nasync function runRouterIntrospectionExclusive<T>(fn: () => Promise<T>): Promise<T> {\n const prev = routerIntrospectionQueue.catch(() => undefined);\n let release!: () => void;\n const next = new Promise<void>((resolve) => {\n release = resolve;\n });\n routerIntrospectionQueue = prev.then(() => next);\n\n await prev;\n try {\n return await fn();\n }\n finally {\n release();\n }\n}\n\nfunction debugLog(message: string) {\n if (process.env.VUE_TESTID_DEBUG === \"1\") {\n console.log(`[vue-pom-generator][router-introspection] ${message}`);\n }\n}\n\nfunction createRouterIntrospectionVueStubPlugin(options: { routerEntryAbs: string }): VitePlugin {\n const routerEntryAbs = path.resolve(options.routerEntryAbs);\n return {\n name: \"vue-testid-router-introspection-vue-stub\",\n enforce: \"pre\",\n load(id) {\n // Vite passes plugin `load(id)` a *resolved* id. In practice this is usually a normalized absolute\n // filesystem path (posix separators) or a Vite fs-prefixed path like `/@fs/<abs>`, optionally with\n // a query string (e.g. `?v=...`). Virtual ids (starting with `\\0`) may also appear.\n //\n // During router introspection we want to:\n // - Allow loading the router entry itself\n // - Stub `.vue` imports with a minimal component object\n // - Reject everything else (especially node_modules)\n\n // Strip query string (e.g. ?v=... or ?import).\n const queryIndex = id.indexOf(\"?\");\n const cleanId = queryIndex === -1 ? id : id.slice(0, queryIndex);\n\n // Virtual modules should not be handled here.\n if (cleanId.startsWith(\"\\0\"))\n return null;\n\n // During SSR evaluation Vite may pass internal ids that are not filesystem paths.\n // Let Vite handle those rather than throwing and aborting router introspection.\n if (\n cleanId.startsWith(\"node:\")\n || cleanId.startsWith(\"virtual:\")\n || cleanId.startsWith(\"vite:\")\n || cleanId.startsWith(\"/@id/\")\n ) {\n return null;\n }\n\n // Handle Vite /@fs/ prefix (absolute filesystem path outside root).\n const fsPath = cleanId.startsWith(\"/@fs/\") ? cleanId.slice(\"/@fs/\".length) : cleanId;\n\n // Always allow the router entry itself to be loaded by Vite/Node.\n // Note: Vite may normalize paths with posix separators. We always compare resolved absolute paths.\n if (path.isAbsolute(fsPath) && path.resolve(fsPath) === routerEntryAbs)\n return null;\n\n // If this still isn't a filesystem absolute path, it's not something we should stub.\n // Returning null means \"not handled\".\n if (!path.isAbsolute(fsPath))\n return null;\n\n // Disallow anything from node_modules during router introspection.\n // This keeps SSR evaluation from pulling in problematic CJS/Esm interop (e.g. devextreme).\n if (fsPath.includes(`${path.sep}node_modules${path.sep}`) || fsPath.includes(\"/node_modules/\"))\n throw new Error(`[vue-pom-generator][router-introspection] Unsupported node_modules import during router introspection: ${cleanId}`);\n\n const parsed = path.parse(fsPath);\n\n // Only `.ts/.tsx` (router code) and `.vue` (stubs) are permitted.\n if (parsed.ext !== \".vue\") {\n if (parsed.ext === \".ts\" || parsed.ext === \".tsx\")\n return null;\n throw new Error(`[vue-pom-generator][router-introspection] Unsupported module during router introspection: ${cleanId}`);\n }\n\n // Minimal Vue component stub. Preserve __file so downstream can infer a component name.\n const componentName = path.basename(parsed.base, \".vue\");\n return `export default { name: ${JSON.stringify(componentName)}, __file: ${JSON.stringify(cleanId)} }`;\n },\n };\n}\n\nexport interface RouterIntrospectionResult {\n routeNameMap: Map<string, string>;\n routePathMap: Map<string, string>;\n routeMetaEntries: Array<{\n componentName: string;\n pathTemplate: string;\n params: Array<{ name: string; optional: boolean }>;\n query: string[];\n }>;\n}\n\ninterface HistoryLike {\n pushState: (...args: never[]) => void;\n replaceState: (...args: never[]) => void;\n}\n\ninterface GlobalDomShim {\n // JSDOM's DOMWindow is not assignable to TS lib.dom Window, so keep this structural.\n window?: object;\n document?: Document;\n location?: object;\n navigator?: object;\n history?: HistoryLike;\n MutationObserver?: object;\n ResizeObserver?: object;\n IntersectionObserver?: object;\n // In browsers these typically return a number; in Node our polyfills return the value from setTimeout.\n requestIdleCallback?: (cb: (deadline: { didTimeout: boolean; timeRemaining: () => number }) => void) => number | ReturnType<typeof setTimeout>;\n requestAnimationFrame?: (cb: (time: number) => void) => number | ReturnType<typeof setTimeout>;\n localStorage?: Storage;\n sessionStorage?: Storage;\n [key: string]:\n | object\n | string\n | number\n | boolean\n | null\n | undefined\n | ((...args: never[]) => object);\n}\n\ntype DocumentWithQueryCommandSupported = Document & {\n queryCommandSupported?: (commandId: string) => boolean;\n};\n\ninterface VueComponentLike {\n __file?: string;\n __name?: string;\n name?: string;\n}\n\ntype RoutePropPrimitive = string | number | boolean | null | undefined;\ntype RoutePropsFunction = (route: RouteLocationNormalizedLoaded) => Record<string, RoutePropPrimitive> | void;\ntype RoutePropsValue = boolean | Record<string, RoutePropPrimitive> | RoutePropsFunction;\ntype RoutePropsContainer = RoutePropsValue | { default?: RoutePropsValue };\n\nconst PARAM_TOKEN_PREFIX = \"__VUE_TESTID_PARAM__\";\n\nfunction getParamToken(name: string) {\n return `${PARAM_TOKEN_PREFIX}${name}__`;\n}\n\nfunction collectRoutePropKeysFromFunction(propsFn: RoutePropsFunction) {\n const paramKeys = new Set<string>();\n const queryKeys = new Set<string>();\n\n const paramsProxy = new Proxy({}, {\n get(_target, prop) {\n if (typeof prop === \"string\")\n paramKeys.add(prop);\n return undefined;\n },\n });\n\n const queryProxy = new Proxy({}, {\n get(_target, prop) {\n if (typeof prop === \"string\")\n queryKeys.add(prop);\n return undefined;\n },\n });\n\n const routeProxy = new Proxy({ params: paramsProxy, query: queryProxy }, {\n get(target, prop) {\n if (prop in target)\n return target[prop as keyof typeof target];\n return undefined;\n },\n });\n\n try {\n propsFn(routeProxy as RouteLocationNormalizedLoaded);\n }\n catch {\n // Ignore errors; we only care about which props are accessed.\n }\n\n return {\n paramKeys: Array.from(paramKeys).sort((a, b) => a.localeCompare(b)),\n queryKeys: Array.from(queryKeys).sort((a, b) => a.localeCompare(b)),\n };\n}\n\nfunction getRoutePropsKeys(record: RouteRecordNormalized) {\n const props = record.props as RoutePropsContainer | undefined;\n if (!props) {\n return { paramKeys: [], queryKeys: [] };\n }\n\n const normalized = (typeof props === \"object\" && \"default\" in props)\n ? (props as { default?: RoutePropsValue }).default\n : props;\n\n if (typeof normalized === \"function\")\n return collectRoutePropKeysFromFunction(normalized as RoutePropsFunction);\n\n if (normalized === true) {\n // props: true -> all route.params, but we don't know keys without parsing the path.\n return { paramKeys: [], queryKeys: [] };\n }\n\n if (typeof normalized === \"object\") {\n // Static props object; no route params/query used.\n return { paramKeys: [], queryKeys: [] };\n }\n\n return { paramKeys: [], queryKeys: [] };\n}\n\nfunction buildRouteTemplate(router: Router, record: RouteRecordNormalized, paramNames: string[]) {\n if (typeof record.name !== \"string\" || !record.name.length) {\n return record.path;\n }\n\n const params = Object.fromEntries(paramNames.map((name) => [name, getParamToken(name)]));\n try {\n return router.resolve({ name: record.name, params }).path;\n }\n catch {\n return record.path;\n }\n}\n\nfunction getRouteParamMeta(router: Router, record: RouteRecordNormalized, paramNames: string[]) {\n if (typeof record.name !== \"string\" || !record.name.length) {\n return paramNames.map((name) => ({ name, optional: false }));\n }\n\n const paramsWithAll = Object.fromEntries(paramNames.map((name) => [name, getParamToken(name)]));\n return paramNames.map((name) => {\n const params = { ...paramsWithAll } as Record<string, string>;\n delete params[name];\n try {\n router.resolve({ name: record.name as string, params });\n return { name, optional: true };\n }\n catch {\n return { name, optional: false };\n }\n });\n}\n\nfunction getComponentNameFromRouteRecord(record: RouteRecordNormalized): string | null {\n // Vue Router's normalized record has `components` (plural) where `default` is the main view component.\n const comp = record.components?.default as VueComponentLike | undefined;\n if (!comp)\n return null;\n\n // When compiled by Vite, SFCs usually have an `__file` pointing at the source file.\n if (typeof comp.__file === \"string\" && comp.__file.length) {\n const base = path.posix.basename(path.posix.normalize(comp.__file));\n if (base.toLowerCase().endsWith(\".vue\"))\n return base.slice(0, -\".vue\".length);\n }\n\n // Fallbacks (less stable / may be minified):\n if (typeof comp.__name === \"string\" && comp.__name.length)\n return comp.__name;\n if (typeof comp.name === \"string\" && comp.name.length)\n return comp.name;\n return null;\n}\n\nasync function ensureDomShim() {\n const domShimHtml = \"<!doctype html><html><head></head><body><div id='app'></div></body></html>\";\n const domShimUrl = \"https://example.test/\";\n\n // NOTE: JSDOM's DOMWindow is not assignable to the TS lib.dom Window, but at runtime it behaves well enough\n // for our use (router creation + route enumeration).\n const g = globalThis as GlobalDomShim;\n if (typeof document !== \"undefined\" && typeof window !== \"undefined\")\n return;\n\n const dom = new JSDOM(domShimHtml, { url: domShimUrl });\n\n g.window = dom.window;\n g.document = dom.window.document;\n g.location = dom.window.location;\n if (!g.self)\n g.self = dom.window;\n if (!g.navigator)\n g.navigator = dom.window.navigator;\n if (!g.history)\n g.history = { pushState() { }, replaceState() { } };\n\n if (!g.MutationObserver) {\n g.MutationObserver = class {\n disconnect() { }\n observe() { }\n takeRecords() { return []; }\n };\n }\n if (!g.ResizeObserver) {\n g.ResizeObserver = class {\n disconnect() { }\n observe() { }\n unobserve() { }\n };\n }\n if (!g.IntersectionObserver) {\n g.IntersectionObserver = class {\n disconnect() { }\n observe() { }\n unobserve() { }\n takeRecords() { return []; }\n };\n }\n if (!g.requestIdleCallback) {\n g.requestIdleCallback = cb => setTimeout(() => cb({ didTimeout: false, timeRemaining: () => 0 }), 1);\n }\n\n // Some editor / rich text libs probe this legacy API.\n const doc = g.document as DocumentWithQueryCommandSupported | undefined;\n if (doc && typeof doc.queryCommandSupported !== \"function\") {\n doc.queryCommandSupported = () => false;\n }\n if (!g.localStorage || !g.sessionStorage) {\n const storageFactory = () => {\n const store = new Map<string, string>();\n return {\n getItem: (k: string) => (store.has(k) ? store.get(k)! : null),\n setItem: (k: string, v: string) => { store.set(k, String(v)); },\n removeItem: (k: string) => { store.delete(k); },\n clear: () => { store.clear(); },\n key: (i: number) => Array.from(store.keys())[i] ?? null,\n get length() { return store.size; },\n } as Storage;\n };\n if (!g.localStorage)\n g.localStorage = storageFactory();\n if (!g.sessionStorage)\n g.sessionStorage = storageFactory();\n }\n\n // Copy common DOM constructor globals onto globalThis. Many browser-oriented libs assume these\n // exist as globals (e.g. HTMLAnchorElement, UIEvent) even when running under Node.\n const names = Object.getOwnPropertyNames(dom.window);\n const shouldCopyGlobal = (name: string) => {\n if (name === \"Node\" || name === \"Element\" || name === \"Document\" || name === \"Event\" || name === \"EventTarget\")\n return true;\n if (name.endsWith(\"Event\"))\n return true;\n if (name.startsWith(\"HTML\") && name.endsWith(\"Element\"))\n return true;\n if (name.startsWith(\"SVG\") && name.endsWith(\"Element\"))\n return true;\n return false;\n };\n\n for (const name of names) {\n if (!shouldCopyGlobal(name) || g[name])\n continue;\n\n const value = Reflect.get(dom.window, name);\n if (value)\n g[name] = value;\n }\n\n if (!g.requestAnimationFrame)\n g.requestAnimationFrame = cb => setTimeout(() => cb(Date.now()), 16);\n}\n\n/**\n * Loads this repo's `src/router.ts` via Vite's SSR module loader and asks Vue Router\n * for its normalized routes.\n *\n * This replaces the previous regex-based parsing so we can support nested route shapes,\n * redirects, and any non-trivial route record composition without maintaining a parser.\n */\nexport async function parseRouterFileFromCwd(routerEntryPath: string): Promise<RouterIntrospectionResult> {\n return await runRouterIntrospectionExclusive(async () => {\n const routerEntry = path.resolve(routerEntryPath);\n if (!fs.existsSync(routerEntry)) {\n throw new Error(`[vue-pom-generator] Router entry not found at ${routerEntry}.`);\n }\n\n const cwd = path.dirname(routerEntry);\n\n await ensureDomShim();\n\n debugLog(`parseRouterFileFromCwd cwd=${cwd}`);\n\n // Dynamically import Vite to keep this file Node-only and avoid bundling Vite into consumers.\n const vite = await import(\"vite\") as { createServer: typeof import(\"vite\")[\"createServer\"] };\n\n // IMPORTANT:\n // When vue-pom-generator is included as a plugin inside the frontend Vite config, calling\n // Vite's `createServer()` with the default behavior will read `vite.config.ts` again.\n // Since `vite.config.ts` imports this plugin, that can create a recursive config-load loop.\n //\n // We avoid that by setting `configFile: false` and providing the minimal config we need to\n // SSR-load `src/router.ts` (mainly alias + Vue SFC plugin).\n const server = await vite.createServer({\n root: cwd,\n configFile: false,\n logLevel: \"error\",\n // This server is created only to SSR-load the router module. Disable HMR/WebSocket\n // to avoid port conflicts in dev/test environments.\n server: { middlewareMode: true, hmr: false, ws: false },\n appType: \"custom\",\n // IMPORTANT:\n // This internal, short-lived Vite server exists only to `ssrLoadModule()` the router entry.\n // We close it immediately after reading routes.\n //\n // Vite's dependency optimizer (vite:dep-scan / optimizeDeps) runs asynchronously and can\n // still have pending resolve requests when we call `server.close()`, which surfaces as:\n // \"The server is being restarted or closed. Request is outdated [plugin vite:dep-scan]\"\n //\n // Disable optimizeDeps entirely for this internal server to avoid that race.\n optimizeDeps: {\n disabled: true,\n },\n resolve: {\n alias: {\n \"@\": cwd,\n },\n },\n // Important: Do NOT include @vitejs/plugin-vue here.\n // We stub all `.vue` imports ourselves, and including the Vue plugin would attempt to parse\n // those stubbed modules as real SFCs (and fail).\n plugins: [createRouterIntrospectionVueStubPlugin({ routerEntryAbs: routerEntry })],\n });\n\n try {\n // Use a file URL so we don't depend on platform-specific path separators.\n // Vite can SSR-load file URLs and will treat this as an absolute module id.\n const moduleId = pathToFileURL(routerEntry).href;\n\n debugLog(`ssrLoadModule(${moduleId}) start`);\n const mod = await server.ssrLoadModule(moduleId) as { default?: () => Router };\n debugLog(`ssrLoadModule(${moduleId}) done; hasDefault=${typeof mod?.default === \"function\"}`);\n const makeRouter = mod?.default;\n if (typeof makeRouter !== \"function\") {\n throw new TypeError(`[vue-pom-generator] ${routerEntry} must export a default router factory function (export default makeRouter).`);\n }\n\n let router: Router;\n try {\n router = makeRouter();\n }\n catch (err) {\n throw new Error(`[vue-pom-generator] makeRouter() invocation failed: ${String(err)}`);\n }\n const routeNameMap = new Map<string, string>();\n const routePathMap = new Map<string, string>();\n const routeMetaEntries: RouterIntrospectionResult[\"routeMetaEntries\"] = [];\n\n for (const r of router.getRoutes()) {\n const componentName = getComponentNameFromRouteRecord(r);\n if (!componentName)\n continue;\n\n if (typeof r.path === \"string\" && r.path.length) {\n routePathMap.set(r.path, componentName);\n }\n\n if (typeof r.name === \"string\" && r.name.length) {\n const key = toPascalCase(r.name);\n routeNameMap.set(key, componentName);\n }\n\n const { paramKeys, queryKeys } = getRoutePropsKeys(r);\n const paramsMeta = getRouteParamMeta(router, r, paramKeys);\n const pathTemplate = buildRouteTemplate(router, r, paramsMeta.map((p) => p.name));\n if (typeof pathTemplate === \"string\" && pathTemplate.length) {\n routeMetaEntries.push({\n componentName,\n pathTemplate,\n params: paramsMeta,\n query: queryKeys,\n });\n }\n }\n\n return { routeNameMap, routePathMap, routeMetaEntries };\n }\n finally {\n debugLog(\"closing internal vite server\");\n await server.close();\n }\n });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport { fileURLToPath } from \"node:url\";\nimport { generateViewObjectModelMethodContent } from \"../method-generation\";\nimport { parseRouterFileFromCwd } from \"../router-introspection\";\n// NOTE: This module intentionally does not depend on Babel parsing.\n\nimport { IComponentDependencies, IDataTestId, PomExtraClickMethodSpec, PomPrimarySpec, upperFirst } from \"../utils\";\n\n// Intentionally imported so tooling understands this exported helper is part of the\n// generated POM public surface (it is consumed by generated Playwright fixtures).\nimport { setPlaywrightAnimationOptions } from \"./Pointer\";\n\nvoid setPlaywrightAnimationOptions;\n\nexport { generateViewObjectModelMethodContent };\n\nconst AUTO_GENERATED_COMMENT\n = \" * DO NOT MODIFY BY HAND\\n\"\n + \" *\\n\"\n + \" * This file is auto-generated by vue-pom-generator.\\n\"\n + \" * Changes should be made in the generator/template, not in the generated output.\\n\"\n + \" */\";\nconst eslintSuppressionHeader = \"/* eslint-disable perfectionist/sort-imports */\\n\";\n\nfunction toPosixRelativePath(fromDir: string, toFile: string): string {\n let rel = path.relative(fromDir, toFile).replace(/\\\\/g, \"/\");\n if (!rel.startsWith(\".\")) {\n rel = `./${rel}`;\n }\n return rel;\n}\n\nfunction changeExtension(filePath: string, expectedExt: string, nextExtWithDot: string): string {\n const parsed = path.parse(filePath);\n if (parsed.ext !== expectedExt)\n return filePath;\n return path.format({ ...parsed, base: `${parsed.name}${nextExtWithDot}`, ext: nextExtWithDot });\n}\n\nfunction stripExtension(filePath: string): string {\n // IMPORTANT:\n // This helper is used for generating *import specifiers*.\n // On Windows, `path.parse/path.format` can re-introduce backslashes even when\n // the input contains `/` separators, producing invalid TS string escapes like `\"..\\\\pom\\\\custom\\\\nGrid\"`.\n // Keep these paths POSIX-normalized.\n const posix = (filePath ?? \"\").replace(/\\\\/g, \"/\");\n const parsed = path.posix.parse(posix);\n return path.posix.format({ ...parsed, base: parsed.name, ext: \"\" });\n}\n\nfunction resolveRouterEntry(projectRoot?: string, routerEntry?: string) {\n if (!routerEntry) {\n throw new Error(\"[vue-pom-generator] Router entry path is required when routerAwarePoms is enabled.\");\n }\n const root = projectRoot ?? process.cwd();\n return path.isAbsolute(routerEntry) ? routerEntry : path.resolve(root, routerEntry);\n}\n\ninterface RouteMeta {\n template: string;\n}\n\nasync function getRouteMetaByComponent(projectRoot?: string, routerEntry?: string): Promise<Record<string, RouteMeta>> {\n const resolvedRouterEntry = resolveRouterEntry(projectRoot, routerEntry);\n const { routeMetaEntries } = await parseRouterFileFromCwd(resolvedRouterEntry);\n\n const map = new Map<string, RouteMeta[]>();\n for (const entry of routeMetaEntries) {\n const list = map.get(entry.componentName) ?? [];\n list.push({ template: entry.pathTemplate });\n map.set(entry.componentName, list);\n }\n\n const chooseRouteMeta = (entries: RouteMeta[]): RouteMeta | null => {\n if (!entries.length)\n return null;\n return entries\n .slice()\n .sort((a, b) => a.template.length - b.template.length || a.template.localeCompare(b.template))[0];\n };\n\n const sorted = Array.from(map.entries()).sort((a, b) => a[0].localeCompare(b[0]));\n return Object.fromEntries(\n sorted\n .map(([componentName, entries]) => {\n const chosen = chooseRouteMeta(entries);\n return chosen ? [componentName, chosen] : null;\n })\n .filter((entry): entry is [string, RouteMeta] => !!entry),\n );\n}\n\nfunction generateRouteProperty(routeMeta: RouteMeta | null): string {\n if (!routeMeta) {\n return \" static readonly route: { template: string } | null = null;\\n\";\n }\n\n return [\n \" static readonly route: { template: string } | null = {\",\n ` template: ${JSON.stringify(routeMeta.template)},`,\n \" } as const;\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction generateGoToSelfMethod(componentName: string): string {\n return [\n \"\",\n \" async goTo() {\",\n \" await this.goToSelf();\",\n \" }\",\n \"\",\n \" async goToSelf() {\",\n ` const route = ${componentName}.route;`,\n \" if (!route) {\",\n ` throw new Error(\"[pom] No router path found for component/page-object '${componentName}'.\");`,\n \" }\",\n \" await this.page.goto(route.template);\",\n \" }\",\n \"\",\n ].join(\"\\n\");\n}\n\nfunction formatMethodParams(params: Record<string, string> | undefined): string {\n if (!params)\n return \"\";\n\n // Keep output stable and somewhat intuitive.\n const preferredOrder = [\"key\", \"value\", \"text\", \"timeOut\", \"annotationText\", \"wait\"];\n\n const entries = Object.entries(params);\n if (!entries.length)\n return \"\";\n\n const score = (name: string) => {\n const idx = preferredOrder.indexOf(name);\n return idx < 0 ? 999 : idx;\n };\n\n return entries\n .slice()\n .sort((a, b) => score(a[0]) - score(b[0]) || a[0].localeCompare(b[0]))\n .map(([name, typeExpr]) => `${name}: ${typeExpr}`)\n .join(\", \");\n}\n\nfunction generateExtraClickMethodContent(spec: PomExtraClickMethodSpec): string {\n if (spec.kind !== \"click\") {\n return \"\";\n }\n\n const params = spec.params ?? {};\n const signatureParams = formatMethodParams(params);\n const signature = signatureParams ? `(${signatureParams})` : \"()\";\n\n const needsTemplate = spec.formattedDataTestId.includes(\"${\");\n const testIdExpr = needsTemplate\n ? `\\`${spec.formattedDataTestId}\\``\n : JSON.stringify(spec.formattedDataTestId);\n\n const lines: string[] = [];\n lines.push(\n \"\",\n ` async ${spec.name}${signature} {`,\n );\n\n if (spec.keyLiteral !== undefined) {\n lines.push(` const key = ${JSON.stringify(spec.keyLiteral)};`);\n }\n\n if (needsTemplate) {\n lines.push(` const testId = ${testIdExpr};`);\n }\n\n // clickByTestId(testId, annotationText = \"\", wait = true)\n const hasAnnotationText = Object.prototype.hasOwnProperty.call(params, \"annotationText\");\n const hasWait = Object.prototype.hasOwnProperty.call(params, \"wait\");\n\n const clickArgs: string[] = [];\n clickArgs.push(needsTemplate ? \"testId\" : testIdExpr);\n\n if (hasAnnotationText || hasWait) {\n clickArgs.push(hasAnnotationText ? \"annotationText\" : \"\\\"\\\"\");\n }\n if (hasWait) {\n clickArgs.push(\"wait\");\n }\n\n lines.push(` await this.clickByTestId(${clickArgs.join(\", \")});`);\n lines.push(\" }\");\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n\nfunction generateMethodContentFromPom(primary: PomPrimarySpec, targetPageObjectModelClass?: string): string {\n if (primary.emitPrimary === false) {\n return \"\";\n }\n\n return generateViewObjectModelMethodContent(\n targetPageObjectModelClass,\n primary.methodName,\n primary.nativeRole,\n primary.formattedDataTestId,\n primary.alternateFormattedDataTestIds,\n primary.getterNameOverride,\n primary.params ?? {},\n );\n}\n\nfunction generateMethodsContentForDependencies(dependencies: IComponentDependencies): string {\n const entries = Array.from(dependencies.dataTestIdSet ?? []);\n const primarySpecsAll = entries\n .map(e => ({ pom: e.pom, target: e.targetPageObjectModelClass }))\n .filter((x): x is { pom: PomPrimarySpec; target: string | undefined } => !!x.pom)\n .sort((a, b) => a.pom.methodName.localeCompare(b.pom.methodName));\n\n // IMPORTANT:\n // `dependencies.dataTestIdSet` is a Set of objects; it does not de-dupe by semantic identity.\n // It's possible to end up with multiple IDataTestId entries that carry identical `pom` specs.\n // When we emit from IR, we must de-dupe here to avoid duplicate getters/methods.\n const seenPrimaryKeys = new Set<string>();\n const primarySpecs = primarySpecsAll.filter(({ pom, target }) => {\n const stableParams = pom.params\n ? Object.fromEntries(Object.entries(pom.params).sort((a, b) => a[0].localeCompare(b[0])))\n : undefined;\n const alternates = (pom.alternateFormattedDataTestIds ?? []).slice().sort();\n const key = JSON.stringify({\n role: pom.nativeRole,\n methodName: pom.methodName,\n getterNameOverride: pom.getterNameOverride ?? null,\n testId: pom.formattedDataTestId,\n alternateTestIds: alternates.length ? alternates : undefined,\n params: stableParams,\n target: target ?? null,\n emitPrimary: pom.emitPrimary ?? true,\n });\n if (seenPrimaryKeys.has(key)) {\n return false;\n }\n seenPrimaryKeys.add(key);\n return true;\n });\n\n const extras = (dependencies.pomExtraMethods ?? [])\n .slice()\n .sort((a, b) => a.name.localeCompare(b.name));\n\n let content = \"\";\n for (const { pom, target } of primarySpecs) {\n content += generateMethodContentFromPom(pom, target);\n }\n\n for (const extra of extras) {\n content += generateExtraClickMethodContent(extra);\n }\n\n return content;\n}\n\nexport interface GenerateFilesOptions {\n /**\n * Output directory for generated files.\n *\n * Defaults to `./pom` when omitted (backwards compatible default for internal usage).\n */\n outDir?: string;\n\n /**\n * Generate Playwright fixture helpers alongside generated POMs.\n *\n * Default output (when `true`):\n * - `<projectRoot>/<outDir>/fixtures.g.ts`\n *\n * Accepted values:\n * - `true`: enable with defaults\n * - `\"path\"`: enable and write the fixture file under this directory (resolved relative to projectRoot),\n * or to this file path if it ends with `.ts`/`.tsx`/`.mts`/`.cts`\n * - `{ outDir }`: enable and override where fixture files are written (resolved relative to projectRoot)\n */\n generateFixtures?: boolean | string | { outDir?: string };\n\n /**\n * Project root used for resolving conventional paths (e.g. src/views, tests/playwright/pom/custom).\n * Defaults to process.cwd() for backwards compatibility.\n */\n projectRoot?: string;\n\n /**\n * Directory containing handwritten POM helpers to import into aggregated output.\n * Defaults to <projectRoot>/tests/playwright/pom/custom.\n */\n customPomDir?: string;\n\n /**\n * Optional import aliases for handwritten POM helpers.\n *\n * Keyed by the helper file/export name (basename of the .ts file).\n * Value is the identifier to import it as.\n *\n * Example: { Toggle: \"ToggleWidget\" }\n */\n customPomImportAliases?: Record<string, string>;\n\n /**\n * Handwritten POM helper attachments. These helpers are assumed to be present in the\n * aggregated output (e.g. via `tests/playwright/pom/custom/*.ts` inlining), but we only attach them to\n * view classes that actually use certain components.\n */\n customPomAttachments?: Array<{\n className: string;\n propertyName: string;\n attachWhenUsesComponents: string[];\n\n /**\n * Controls whether this attachment is applied to views, components, or both.\n * Defaults to \"views\" for backwards compatibility.\n */\n attachTo?: \"views\" | \"components\" | \"both\";\n }>;\n\n /** Attribute name to treat as the test id. Defaults to `data-testid`. */\n testIdAttribute?: string;\n\n /** Which POM languages to emit. Defaults to [\"ts\"]. */\n emitLanguages?: Array<\"ts\" | \"csharp\">;\n\n /** When true, generate router-aware helpers like goToSelf() on view POMs. */\n vueRouterFluentChaining?: boolean;\n\n /** Router entry path used for vue-router introspection when fluent chaining is enabled. */\n routerEntry?: string;\n\n routeMetaByComponent?: Record<string, RouteMeta>;\n}\n\ninterface GenerateContentOptions {\n /** Directory the generated .g.ts file will live in (used for relative imports). Defaults to the Vue file's directory. */\n outputDir?: string;\n /** When true, omit file headers/import blocks that should be shared in an aggregated file. */\n aggregated?: boolean;\n\n customPomAttachments?: Array<{\n className: string;\n propertyName: string;\n attachWhenUsesComponents: string[];\n\n /**\n * Controls whether this attachment is applied to views, components, or both.\n * Defaults to \"views\" for backwards compatibility.\n */\n attachTo?: \"views\" | \"components\" | \"both\";\n }>;\n\n projectRoot?: string;\n customPomDir?: string;\n customPomImportAliases?: Record<string, string>;\n\n /** Attribute name to treat as the test id. Defaults to `data-testid`. */\n testIdAttribute?: string;\n\n /** When true, generate router-aware helpers like goToSelf() on view POMs. */\n vueRouterFluentChaining?: boolean;\n\n routeMetaByComponent?: Record<string, RouteMeta>;\n}\n\nexport async function generateFiles(\n componentHierarchyMap: Map<string, IComponentDependencies>,\n vueFilesPathMap: Map<string, string>,\n basePageClassPath: string,\n options: GenerateFilesOptions = {},\n) {\n const {\n outDir: outDirOverride,\n generateFixtures,\n customPomAttachments = [],\n projectRoot,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n emitLanguages: emitLanguagesOverride,\n vueRouterFluentChaining,\n routerEntry,\n } = options;\n\n const emitLanguages: Array<\"ts\" | \"csharp\"> = emitLanguagesOverride?.length\n ? emitLanguagesOverride\n : [\"ts\"];\n\n const outDir = outDirOverride ?? \"./pom\";\n\n const routeMetaByComponent = vueRouterFluentChaining\n ? await getRouteMetaByComponent(projectRoot, routerEntry)\n : undefined;\n\n if (emitLanguages.includes(\"ts\")) {\n const files = await generateAggregatedFiles(componentHierarchyMap, vueFilesPathMap, basePageClassPath, outDir, {\n customPomAttachments,\n projectRoot,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n generateFixtures,\n routeMetaByComponent,\n vueRouterFluentChaining,\n });\n for (const file of files) {\n createFile(file.filePath, file.content);\n }\n\n maybeGenerateFixtureRegistry(componentHierarchyMap, {\n generateFixtures,\n pomOutDir: outDir,\n projectRoot,\n });\n }\n\n if (emitLanguages.includes(\"csharp\")) {\n const csFiles = generateAggregatedCSharpFiles(componentHierarchyMap, outDir, {\n projectRoot,\n });\n for (const file of csFiles) {\n createFile(file.filePath, file.content);\n }\n }\n}\n\nfunction toCSharpTestIdExpression(formattedDataTestId: string): string {\n // Convert our `${var}` placeholder format into C# interpolated-string `{var}`.\n const needsInterpolation = formattedDataTestId.includes(\"${\");\n if (!needsInterpolation) {\n return JSON.stringify(formattedDataTestId);\n }\n\n const inner = formattedDataTestId.replace(/\\$\\{/g, \"{\");\n // Use verbatim JSON escaping for quotes/backslashes, then adapt to C# string literal.\n // JSON.stringify gives us a JS string literal with escapes, which is close enough for a C# normal string.\n const quoted = JSON.stringify(inner);\n return `$${quoted}`;\n}\n\nfunction toCSharpParam(paramTypeExpr: string): { type: string; defaultExpr?: string } {\n const trimmed = (paramTypeExpr ?? \"\").trim();\n\n // Handle default values: \"boolean = true\", \"string = \\\"\\\"\", \"timeOut = 500\".\n const eqIdx = trimmed.indexOf(\"=\");\n const left = eqIdx >= 0 ? trimmed.slice(0, eqIdx).trim() : trimmed;\n const right = eqIdx >= 0 ? trimmed.slice(eqIdx + 1).trim() : undefined;\n\n // Collapse union types to their widest practical type.\n const typePart = left.includes(\"|\") ? \"string\" : left;\n\n let type = \"string\";\n if (/(^|\\s)boolean(\\s|$)/.test(typePart))\n type = \"bool\";\n else if (/(^|\\s)string(\\s|$)/.test(typePart))\n type = \"string\";\n else if (/(^|\\s)number(\\s|$)/.test(typePart))\n type = \"int\";\n else if (/\\d+/.test(typePart) && typePart === \"\")\n type = \"int\";\n else if (/\\btimeOut\\b/i.test(typePart))\n type = \"int\";\n\n let defaultExpr: string | undefined;\n if (right !== undefined) {\n if (type === \"bool\") {\n defaultExpr = right.includes(\"true\") ? \"true\" : right.includes(\"false\") ? \"false\" : undefined;\n }\n else if (type === \"int\") {\n const m = right.match(/\\d+/);\n defaultExpr = m ? m[0] : undefined;\n }\n else {\n // string defaults, keep empty string if detected.\n if (right === \"\\\"\\\"\" || right === \"\\\"\\\"\" || right === \"''\") {\n defaultExpr = \"\\\"\\\"\";\n }\n }\n }\n\n return { type, defaultExpr };\n}\n\nfunction formatCSharpParams(params: Record<string, string> | undefined): { signature: string; argNames: string[] } {\n if (!params)\n return { signature: \"\", argNames: [] };\n\n const entries = Object.entries(params);\n if (!entries.length)\n return { signature: \"\", argNames: [] };\n\n const signatureParts: string[] = [];\n const argNames: string[] = [];\n\n for (const [name, typeExpr] of entries) {\n const { type, defaultExpr } = toCSharpParam(typeExpr);\n argNames.push(name);\n signatureParts.push(defaultExpr !== undefined ? `${type} ${name} = ${defaultExpr}` : `${type} ${name}`);\n }\n\n return { signature: signatureParts.join(\", \"), argNames };\n}\n\nfunction generateAggregatedCSharpFiles(\n componentHierarchyMap: Map<string, IComponentDependencies>,\n outDir: string,\n options: { projectRoot?: string } = {},\n): Array<{ filePath: string; content: string }> {\n const projectRoot = options.projectRoot ?? process.cwd();\n const outAbs = path.isAbsolute(outDir) ? outDir : path.resolve(projectRoot, outDir);\n\n const entries = Array.from(componentHierarchyMap.entries()).sort((a, b) => a[0].localeCompare(b[0]));\n\n const header = [\n \"// <auto-generated>\",\n \"// DO NOT MODIFY BY HAND\",\n \"//\",\n \"// This file is auto-generated by vue-pom-generator.\",\n \"// Changes should be made in the generator/template, not in the generated output.\",\n \"// </auto-generated>\",\n \"\",\n \"using System;\",\n \"using System.Threading.Tasks;\",\n \"using Microsoft.Playwright;\",\n \"\",\n \"namespace ImmyBot.Playwright.Generated;\",\n \"\",\n \"public abstract class BasePage\",\n \"{\",\n \" protected BasePage(IPage page) => Page = page;\",\n \" protected IPage Page { get; }\",\n \" protected ILocator LocatorByTestId(string testId) => Page.GetByTestId(testId);\",\n \"\",\n \" // Minimal vue-select helper mirroring the TS BasePage.selectVSelectByTestId behavior.\",\n \" // Note: annotationText is currently a no-op in C# output (we don't render a cursor overlay).\",\n \" protected async Task SelectVSelectByTestIdAsync(string testId, string value, int timeOut = 500)\",\n \" {\",\n \" var root = LocatorByTestId(testId);\",\n \" var input = root.Locator(\\\"input\\\");\",\n \"\",\n \" await input.ClickAsync(new LocatorClickOptions { Force = true });\",\n \" await input.FillAsync(value);\",\n \" await Page.WaitForTimeoutAsync(timeOut);\",\n \"\",\n \" var option = root.Locator(\\\"ul.vs__dropdown-menu li[role='option']\\\").First;\",\n \" if (await option.CountAsync() > 0)\",\n \" {\",\n \" await option.ClickAsync();\",\n \" }\",\n \" }\",\n \"}\",\n \"\",\n ].join(\"\\n\");\n\n const chunks: string[] = [header];\n\n for (const [componentName, deps] of entries) {\n chunks.push(\n `public sealed class ${componentName} : BasePage\\n{\\n public ${componentName}(IPage page) : base(page) { }\\n`,\n );\n\n // Primary specs\n const primaries = Array.from(deps.dataTestIdSet ?? [])\n .map(e => ({ pom: e.pom, target: e.targetPageObjectModelClass }))\n .filter((x): x is { pom: PomPrimarySpec; target: string | undefined } => !!x.pom)\n .sort((a, b) => a.pom.methodName.localeCompare(b.pom.methodName));\n\n for (const { pom, target } of primaries) {\n if (pom.emitPrimary === false)\n continue;\n\n const roleSuffix = (pom.nativeRole || \"Element\") === \"vselect\" ? \"VSelect\" : upperFirst(pom.nativeRole || \"Element\");\n const baseMethodName = upperFirst(pom.methodName);\n const baseGetterName = upperFirst(pom.getterNameOverride ?? pom.methodName);\n const locatorName = baseGetterName.endsWith(roleSuffix) ? baseGetterName : `${baseGetterName}${roleSuffix}`;\n const testIdExpr = toCSharpTestIdExpression(pom.formattedDataTestId);\n const { signature, argNames } = formatCSharpParams(pom.params);\n const args = argNames.join(\", \");\n\n const allTestIds = [pom.formattedDataTestId, ...(pom.alternateFormattedDataTestIds ?? [])]\n .filter((v, idx, arr) => v && arr.indexOf(v) === idx);\n\n if (pom.formattedDataTestId.includes(\"${\")) {\n chunks.push(` public ILocator ${locatorName}(${signature}) => LocatorByTestId(${testIdExpr});`);\n }\n else {\n chunks.push(` public ILocator ${locatorName} => LocatorByTestId(${testIdExpr});`);\n }\n\n // Action method\n const actionPrefix = pom.nativeRole === \"input\"\n ? \"Type\"\n : (pom.nativeRole === \"select\" || pom.nativeRole === \"vselect\" || pom.nativeRole === \"radio\")\n ? \"Select\"\n : target\n ? \"GoTo\"\n : \"Click\";\n\n const actionName = `${actionPrefix}${baseMethodName}Async`;\n const sig = signature;\n\n if (target) {\n chunks.push(` public async Task<${target}> ${actionName}(${sig})`);\n chunks.push(\" {\");\n if (pom.formattedDataTestId.includes(\"${\") || allTestIds.length <= 1) {\n chunks.push(` await ${locatorName}${pom.formattedDataTestId.includes(\"${\") ? `(${args})` : \"\"}.ClickAsync();`);\n }\n else {\n chunks.push(\" Exception? lastError = null;\");\n chunks.push(` foreach (var testId in new[] { ${allTestIds.map(toCSharpTestIdExpression).join(\", \")} })`);\n chunks.push(\" {\");\n chunks.push(\" try\");\n chunks.push(\" {\");\n chunks.push(\" var locator = LocatorByTestId(testId);\");\n chunks.push(\" if (await locator.CountAsync() > 0)\");\n chunks.push(\" {\");\n chunks.push(\" await locator.ClickAsync();\");\n chunks.push(` return new ${target}(Page);`);\n chunks.push(\" }\");\n chunks.push(\" }\");\n chunks.push(\" catch (Exception e)\");\n chunks.push(\" {\");\n chunks.push(\" lastError = e;\");\n chunks.push(\" }\");\n chunks.push(\" }\");\n chunks.push(\" throw lastError ?? new System.Exception(\\\"[pom] Failed to navigate using any candidate test id.\\\");\");\n }\n chunks.push(` return new ${target}(Page);`);\n chunks.push(\" }\");\n chunks.push(\"\");\n continue;\n }\n\n chunks.push(` public async Task ${actionName}(${sig})`);\n chunks.push(\" {\");\n\n const callSuffix = pom.formattedDataTestId.includes(\"${\") ? `(${args})` : \"\";\n\n const emitActionCall = (locatorAccess: string) => {\n if (pom.nativeRole === \"input\") {\n chunks.push(` await ${locatorAccess}.FillAsync(text);`);\n }\n else if (pom.nativeRole === \"select\") {\n chunks.push(` await ${locatorAccess}.SelectOptionAsync(value);`);\n }\n else if (pom.nativeRole === \"vselect\") {\n // vselect requires custom selection mechanics.\n chunks.push(` await SelectVSelectByTestIdAsync(${testIdExpr}, value, timeOut);`);\n }\n else {\n chunks.push(` await ${locatorAccess}.ClickAsync();`);\n }\n };\n\n if (!pom.formattedDataTestId.includes(\"${\") && allTestIds.length > 1) {\n chunks.push(\" Exception? lastError = null;\");\n chunks.push(` foreach (var testId in new[] { ${allTestIds.map(toCSharpTestIdExpression).join(\", \")} })`);\n chunks.push(\" {\");\n chunks.push(\" try\");\n chunks.push(\" {\");\n if (pom.nativeRole === \"vselect\") {\n chunks.push(\" // vselect fallback: use the same selection routine for each candidate test id.\");\n chunks.push(\" var root = LocatorByTestId(testId);\");\n chunks.push(\" if (await root.CountAsync() > 0)\");\n chunks.push(\" {\");\n chunks.push(\" await SelectVSelectByTestIdAsync(testId, value, timeOut);\");\n chunks.push(\" return;\");\n chunks.push(\" }\");\n }\n else {\n chunks.push(\" var locator = LocatorByTestId(testId);\");\n chunks.push(\" if (await locator.CountAsync() > 0)\");\n chunks.push(\" {\");\n if (pom.nativeRole === \"input\") {\n chunks.push(\" await locator.FillAsync(text);\");\n }\n else if (pom.nativeRole === \"select\") {\n chunks.push(\" await locator.SelectOptionAsync(value);\");\n }\n else {\n chunks.push(\" await locator.ClickAsync();\");\n }\n chunks.push(\" return;\");\n chunks.push(\" }\");\n }\n chunks.push(\" }\");\n chunks.push(\" catch (Exception e)\");\n chunks.push(\" {\");\n chunks.push(\" lastError = e;\");\n chunks.push(\" }\");\n chunks.push(\" }\");\n chunks.push(\" throw lastError ?? new Exception(\\\"[pom] Failed to click any candidate test id.\\\");\");\n chunks.push(\" }\");\n chunks.push(\"\");\n continue;\n }\n\n emitActionCall(`${locatorName}${callSuffix}`);\n\n chunks.push(\" }\");\n chunks.push(\"\");\n }\n\n // Extra click specs\n const extras = (deps.pomExtraMethods ?? []).slice().sort((a, b) => a.name.localeCompare(b.name));\n for (const extra of extras) {\n if (extra.kind !== \"click\")\n continue;\n const { signature } = formatCSharpParams(extra.params);\n const needsTemplate = extra.formattedDataTestId.includes(\"${\");\n const testIdExpr = toCSharpTestIdExpression(extra.formattedDataTestId);\n\n const extraName = upperFirst(extra.name);\n\n chunks.push(` public async Task ${extraName}Async(${signature})`);\n chunks.push(\" {\");\n if (extra.keyLiteral !== undefined) {\n chunks.push(` var key = ${JSON.stringify(extra.keyLiteral)};`);\n }\n if (needsTemplate) {\n chunks.push(` var testId = ${testIdExpr};`);\n chunks.push(\" await LocatorByTestId(testId).ClickAsync();\");\n }\n else {\n chunks.push(` await LocatorByTestId(${testIdExpr}).ClickAsync();`);\n }\n chunks.push(\" }\");\n chunks.push(\"\");\n }\n\n chunks.push(\"}\");\n chunks.push(\"\");\n }\n\n const outputFile = path.join(outAbs, \"page-object-models.g.cs\");\n return [{ filePath: outputFile, content: chunks.join(\"\\n\") }];\n}\n\nfunction maybeGenerateFixtureRegistry(\n componentHierarchyMap: Map<string, IComponentDependencies>,\n options: {\n generateFixtures: GenerateFilesOptions[\"generateFixtures\"];\n pomOutDir: string;\n projectRoot?: string;\n },\n) {\n const { generateFixtures, pomOutDir, projectRoot } = options;\n if (!generateFixtures)\n return;\n\n // generateFixtures accepts:\n // - true: enable fixtures with defaults\n // - \"path\": enable fixtures and write them under this directory OR to this file if it ends with .ts\n // - { outDir }: enable fixtures and override output directory\n const defaultFixtureOutDirRel = pomOutDir;\n const fixtureOutRel = typeof generateFixtures === \"string\"\n ? generateFixtures\n : (typeof generateFixtures === \"object\" && generateFixtures?.outDir\n ? generateFixtures.outDir\n : defaultFixtureOutDirRel);\n\n const looksLikeFilePath = fixtureOutRel.endsWith(\".ts\") || fixtureOutRel.endsWith(\".tsx\") || fixtureOutRel.endsWith(\".mts\") || fixtureOutRel.endsWith(\".cts\");\n const fixtureOutDirRel = looksLikeFilePath ? path.dirname(fixtureOutRel) : fixtureOutRel;\n const fixtureFileName = looksLikeFilePath ? path.basename(fixtureOutRel) : \"fixtures.g.ts\";\n\n const root = projectRoot ?? process.cwd();\n const fixtureOutDirAbs = path.isAbsolute(fixtureOutDirRel)\n ? fixtureOutDirRel\n : path.resolve(root, fixtureOutDirRel);\n\n // Resolve the directory that contains the POM barrel export (e.g. <root>/pom).\n const pomDirAbs = path.isAbsolute(pomOutDir) ? pomOutDir : path.resolve(root, pomOutDir);\n\n const pomImport = toPosixRelativePath(fixtureOutDirAbs, pomDirAbs);\n\n const viewClassNames = Array.from(componentHierarchyMap.entries())\n .filter(([, deps]) => !!deps.isView)\n .map(([name]) => name)\n .sort((a, b) => a.localeCompare(b));\n\n const reservedPlaywrightFixtureNames = new Set([\n // Built-in Playwright fixtures\n \"page\",\n \"context\",\n \"browser\",\n \"browserName\",\n \"request\",\n // Our own fixtureOptions\n \"animation\",\n ]);\n\n const viewFixtureNames = new Set(viewClassNames.map(name => lowerFirst(name)));\n\n const componentClassNames = Array.from(componentHierarchyMap.entries())\n .filter(([, deps]) => !deps.isView)\n .map(([name]) => name)\n .filter((name) => {\n const fixtureName = lowerFirst(name);\n if (reservedPlaywrightFixtureNames.has(fixtureName))\n return false;\n if (viewFixtureNames.has(fixtureName))\n return false;\n return true;\n })\n .sort((a, b) => a.localeCompare(b));\n\n const header = `${eslintSuppressionHeader}/**\\n`\n + ` * DO NOT MODIFY BY HAND\\n`\n + ` *\\n`\n + ` * This file is auto-generated by vue-pom-generator.\\n`\n + ` * Changes should be made in the generator/template, not in the generated output.\\n`\n + ` */\\n\\n`;\n\n // Concrete, strongly-typed fixtures for Playwright tests.\n // test(\"...\", async ({ preferencesPage }) => { ... })\n //\n // View POMs implement goTo() directly, so fixtures can be strongly typed without\n // casting/augmenting at runtime.\n const fixturesTypeEntries = viewClassNames\n .map(name => ` ${lowerFirst(name)}: Pom.${name},`)\n .join(\"\\n\");\n\n const componentFixturesTypeEntries = componentClassNames\n .map(name => ` ${lowerFirst(name)}: Pom.${name},`)\n .join(\"\\n\");\n\n const pomFactoryType = `export type PomConstructor<T> = new (page: PwPage) => T;\\n\\n`\n + `export interface PomFactory {\\n`\n + ` create<T>(ctor: PomConstructor<T>): T;\\n`\n + `}\\n\\n`;\n\n // NOTE: We intentionally do not generate \"openXPage\" helpers.\n // Each view POM provides goTo(), and tests call it explicitly.\n\n // Openers removed.\n\n const fixturesContent = `${header\n }/** Generated Playwright fixtures (typed page objects). */\\n\\n`\n + `import { expect, test as base } from \"@playwright/test\";\\n`\n + `import type { Page as PwPage } from \"@playwright/test\";\\n`\n + `import * as Pom from \"${pomImport}\";\\n\\n`\n + `export interface PlaywrightOptions {\\n`\n + ` animation: Pom.PlaywrightAnimationOptions;\\n`\n + `}\\n\\n`\n + `${pomFactoryType}`\n + `type PomSetupFixture = { pomSetup: void };\\n`\n + `type PomFactoryFixture = { pomFactory: PomFactory };\\n\\n`\n + `const pageCtors = {\\n${fixturesTypeEntries}\\n} as const;\\n`\n + `const componentCtors = {\\n${componentFixturesTypeEntries}\\n} as const;\\n\\n`\n + `export type GeneratedPageFixtures = { [K in keyof typeof pageCtors]: InstanceType<(typeof pageCtors)[K]> };\\n`\n + `export type GeneratedComponentFixtures = { [K in keyof typeof componentCtors]: InstanceType<(typeof componentCtors)[K]> };\\n\\n`\n + `const makePomFixture = <T>(Ctor: PomConstructor<T>) => async ({ page }: { page: PwPage }, use: (t: T) => Promise<void>) => {\\n`\n + ` await use(new Ctor(page));\\n`\n + `};\\n\\n`\n + `const createPomFixtures = <TMap extends Record<string, PomConstructor<any>>>(ctors: TMap) => {\\n`\n + ` const out: Record<string, any> = {};\\n`\n + ` for (const [key, Ctor] of Object.entries(ctors)) {\\n`\n + ` out[key] = makePomFixture(Ctor as PomConstructor<any>);\\n`\n + ` }\\n`\n + ` return out as any;\\n`\n + `};\\n\\n`\n + `const test = base.extend<PlaywrightOptions & PomSetupFixture & PomFactoryFixture & GeneratedPageFixtures & GeneratedComponentFixtures>({\\n`\n + ` animation: [{\\n`\n + ` pointer: { durationMilliseconds: 250, transitionStyle: \"ease-in-out\", clickDelayMilliseconds: 0 },\\n`\n + ` keyboard: { typeDelayMilliseconds: 100 },\\n`\n + ` }, { option: true }],\\n`\n + ` pomSetup: [async ({ animation }, use) => {\\n`\n + ` Pom.setPlaywrightAnimationOptions(animation);\\n`\n + ` await use();\\n`\n + ` }, { auto: true }],\\n`\n + ` pomFactory: async ({ page }, use) => {\\n`\n + ` await use({\\n`\n + ` create: <T>(ctor: PomConstructor<T>) => new ctor(page),\\n`\n + ` });\\n`\n + ` },\\n`\n + ` ...createPomFixtures(pageCtors),\\n`\n + ` ...createPomFixtures(componentCtors),\\n`\n + `});\\n\\n`\n + `export { test, expect };\\n`;\n\n createFile(path.resolve(fixtureOutDirAbs, fixtureFileName), fixturesContent);\n\n // No pomFixture is generated; goToSelf is emitted directly on each view POM.\n}\n\nfunction generateViewObjectModelContent(\n componentName: string,\n dependencies: IComponentDependencies,\n componentHierarchyMap: Map<string, IComponentDependencies>,\n vueFilesPathMap: Map<string, string>,\n basePageClassPath: string,\n options: GenerateContentOptions = {},\n) {\n const { isView, childrenComponentSet, usedComponentSet, filePath } = dependencies;\n\n const {\n outputDir = path.dirname(filePath),\n aggregated = false,\n customPomAttachments = [],\n testIdAttribute,\n } = options;\n\n const hasChildComponent = (needle: string) => {\n const haystack = usedComponentSet?.size ? usedComponentSet : childrenComponentSet;\n for (const child of haystack) {\n if (child === needle)\n return true;\n if (child === `${needle}.vue`)\n return true;\n if (child.endsWith(\".vue\") && child.slice(0, -4) === needle)\n return true;\n }\n return false;\n };\n\n const attachmentsForThisClass = customPomAttachments\n .filter((a) => {\n const scope = a.attachTo ?? \"views\";\n const scopeOk = isView\n ? (scope === \"views\" || scope === \"both\")\n : (scope === \"components\" || scope === \"both\");\n if (!scopeOk)\n return false;\n return a.attachWhenUsesComponents.some(c => hasChildComponent(c));\n })\n .map(a => ({ className: a.className, propertyName: a.propertyName }));\n\n let content: string = \"\";\n\n const sourceRel = toPosixRelativePath(outputDir, filePath);\n const kind = isView ? \"Page\" : \"Component\";\n const doc = `/** ${kind} POM: ${componentName} (source: ${sourceRel}) */\\n`;\n\n // In aggregated mode, imports are hoisted once at the top of the file.\n if (!aggregated) {\n content = `${eslintSuppressionHeader}${doc}`;\n\n // We only need PwPage when we emit a constructor (views always do; components only do\n // when they have custom attachments like Grid).\n if (isView || attachmentsForThisClass.length > 0) {\n content += \"import type { Page as PwPage } from \\\"@playwright/test\\\";\\n\";\n }\n\n const projectRoot = options.projectRoot ?? process.cwd();\n const fromAbs = path.isAbsolute(outputDir) ? outputDir : path.resolve(projectRoot, outputDir);\n const toAbs = basePageClassPath\n ? (path.isAbsolute(basePageClassPath) ? basePageClassPath : path.resolve(projectRoot, basePageClassPath))\n : \"\";\n const basePageImport = path.relative(fromAbs, toAbs).replace(/\\\\/g, \"/\");\n // stripExtension uses node:path formatting (platform-specific). Re-normalize to POSIX\n // so the import specifier is valid on Windows.\n const basePageImportNoExt = stripExtension(basePageImport).replace(/\\\\/g, \"/\");\n const basePageImportSpecifier = basePageImportNoExt.startsWith(\".\") ? basePageImportNoExt : `./${basePageImportNoExt}`;\n content += `import { BasePage, Fluent } from '${basePageImportSpecifier}';\\n\\n`;\n\n if (isView && childrenComponentSet.size > 0) {\n childrenComponentSet.forEach((child) => {\n if (componentHierarchyMap.has(child) && componentHierarchyMap.get(child)?.dataTestIdSet.size) {\n const childPath = vueFilesPathMap.get(child);\n let relativePath = path.relative(outputDir, childPath || \"\");\n relativePath = changeExtension(relativePath, \".vue\", \".g\").replace(/\\\\/g, \"/\");\n content += `import { ${child} } from '${relativePath}';\\n`;\n }\n });\n }\n }\n else {\n // Keep per-class doc comment, but avoid repeating eslint suppression / imports.\n content = doc;\n }\n\n content += `\\nexport class ${componentName} extends BasePage {\\n`;\n\n const widgetInstances = isView\n ? getWidgetInstancesForView(componentName, dependencies.dataTestIdSet)\n : [];\n\n // For views, `childrenComponentSet` only includes component tags on which we applied a data-testid.\n // Thin wrapper views (e.g. NewTenantPage) may have *no* generated test ids but still contain\n // important child component POMs (forms, grids, etc). In those cases, we use `usedComponentSet`\n // to discover and instantiate child component POMs.\n const componentRefsForInstances = isView\n ? (usedComponentSet?.size ? usedComponentSet : childrenComponentSet)\n : childrenComponentSet;\n\n // Only views get child component instance fields by default.\n // Components will only get a constructor/fields when they have explicit custom attachments\n // (e.g. wrapper components around a third-party data grid should get a `grid: Grid`).\n if (isView && (componentRefsForInstances.size > 0 || attachmentsForThisClass.length > 0 || widgetInstances.length > 0)) {\n content += getComponentInstances(componentRefsForInstances, componentHierarchyMap, attachmentsForThisClass, widgetInstances);\n content += getConstructor(componentRefsForInstances, componentHierarchyMap, attachmentsForThisClass, widgetInstances, { testIdAttribute });\n }\n if (!isView && attachmentsForThisClass.length > 0) {\n content += getComponentInstances(new Set(), componentHierarchyMap, attachmentsForThisClass);\n content += getConstructor(new Set(), componentHierarchyMap, attachmentsForThisClass, [], { testIdAttribute });\n }\n\n // Ergonomics: when a view is primarily composed of a single component POM (e.g. a form),\n // allow calling that component's methods directly on the page class.\n //\n // Example:\n // await tenantListPage.goToNewTenant().typeTenantName(...).clickCreateTenant();\n //\n // Rules:\n // - Only for views (not components) to avoid polluting component surfaces.\n // - Only generate pass-throughs when the method is unambiguous across child components.\n // - Never generate a pass-through that would collide with an existing method on the view.\n // Only generate view passthrough methods when the view is essentially a thin wrapper\n // around a single child component POM. This prevents \"layout\" components (Page, PageHeader,\n // etc.) from injecting lots of noisy passthrough APIs into every view.\n if (isView && componentRefsForInstances.size === 1) {\n content += getViewPassthroughMethods(componentName, dependencies, componentRefsForInstances, componentHierarchyMap);\n }\n\n if (isView && options.vueRouterFluentChaining) {\n const routeMeta = options.routeMetaByComponent?.[componentName] ?? null;\n content += generateRouteProperty(routeMeta);\n content += generateGoToSelfMethod(componentName);\n }\n\n content += generateMethodsContentForDependencies(dependencies);\n\n content += \"}\\n\";\n return content;\n}\n\nfunction getViewPassthroughMethods(\n viewName: string,\n viewDependencies: IComponentDependencies,\n childrenComponentSet: Set<string>,\n componentHierarchyMap: Map<string, IComponentDependencies>,\n) {\n const existingOnView = viewDependencies.generatedMethods ?? new Map<string, { params: string; argNames: string[] } | null>();\n\n // methodName -> candidates\n const methodToChildren = new Map<string, Array<{ childProp: string; params: string; argNames: string[] }>>();\n\n for (const child of childrenComponentSet) {\n const childDeps = componentHierarchyMap.get(child);\n if (!childDeps || !childDeps.dataTestIdSet?.size)\n continue;\n\n const methods = childDeps.generatedMethods;\n if (!methods)\n continue;\n\n // Property name matches how we emit instance fields (strip .vue if present).\n const childProp = child.endsWith(\".vue\") ? child.slice(0, -4) : child;\n\n for (const [name, sig] of methods.entries()) {\n if (!sig)\n continue; // ambiguous on the child itself\n\n // If the view already has this method name, never generate a pass-through.\n if (existingOnView.has(name))\n continue;\n\n const list = methodToChildren.get(name) ?? [];\n list.push({ childProp, params: sig.params, argNames: sig.argNames });\n methodToChildren.set(name, list);\n }\n }\n\n const sorted = Array.from(methodToChildren.entries()).sort((a, b) => a[0].localeCompare(b[0]));\n const lines: string[] = [];\n\n for (const [methodName, candidates] of sorted) {\n // Only generate when exactly one child can satisfy the call.\n if (candidates.length !== 1)\n continue;\n\n const { childProp, params, argNames } = candidates[0];\n const callArgs = argNames.join(\", \");\n\n lines.push(\n \"\",\n ` async ${methodName}(${params}) {`,\n ` return await this.${childProp}.${methodName}(${callArgs});`,\n \" }\",\n );\n }\n\n if (!lines.length) {\n return \"\";\n }\n\n return [\n \"\",\n ` // Passthrough methods composed from child component POMs of ${viewName}.`,\n ...lines,\n \"\",\n ].join(\"\\n\");\n}\n\nfunction ensureDir(dir: string) {\n const normalized = dir.replace(/\\\\/g, \"/\");\n if (!fs.existsSync(normalized)) {\n fs.mkdirSync(normalized, { recursive: true });\n }\n return normalized;\n}\n\nasync function generateAggregatedFiles(\n componentHierarchyMap: Map<string, IComponentDependencies>,\n vueFilesPathMap: Map<string, string>,\n basePageClassPath: string,\n outDir: string,\n options: {\n customPomAttachments?: GenerateFilesOptions[\"customPomAttachments\"];\n projectRoot?: GenerateFilesOptions[\"projectRoot\"];\n customPomDir?: GenerateFilesOptions[\"customPomDir\"];\n customPomImportAliases?: GenerateFilesOptions[\"customPomImportAliases\"];\n testIdAttribute?: GenerateFilesOptions[\"testIdAttribute\"];\n generateFixtures?: GenerateFilesOptions[\"generateFixtures\"];\n routeMetaByComponent?: Record<string, RouteMeta>;\n vueRouterFluentChaining?: boolean;\n } = {},\n) {\n const projectRoot = options.projectRoot ?? process.cwd();\n const entries = Array.from(componentHierarchyMap.entries())\n .sort((a, b) => a[0].localeCompare(b[0]));\n\n const views = entries.filter(([, d]) => d.isView);\n const components = entries.filter(([, d]) => !d.isView);\n\n const makeAggregatedContent = (\n header: string,\n outputDir: string,\n items: Array<[string, IComponentDependencies]>,\n ) => {\n // Alias Playwright types to avoid collisions with generated classes (e.g. a Vue component named `Page`).\n const imports: string[] = [\"import type { Locator as PwLocator, Page as PwPage } from \\\"@playwright/test\\\";\"];\n\n if (!basePageClassPath) {\n throw new Error(\"basePageClassPath is required for aggregated generation\");\n }\n\n // Inline BasePage into the aggregated output.\n //\n // Why:\n // - Playwright's runtime loader can treat workspace packages (like `vue-pom-generator`)\n // as external and not apply TS transforms/module resolution consistently.\n // - Importing a .ts file from inside a \"type\": \"module\" package can fail with\n // \"Cannot find module\" at runtime.\n //\n // Inlining keeps the generated POMs self-contained and stable across platforms.\n const clickInstrumentationInline = [\n \"export const TESTID_CLICK_EVENT_NAME = \\\"__testid_event__\\\";\",\n \"export const TESTID_CLICK_EVENT_STRICT_FLAG = \\\"__testid_click_event_strict__\\\";\",\n \"export interface TestIdClickEventDetail {\",\n \" testId?: string;\",\n \" phase?: \\\"before\\\" | \\\"after\\\" | \\\"error\\\" | string;\",\n \" err?: string;\",\n \"}\",\n ].join(\"\\n\");\n\n const inlinePointerModule = () => {\n // Inline Pointer.ts from this package so generated POMs are self-contained and do not\n // rely on runtime TS module resolution within workspace packages.\n const pointerPath = fileURLToPath(new URL(\"./Pointer.ts\", import.meta.url));\n\n let pointerSource = \"\";\n try {\n pointerSource = fs.readFileSync(pointerPath, \"utf8\");\n }\n catch {\n throw new Error(`Failed to read Pointer.ts at ${pointerPath}`);\n }\n\n // Replace the click-instrumentation import with an inline copy.\n pointerSource = pointerSource.replace(\n /import\\s*\\{[\\s\\S]*?\\}\\s*from\\s*[\"']\\.\\.\\/click-instrumentation[\"'];?\\s*/,\n `${clickInstrumentationInline}\\n\\n`,\n );\n\n // If Pointer uses a split value import + type-only import, remove the type-only import too.\n // The inline block already declares TestIdClickEventDetail.\n pointerSource = pointerSource.replace(\n /import\\s+type\\s*\\{\\s*TestIdClickEventDetail\\s*\\}\\s*from\\s*[\"']\\.\\.\\/click-instrumentation[\"'];?\\s*/g,\n \"\",\n );\n\n // The aggregated file already imports these Playwright types once at the top.\n pointerSource = pointerSource.replace(\n /import\\s+type\\s*\\{\\s*Locator\\s+as\\s+PwLocator\\s*,\\s*Page\\s+as\\s+PwPage\\s*\\}\\s*from\\s*[\"']@playwright\\/test[\"'];?\\s*/,\n \"\",\n );\n\n return pointerSource.trim();\n };\n\n const inlineBasePageModule = () => {\n let basePageSource = \"\";\n try {\n basePageSource = fs.readFileSync(basePageClassPath, \"utf8\");\n }\n catch {\n throw new Error(`Failed to read BasePage.ts at ${basePageClassPath}`);\n }\n\n // Replace the click-instrumentation import with an inline copy.\n basePageSource = basePageSource.replace(\n /import\\s*\\{[\\s\\S]*?\\}\\s*from\\s*[\"']\\.\\.\\/click-instrumentation[\"'];?\\s*/,\n `${clickInstrumentationInline}\\n\\n`,\n );\n\n // If BasePage uses a split value import + type-only import, remove the type-only import too.\n // The inline block already declares TestIdClickEventDetail.\n basePageSource = basePageSource.replace(\n /import\\s+type\\s*\\{\\s*TestIdClickEventDetail\\s*\\}\\s*from\\s*[\"']\\.\\.\\/click-instrumentation[\"'];?\\s*/g,\n \"\",\n );\n\n // The aggregated file already imports these Playwright types once at the top.\n // Remove BasePage's own import to avoid duplicate identifiers.\n basePageSource = basePageSource.replace(\n /import\\s+type\\s*\\{\\s*Locator\\s+as\\s+PwLocator\\s*,\\s*Page\\s+as\\s+PwPage\\s*\\}\\s*from\\s*[\"']@playwright\\/test[\"'];?\\s*/,\n \"\",\n );\n\n // BasePage references Pointer, but in aggregated output we inline Pointer above.\n basePageSource = basePageSource.replace(\n /import\\s*\\{\\s*Pointer\\s*\\}\\s*from\\s*[\"']\\.\\/Pointer[\"'];?\\s*/g,\n \"\",\n );\n\n return basePageSource.trim();\n };\n\n const pointerInline = inlinePointerModule();\n const basePageInline = inlineBasePageModule();\n\n // Handwritten POM helpers for complicated/third-party widgets.\n // Convention: place them in `tests/playwright/pom/custom/*.ts`.\n // Import them rather than inlining so TypeScript can typecheck them.\n const addCustomPomImports = () => {\n // Some custom POM helpers intentionally share names with generated component POMs\n // (e.g. Toggle.vue -> generated class `Toggle`). Import with aliases to avoid\n // merged-declaration conflicts in the aggregated output.\n const importAliases: Record<string, string> = {\n Toggle: \"ToggleWidget\",\n Checkbox: \"CheckboxWidget\",\n ...(options.customPomImportAliases ?? {}),\n };\n\n const customDirRelOrAbs = options.customPomDir ?? \"tests/playwright/pom/custom\";\n const customDirAbs = path.isAbsolute(customDirRelOrAbs)\n ? customDirRelOrAbs\n : path.resolve(projectRoot, customDirRelOrAbs);\n\n if (!fs.existsSync(customDirAbs)) {\n return;\n }\n\n const files = fs.readdirSync(customDirAbs)\n .filter(f => f.endsWith(\".ts\"))\n .sort((a, b) => a.localeCompare(b));\n\n for (const file of files) {\n const exportName = file.replace(/\\.ts$/i, \"\");\n // In this repo, custom POMs are authored as `export class <Name> { ... }`.\n // Import by the basename, which matches the class name convention.\n const alias = importAliases[exportName];\n const customFileAbs = path.join(customDirAbs, file);\n const fromOutputDir = outputDir;\n const importPath = stripExtension(toPosixRelativePath(fromOutputDir, customFileAbs));\n if (alias) {\n imports.push(`import { ${exportName} as ${alias} } from \"${importPath}\";`);\n }\n else {\n imports.push(`import { ${exportName} } from \"${importPath}\";`);\n }\n }\n };\n\n addCustomPomImports();\n\n // Collect any navigation return types referenced by generated methods so we can emit\n // stub classes when the destination view has no generated test ids (and therefore no\n // corresponding POM class in this file).\n const referencedTargets = new Set<string>();\n for (const [, deps] of items) {\n for (const dt of deps.dataTestIdSet) {\n if (dt.targetPageObjectModelClass) {\n referencedTargets.add(dt.targetPageObjectModelClass);\n }\n }\n }\n\n const generatedClassNames = new Set(items.map(([name]) => name));\n const stubTargets = Array.from(referencedTargets)\n .filter(t => !generatedClassNames.has(t))\n .sort((a, b) => a.localeCompare(b));\n\n const availableClassNames = new Set<string>([...generatedClassNames, ...stubTargets]);\n\n const depsByClassName = new Map<string, IComponentDependencies>(entries);\n\n const scanPascalCaseTags = (template: string) => {\n // Extracts tag names like <TenantDetailsEditForm ...> without regex.\n // We only care about PascalCase component tags.\n const names: string[] = [];\n const len = template.length;\n let i = 0;\n while (i < len) {\n const ch = template[i];\n if (ch !== \"<\") {\n i++;\n continue;\n }\n\n i++; // consume '<'\n if (i >= len)\n break;\n\n // Skip closing tags and directives/comments\n if (template[i] === \"/\" || template[i] === \"!\" || template[i] === \"?\") {\n i++;\n continue;\n }\n\n // Skip whitespace\n while (i < len && (template[i] === \" \" || template[i] === \"\\n\" || template[i] === \"\\t\" || template[i] === \"\\r\")) i++;\n if (i >= len)\n break;\n\n const first = template[i];\n // Only PascalCase (starts with A-Z)\n if (first < \"A\" || first > \"Z\") {\n continue;\n }\n\n const start = i;\n i++;\n while (i < len) {\n const c = template[i];\n const isLetter = (c >= \"A\" && c <= \"Z\") || (c >= \"a\" && c <= \"z\");\n const isDigit = c >= \"0\" && c <= \"9\";\n const isUnderscore = c === \"_\";\n if (isLetter || isDigit || isUnderscore) {\n i++;\n continue;\n }\n break;\n }\n const name = template.slice(start, i);\n if (name)\n names.push(name);\n }\n return Array.from(new Set(names));\n };\n\n const getComposedStubBody = (targetClassName: string) => {\n const mapped = vueFilesPathMap.get(targetClassName);\n const candidates = [\n mapped,\n path.join(projectRoot, \"src\", \"views\", `${targetClassName}.vue`),\n path.join(projectRoot, \"src\", \"components\", `${targetClassName}.vue`),\n ].filter((p): p is string => typeof p === \"string\" && p.length > 0);\n\n const filePath = candidates.find(p => fs.existsSync(p));\n if (!filePath)\n return undefined;\n\n // Heuristic: scan the SFC template for PascalCase tags. If we have generated\n // POM classes for those components, include them as composed children.\n let source = \"\";\n try {\n source = fs.readFileSync(filePath, \"utf8\");\n }\n catch {\n return undefined;\n }\n\n const templateOpen = source.indexOf(\"<template\");\n const templateClose = source.lastIndexOf(\"</template>\");\n if (templateOpen === -1 || templateClose === -1 || templateClose <= templateOpen)\n return undefined;\n\n const afterOpenTag = source.indexOf(\">\", templateOpen);\n if (afterOpenTag === -1 || afterOpenTag >= templateClose)\n return undefined;\n\n const template = source.slice(afterOpenTag + 1, templateClose);\n if (!template)\n return undefined;\n\n const tags = scanPascalCaseTags(template);\n const childClassNames = Array.from(\n new Set(\n tags\n .filter(name => availableClassNames.has(name))\n .filter(name => name !== targetClassName),\n ),\n ).sort((a, b) => a.localeCompare(b));\n\n if (!childClassNames.length)\n return undefined;\n\n // Build passthrough methods from stub -> child component when the method is unambiguous.\n // This enables ergonomics like:\n // await tenantListPage.goToNewTenant().typeTenantName(...)\n // without forcing the test to reference `.TenantDetailsEditForm`.\n const methodToChildren = new Map<string, Array<{ child: string; params: string; argNames: string[] }>>();\n for (const child of childClassNames) {\n const childDeps = depsByClassName.get(child);\n const methods = childDeps?.generatedMethods;\n if (!methods)\n continue;\n\n for (const [name, sig] of methods.entries()) {\n if (!sig)\n continue; // ambiguous\n const list = methodToChildren.get(name) ?? [];\n list.push({ child, params: sig.params, argNames: sig.argNames });\n methodToChildren.set(name, list);\n }\n }\n\n const passthroughLines: string[] = [];\n for (const [methodName, candidatesForMethod] of methodToChildren.entries()) {\n if (candidatesForMethod.length !== 1)\n continue;\n\n // Avoid creating pass-throughs for internal-ish helpers.\n if (methodName === \"constructor\")\n continue;\n\n const { child, params, argNames } = candidatesForMethod[0];\n const callArgs = argNames.join(\", \");\n\n passthroughLines.push(\n \"\",\n ` async ${methodName}(${params}) {`,\n ` return await this.${child}.${methodName}(${callArgs});`,\n \" }\",\n );\n }\n\n return {\n childClassNames,\n lines: [\n ...childClassNames.map(c => ` ${c}: ${c};`),\n \"\",\n \" constructor(page: PwPage) {\",\n \" super(page);\",\n ...childClassNames.map(c => ` this.${c} = new ${c}(page);`),\n \" }\",\n ...passthroughLines,\n ],\n };\n };\n\n const stubs = stubTargets.map(t =>\n (() => {\n const composed = getComposedStubBody(t);\n const body = composed?.lines ?? [\n \" constructor(page: PwPage) {\",\n \" super(page);\",\n \" }\",\n ];\n\n return [\n \"/**\\n * Stub POM generated because it is referenced as a navigation target but\\n * did not have any generated test ids in this build.\\n */\",\n `export class ${t} extends BasePage {`,\n ...body,\n \"}\",\n ].join(\"\\n\");\n })(),\n );\n\n const classes = items.map(([name, deps]) =>\n generateViewObjectModelContent(name, deps, componentHierarchyMap, vueFilesPathMap, basePageClassPath, {\n outputDir,\n aggregated: true,\n\n customPomAttachments: options.customPomAttachments ?? [],\n testIdAttribute: options.testIdAttribute,\n vueRouterFluentChaining: options.vueRouterFluentChaining,\n routeMetaByComponent: options.routeMetaByComponent,\n }),\n );\n\n const baseContent = [\n header,\n ...imports,\n \"\",\n pointerInline,\n \"\",\n basePageInline,\n \"\",\n ...classes,\n ...(stubs.length ? [\"\", ...stubs] : []),\n ].filter(Boolean).join(\"\\n\\n\");\n\n return baseContent;\n };\n\n const base = ensureDir(outDir);\n const outputFile = path.join(base, \"page-object-models.g.ts\");\n const header = `${eslintSuppressionHeader}/**\\n * Aggregated generated POMs\\n${AUTO_GENERATED_COMMENT}`;\n const content = makeAggregatedContent(header, path.dirname(outputFile), [...views, ...components]);\n\n const indexFile = path.join(base, \"index.ts\");\n const indexContent = `${eslintSuppressionHeader}/**\\n * POM exports\\n${AUTO_GENERATED_COMMENT}\\n\\nexport * from \"./page-object-models.g\";\\n`;\n\n return [\n { filePath: outputFile, content },\n { filePath: indexFile, content: indexContent },\n ];\n}\n\nfunction createFile(filePath: string, content: string) {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n fs.writeFileSync(filePath, content);\n}\n\nfunction lowerFirst(value: string): string {\n if (!value)\n return value;\n return value.charAt(0).toLowerCase() + value.slice(1);\n}\n\nfunction toPascalCaseLocal(str: string): string {\n const cleaned = (str ?? \"\")\n .replace(/\\$\\{[^}]*\\}/g, \" \")\n .replace(/[^a-z0-9]+/gi, \" \")\n .trim();\n\n if (!cleaned)\n return \"\";\n\n return cleaned\n .split(/\\s+/)\n .filter(Boolean)\n .map((word) => {\n const preserveInternalCaps = /[a-z][A-Z]/.test(word);\n return preserveInternalCaps\n ? upperFirst(word)\n : upperFirst(word.toLowerCase());\n })\n .join(\"\");\n}\n\ninterface WidgetInstance {\n className: \"ToggleWidget\" | \"CheckboxWidget\";\n propertyName: string;\n testId: string;\n}\n\nfunction getWidgetInstancesForView(componentName: string, dataTestIdSet: Set<IDataTestId>): WidgetInstance[] {\n const out: WidgetInstance[] = [];\n const usedPropNames = new Set<string>();\n\n const ensureUnique = (base: string) => {\n let candidate = base;\n let i = 2;\n while (usedPropNames.has(candidate)) {\n candidate = `${base}${i}`;\n i++;\n }\n usedPropNames.add(candidate);\n return candidate;\n };\n\n for (const dt of dataTestIdSet) {\n const raw = dt.value;\n\n // Skip keyed/dynamic test ids; instance fields can't represent those ergonomically.\n if (raw.includes(\"${\")) {\n continue;\n }\n\n const toggleSuffix = \"-toggle\";\n const checkboxSuffix = \"-checkbox\";\n\n let className: WidgetInstance[\"className\"] | null = null;\n let stem = \"\";\n\n if (raw.endsWith(toggleSuffix)) {\n className = \"ToggleWidget\";\n stem = raw.slice(0, -toggleSuffix.length);\n }\n else if (raw.endsWith(checkboxSuffix)) {\n className = \"CheckboxWidget\";\n stem = raw.slice(0, -checkboxSuffix.length);\n }\n else {\n continue;\n }\n\n // Prefer stripping the view prefix (e.g. PreferencesPage-) for cleaner member names.\n const viewPrefix = `${componentName}-`;\n const descriptorRaw = stem.startsWith(viewPrefix) ? stem.slice(viewPrefix.length) : stem;\n const descriptorPascal = toPascalCaseLocal(descriptorRaw);\n\n if (!descriptorPascal) {\n continue;\n }\n\n if (className === \"ToggleWidget\") {\n let base = descriptorPascal.replace(/Toggle$/i, \"\");\n\n // Ergonomic naming: if a toggle name contains an \"Enable...\" tail, prefer that tail.\n // Example: AppPreferencesEnableSessionEmails -> enableSessionEmailsToggle\n const enableIndex = base.indexOf(\"Enable\");\n if (enableIndex > 0) {\n base = base.slice(enableIndex);\n }\n\n const propBase = lowerFirst(base);\n const propName = ensureUnique(propBase ? `${propBase}Toggle` : \"toggle\");\n out.push({ className, propertyName: propName, testId: raw });\n continue;\n }\n\n // Checkbox\n const base = descriptorPascal\n .replace(/CheckBox$/i, \"\")\n .replace(/Checkbox$/i, \"\");\n const propBase = lowerFirst(base);\n const propName = ensureUnique(propBase ? `${propBase}Checkbox` : \"checkbox\");\n out.push({ className, propertyName: propName, testId: raw });\n }\n\n return out;\n}\n\nfunction getComponentInstances(\n childrenComponent: Set<string>,\n componentHierarchyMap: Map<string, IComponentDependencies>,\n attachmentsForThisView: Array<{ className: string; propertyName: string }> = [],\n widgetInstances: WidgetInstance[] = [],\n) {\n let content = \"\\n\";\n\n for (const a of attachmentsForThisView) {\n content += ` ${a.propertyName}: ${a.className};\\n`;\n }\n\n for (const w of widgetInstances) {\n content += ` ${w.propertyName}: ${w.className};\\n`;\n }\n\n childrenComponent.forEach((child) => {\n if (componentHierarchyMap.has(child) && componentHierarchyMap.get(child)?.dataTestIdSet.size) {\n const childName = child.split(\".vue\")[0];\n content += ` ${childName}: ${childName};\\n`;\n }\n });\n return `${content}\\n`;\n}\n\nfunction getConstructor(\n childrenComponent: Set<string>,\n componentHierarchyMap: Map<string, IComponentDependencies>,\n attachmentsForThisView: Array<{ className: string; propertyName: string }> = [],\n widgetInstances: WidgetInstance[] = [],\n options?: { testIdAttribute?: string },\n) {\n let content = \" constructor(page: PwPage) {\\n\";\n const attr = (options?.testIdAttribute ?? \"data-testid\").trim() || \"data-testid\";\n content += ` super(page, { testIdAttribute: ${JSON.stringify(attr)} });\\n`;\n\n for (const a of attachmentsForThisView) {\n content += ` this.${a.propertyName} = new ${a.className}(page, this);\\n`;\n }\n\n for (const w of widgetInstances) {\n content += ` this.${w.propertyName} = new ${w.className}(page, ${JSON.stringify(w.testId)});\\n`;\n }\n\n childrenComponent.forEach((child) => {\n if (componentHierarchyMap.has(child) && componentHierarchyMap.get(child)?.dataTestIdSet.size) {\n const childName = child.split(\".vue\")[0];\n content += ` this.${childName} = new ${childName}(page);\\n`;\n }\n });\n content += \" }\";\n return `${content}\\n`;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport type { PluginOption } from \"vite\";\n\nimport { generateFiles } from \"../../class-generation\";\nimport { parseRouterFileFromCwd } from \"../../router-introspection\";\nimport { setResolveToComponentNameFn, setRouteNameToComponentNameMap, toPascalCase } from \"../../utils\";\nimport type { IComponentDependencies } from \"../../utils\";\nimport type { VuePomGeneratorLogger } from \"../logger\";\n\ninterface BuildProcessorOptions {\n componentHierarchyMap: Map<string, IComponentDependencies>;\n vueFilesPathMap: Map<string, string>;\n\n basePageClassPath: string;\n normalizedBasePagePath: string;\n\n outDir?: string;\n emitLanguages?: Array<\"ts\" | \"csharp\">;\n generateFixtures?: boolean | string | { outDir?: string };\n customPomAttachments?: Array<{ className: string; propertyName: string; attachWhenUsesComponents: string[]; attachTo?: \"views\" | \"components\" | \"both\" }>;\n projectRootRef: { current: string };\n customPomDir?: string;\n customPomImportAliases?: Record<string, string>;\n testIdAttribute: string;\n\n routerAwarePoms: boolean;\n resolvedRouterEntry?: string;\n\n loggerRef: { current: VuePomGeneratorLogger };\n}\n\nexport function createBuildProcessorPlugin(options: BuildProcessorOptions): PluginOption {\n const {\n componentHierarchyMap,\n vueFilesPathMap,\n basePageClassPath,\n normalizedBasePagePath,\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n projectRootRef,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n routerAwarePoms,\n resolvedRouterEntry,\n loggerRef,\n } = options;\n\n // Vite (v6/v7) may run multiple build environments/passes (e.g. SSR + client) in a single invocation.\n // Some passes can execute without compiling any Vue SFC templates that reach our transform, leaving\n // `componentHierarchyMap` empty. If we blindly generate on that pass, we can overwrite a previously\n // correct aggregated output (e.g. `tests/playwright/generated/page-object-models.g.ts`) with an incomplete file.\n //\n // Guard generation so we only write when we have meaningful data, and prefer the \"largest\" pass.\n let lastGeneratedEntryCount = 0;\n\n return {\n name: \"vue-pom-generator-build\",\n // This plugin exists to generate code on build output; it is not needed during dev-server HMR.\n apply: \"build\",\n enforce: \"pre\",\n async buildStart() {\n // Router introspection: build a route-name -> component-name map once per build.\n // This enables `:to`-based methods to return `new <TargetPage>(page)`.\n if (!routerAwarePoms) {\n setRouteNameToComponentNameMap(new Map());\n setResolveToComponentNameFn(() => null);\n return;\n }\n\n if (!resolvedRouterEntry)\n throw new Error(\"[vue-pom-generator] router.entry is required when router introspection is enabled.\");\n const { routeNameMap, routePathMap } = await parseRouterFileFromCwd(resolvedRouterEntry);\n setRouteNameToComponentNameMap(routeNameMap);\n\n // Provide a resolve()-like helper:\n // - string: treat as literal path, exact match\n // - object: prefer name (normalized key), fallback to literal path\n setResolveToComponentNameFn((to) => {\n if (typeof to === \"string\") {\n return routePathMap.get(to) ?? null;\n }\n\n const maybe = to as { name?: string; path?: string };\n if (typeof maybe.name === \"string\" && maybe.name.length) {\n const key = toPascalCase(maybe.name);\n return routeNameMap.get(key) ?? null;\n }\n if (typeof maybe.path === \"string\" && maybe.path.length) {\n return routePathMap.get(maybe.path) ?? null;\n }\n return null;\n });\n\n if (!fs.existsSync(basePageClassPath)) {\n this.error(`BasePage.ts not found at ${basePageClassPath}. Ensure it is included in the build.`);\n }\n this.addWatchFile(basePageClassPath);\n\n const pointerPath = path.resolve(path.dirname(basePageClassPath), \"Pointer.ts\");\n if (!fs.existsSync(pointerPath)) {\n this.error(`Pointer.ts not found at ${pointerPath}. Ensure it is included in the build.`);\n }\n this.addWatchFile(pointerPath);\n },\n buildEnd() {\n const entryCount = componentHierarchyMap.size;\n if (entryCount <= 0) {\n // Skip generation rather than overwriting an existing aggregated file with an empty one.\n return;\n }\n\n if (entryCount < lastGeneratedEntryCount) {\n // If we already generated from a richer pass, do not clobber it with a smaller/partial pass.\n return;\n }\n\n generateFiles(componentHierarchyMap, vueFilesPathMap, normalizedBasePagePath, {\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n projectRoot: projectRootRef.current,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n vueRouterFluentChaining: routerAwarePoms,\n routerEntry: resolvedRouterEntry,\n });\n lastGeneratedEntryCount = entryCount;\n loggerRef.current.info(`generated POMs (${entryCount} entries)`);\n },\n closeBundle() {\n loggerRef.current.info(\"build complete\");\n },\n } satisfies PluginOption;\n}\n","// Shared click-instrumentation contract between the Vue template transform and\n// the generated Playwright Page Object Model runtime.\n\nexport const TESTID_CLICK_EVENT_NAME = \"__testid_event__\";\n\n// When strict mode is enabled, the injected click wrapper will fail fast if it\n// cannot emit the expected event.\nexport const TESTID_CLICK_EVENT_STRICT_FLAG = \"__testid_click_event_strict__\";\n\nexport interface TestIdClickEventDetail {\n testId?: string;\n phase?: \"before\" | \"after\" | \"error\" | string;\n err?: string;\n}\n","import type {\n ElementNode,\n NodeTransform,\n RootNode,\n TemplateChildNode,\n AttributeNode,\n DirectiveNode,\n SimpleExpressionNode,\n CompoundExpressionNode,\n IfNode,\n IfBranchNode,\n} from \"@vue/compiler-core\";\nimport type { AttributeValue, HierarchyMap } from \"./utils\";\nimport { NodeTypes, stringifyExpression } from \"@vue/compiler-core\";\nimport { parse as parseSfc } from \"@vue/compiler-sfc\";\nimport { parse as parseTemplate } from \"@vue/compiler-dom\";\nimport { parseExpression } from \"@babel/parser\";\nimport path from \"node:path\";\nimport fs from \"node:fs\";\nimport process from \"node:process\";\nimport { TESTID_CLICK_EVENT_NAME, TESTID_CLICK_EVENT_STRICT_FLAG } from \"./click-instrumentation\";\nimport {\n upsertAttribute,\n findTestIdAttribute,\n formatTagName,\n getComposedClickHandlerContent,\n getIdOrName,\n getInnerText,\n getContainedInVForDirectiveKeyValue,\n tryGetContainedInStaticVForSourceLiteralValues,\n getKeyDirectiveValue,\n getNativeWrapperTransformInfo,\n getSelfClosingForDirectiveKeyAttrValue,\n nodeHandlerAttributeInfo,\n tryGetClickDirective,\n nodeHasToDirective,\n generateToDirectiveDataTestId,\n toDirectiveObjectFieldNameValue,\n staticAttributeValue,\n templateAttributeValue,\n tryResolveToDirectiveTargetComponentName,\n IDataTestId,\n IComponentDependencies,\n NativeWrappersMap,\n applyResolvedDataTestId,\n tryGetExistingElementDataTestId,\n} from \"./utils\";\n\nconst CLICK_EVENT_NAME = TESTID_CLICK_EVENT_NAME;\nconst ENABLE_CLICK_INSTRUMENTATION = true;\n\n// Cache inferred wrapper configs across transforms/build passes.\n// Keyed by component tag name (e.g. \"CustomInput\").\nconst inferredNativeWrapperConfigByTag = new Map<string, { role: string }>();\n\nfunction trimLeadingSeparators(value: string): string {\n if (!value) {\n return \"\";\n }\n let i = 0;\n while (i < value.length) {\n const ch = value[i];\n if (ch === \"-\" || ch === \"_\" || ch === \" \" || ch === \"\\t\" || ch === \"\\n\" || ch === \"\\r\") {\n i += 1;\n continue;\n }\n break;\n }\n return value.slice(i);\n}\n\nfunction getConditionalDirectiveInfo(element: ElementNode): { kind: \"if\" | \"else-if\" | \"else\"; source: string } | null {\n const directive = element.props.find((p): p is DirectiveNode => {\n return p.type === NodeTypes.DIRECTIVE && (p.name === \"if\" || p.name === \"else-if\" || p.name === \"else\" || p.name === \"elseif\");\n });\n\n if (!directive)\n return null;\n\n // Some compiler versions/paths represent `v-else-if` as directive.name === \"else\" with an expression.\n if (directive.name === \"else\") {\n const exp = directive.exp;\n if (exp && (exp.type === NodeTypes.SIMPLE_EXPRESSION || exp.type === NodeTypes.COMPOUND_EXPRESSION)) {\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n return { kind: \"else-if\", source };\n }\n return { kind: \"else\", source: \"\" };\n }\n\n // Alternate naming for else-if.\n if (directive.name === \"elseif\") {\n const exp = directive.exp;\n if (!exp || (exp.type !== NodeTypes.SIMPLE_EXPRESSION && exp.type !== NodeTypes.COMPOUND_EXPRESSION))\n return null;\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n return { kind: \"else-if\", source };\n }\n\n const exp = directive.exp;\n if (!exp || (exp.type !== NodeTypes.SIMPLE_EXPRESSION && exp.type !== NodeTypes.COMPOUND_EXPRESSION))\n return null;\n\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n return { kind: directive.name as \"if\" | \"else-if\", source };\n}\n\nfunction tryExtractStableHintFromConditionalExpressionSource(source: string): string | null {\n const src = (source ?? \"\").trim();\n if (!src)\n return null;\n\n const isIdentifierish = (value: string): boolean => {\n const v = value.trim();\n if (!v)\n return false;\n const isAlpha = (ch: number) => (ch >= 65 && ch <= 90) || (ch >= 97 && ch <= 122);\n const isDigit = (ch: number) => ch >= 48 && ch <= 57;\n const isUnderscore = (ch: number) => ch === 95;\n\n const first = v.charCodeAt(0);\n if (!isAlpha(first))\n return false;\n\n for (let i = 1; i < v.length; i += 1) {\n const ch = v.charCodeAt(i);\n if (isAlpha(ch) || isDigit(ch) || isUnderscore(ch)) {\n continue;\n }\n return false;\n }\n return true;\n };\n\n try {\n const expr = parseExpression(src, { plugins: [\"typescript\"] }) as object;\n\n const isNodeType = (n: object | null, type: string): n is { type: string } => {\n return n !== null && (n as { type?: string }).type === type;\n };\n const isStringLiteralNode = (n: object | null): n is { type: \"StringLiteral\"; value: string } => {\n return isNodeType(n, \"StringLiteral\") && typeof (n as { value?: string }).value === \"string\";\n };\n const isIdentifierNode = (n: object | null): n is { type: \"Identifier\"; name: string } => {\n return isNodeType(n, \"Identifier\") && typeof (n as { name?: string }).name === \"string\";\n };\n\n const results: string[] = [];\n\n const walk = (n: object | null) => {\n if (!n)\n return;\n\n if (isStringLiteralNode(n)) {\n const v = (n.value ?? \"\").trim();\n if (isIdentifierish(v)) {\n results.push(v);\n }\n }\n\n if (isIdentifierNode(n)) {\n const v = (n.name ?? \"\").trim();\n if (isIdentifierish(v)) {\n results.push(v);\n }\n }\n\n const node = n as Record<string, unknown>;\n for (const value of Object.values(node)) {\n if (!value)\n continue;\n if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === \"object\") {\n walk(item as object);\n }\n }\n continue;\n }\n if (typeof value === \"object\") {\n walk(value as object);\n }\n }\n };\n\n walk(expr);\n return results.length ? results[results.length - 1]! : null;\n }\n catch {\n return null;\n }\n}\n\nfunction tryInferNativeWrapperRoleFromSfc(tag: string): { role: \"input\" | \"select\" } | null {\n // Only attempt inference for PascalCase component tags.\n const first = tag.charCodeAt(0);\n const isUpper = first >= 65 && first <= 90;\n if (!isUpper)\n return null;\n\n const cached = inferredNativeWrapperConfigByTag.get(tag);\n if (cached)\n return cached as { role: \"input\" | \"select\" };\n\n // Prefer conventional paths in this repo.\n const candidates = [\n path.resolve(process.cwd(), \"src/components\", `${tag}.vue`),\n ];\n\n const filePath = candidates.find(p => fs.existsSync(p));\n if (!filePath) {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n }\n\n let source = \"\";\n try {\n source = fs.readFileSync(filePath, \"utf8\");\n }\n catch {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n }\n\n // Parse the SFC and then parse the template into an AST to find the first meaningful element.\n // This avoids brittle string scanning and correctly ignores comments/whitespace.\n let template = \"\";\n try {\n const { descriptor } = parseSfc(source, { filename: filePath });\n template = descriptor.template?.content ?? \"\";\n }\n catch {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n }\n\n if (!template.trim()) {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n }\n\n let rootTag = \"\";\n try {\n const ast = parseTemplate(template, { comments: false });\n\n // Find first Element-like node in root children (skip text/comments).\n // We intentionally only look at the first meaningful root tag; this is a conservative heuristic.\n const children = ast.children ?? [];\n for (const child of children) {\n if (!child || typeof child !== \"object\")\n continue;\n // NodeTypes.ELEMENT === 1\n if (child.type === NodeTypes.ELEMENT && typeof child.tag === \"string\") {\n rootTag = (child.tag || \"\").toLowerCase();\n break;\n }\n }\n }\n catch {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n }\n\n // Only infer for a few safe primitives.\n if (rootTag === \"input\" || rootTag === \"textarea\") {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"input\" });\n return { role: \"input\" };\n }\n if (rootTag === \"select\") {\n inferredNativeWrapperConfigByTag.set(tag, { role: \"select\" });\n return { role: \"select\" };\n }\n\n inferredNativeWrapperConfigByTag.set(tag, { role: \"\" });\n return null;\n}\n\nfunction tryWrapClickDirectiveForTestEvents(element: ElementNode, testIdAttribute: string): void {\n const jsStringLiteral = (value: string) => {\n // Use JSON.stringify to safely escape quotes/newlines.\n return JSON.stringify(value);\n };\n\n // Prefer using the template node's data-testid (static or bound) so wrapper components\n // like <AppButton data-testid=\"...\"> still emit the expected id even though the\n // underlying DOM <button> doesn't have the attribute.\n const getTestIdExpressionForNode = (): string => {\n const existing = findTestIdAttribute(element, testIdAttribute);\n if (!existing) {\n return \"undefined\";\n }\n\n if (existing.type === NodeTypes.ATTRIBUTE) {\n const v = existing.value?.content;\n if (!v) {\n return \"undefined\";\n }\n return jsStringLiteral(v);\n }\n\n // :<attr>=\"...\" / v-bind:<attr>=\"...\"\n const directive = existing as DirectiveNode;\n const exp = directive.exp;\n if (!exp || exp.type !== NodeTypes.SIMPLE_EXPRESSION) {\n return \"undefined\";\n }\n const content = (exp.content ?? \"\").trim();\n if (!content) {\n return \"undefined\";\n }\n // Use the bound expression verbatim; it will be evaluated in the same scope as the handler.\n return `(${content})`;\n };\n\n const testIdExpression = getTestIdExpressionForNode();\n\n // Find @click / v-on:click directive.\n const clickDirective = tryGetClickDirective(element);\n\n if (!clickDirective)\n return;\n\n // Mark nodes whose click handlers we instrument so the Playwright runtime can\n // deterministically decide whether it should wait for the event.\n // (Avoids env-var gating and avoids waiting on clicks that aren't instrumented.)\n const hasInstrumentedAttr = element.props.some(p => p.type === NodeTypes.ATTRIBUTE && p.name === \"data-click-instrumented\");\n if (!hasInstrumentedAttr) {\n upsertAttribute(element, \"data-click-instrumented\", staticAttributeValue(\"1\"));\n }\n\n const exp = clickDirective.exp;\n if (!exp)\n return;\n\n // Avoid double-wrapping if transform runs multiple times (SSR + client passes).\n const existingSource = (exp.loc?.source ?? (exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : \"\")).trim();\n if (existingSource.includes(CLICK_EVENT_NAME))\n return;\n\n // Best-effort extract of the original handler expression.\n // For SIMPLE_EXPRESSION, prefer content; otherwise fall back to loc.source.\n const originalExpression = (exp.type === NodeTypes.SIMPLE_EXPRESSION ? exp.content : exp.loc?.source ?? \"\").trim();\n if (!originalExpression)\n return;\n\n // Vue treats v-on expressions as raw statements in many cases (e.g. multiline @click with `if (...) ...`).\n // Our wrapper must preserve that capability; otherwise the Vue compiler will try to parse statements as\n // an expression and fail.\n const isStatementBody = (() => {\n const v = originalExpression.trim();\n if (!v)\n return false;\n\n // Prefer AST parsing over string heuristics.\n // - If the handler parses as an expression, we can treat it as an expression body.\n // - If it fails to parse as an expression (e.g. `if (...) ...`, `foo(); bar();`, `{ ... }` block),\n // Vue expects statement semantics.\n try {\n parseExpression(v, { plugins: [\"typescript\"] });\n return false;\n }\n catch {\n return true;\n }\n })();\n\n // Wrap in an arrow to preserve $event semantics.\n // We intentionally read the test id at runtime from the event target rather than trying to\n // statically embed it. NOTE: wrapper components often don't forward data-testid to the actual DOM.\n // We therefore prefer the template node's data-testid expression, with an event-target fallback.\n const statementWrappedHandler = `($event) => {\n const __win = ($event && $event.view) ? $event.view : undefined;\n const __target = ($event && $event.currentTarget) ? $event.currentTarget : undefined;\n const __testIdFromNode = ${testIdExpression};\n const __testIdFromTarget = (__target && typeof __target.getAttribute === 'function') ? __target.getAttribute(${jsStringLiteral(testIdAttribute)}) : undefined;\n const __testId = (__testIdFromNode ?? __testIdFromTarget);\n const __emit = (phase, err) => {\n try {\n const __w = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n const __CustomEvent = __w && __w.CustomEvent;\n if (__w && typeof __w.dispatchEvent === 'function' && __CustomEvent) {\n __w.dispatchEvent(new __CustomEvent('${CLICK_EVENT_NAME}', { detail: { testId: __testId, phase, err: err ? String(err) : undefined } }));\n }\n } catch (e) {\n // Instrumentation must never hide failures during e2e strict mode.\n // In strict mode we rethrow so tests fail fast and the underlying problem is visible.\n // Outside strict mode we log and continue so we don't break real user clicks.\n const __w = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n if (__w && __w.console && typeof __w.console.error === 'function') {\n __w.console.error('[testid-click-event] failed to emit ${CLICK_EVENT_NAME}', e);\n }\n if (__w && (__w[${JSON.stringify(TESTID_CLICK_EVENT_STRICT_FLAG)}] === true)) {\n throw e;\n }\n }\n };\n const __w2 = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n const __P = __w2 && __w2.Promise;\n __emit('before');\n let __ret;\n try {\n __ret = (async () => {\n ${originalExpression}\n })();\n } catch (e) {\n __emit('error', e);\n throw e;\n }\n // Avoid referencing globals like Promise/globalThis directly in the template expression;\n // Vue may rewrite them to _ctx.* and break at runtime. Use window properties instead.\n if (__P && typeof __P.resolve === 'function') {\n return __P.resolve(__ret)\n .then(() => { __emit('after'); }, (e) => { __emit('error', e); throw e; });\n }\n // Fallback: if the return is thenable, attach handlers.\n if (__ret && typeof __ret.then === 'function') {\n return __ret.then(() => { __emit('after'); }, (e) => { __emit('error', e); throw e; });\n }\n __emit('after');\n return __ret;\n}`;\n\n const expressionWrappedHandler = `($event) => {\n const __win = ($event && $event.view) ? $event.view : undefined;\n const __target = ($event && $event.currentTarget) ? $event.currentTarget : undefined;\n const __testIdFromNode = ${testIdExpression};\n const __testIdFromTarget = (__target && typeof __target.getAttribute === 'function') ? __target.getAttribute(${jsStringLiteral(testIdAttribute)}) : undefined;\n const __testId = (__testIdFromNode ?? __testIdFromTarget);\n const __emit = (phase, err) => {\n try {\n const __w = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n const __CustomEvent = __w && __w.CustomEvent;\n if (__w && typeof __w.dispatchEvent === 'function' && __CustomEvent) {\n __w.dispatchEvent(new __CustomEvent('${CLICK_EVENT_NAME}', { detail: { testId: __testId, phase, err: err ? String(err) : undefined } }));\n }\n } catch (e) {\n // Instrumentation must never hide failures during e2e strict mode.\n // In strict mode we rethrow so tests fail fast and the underlying problem is visible.\n // Outside strict mode we log and continue so we don't break real user clicks.\n const __w = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n if (__w && __w.console && typeof __w.console.error === 'function') {\n __w.console.error('[testid-click-event] failed to emit ${CLICK_EVENT_NAME}', e);\n }\n if (__w && (__w[${JSON.stringify(TESTID_CLICK_EVENT_STRICT_FLAG)}] === true)) {\n throw e;\n }\n }\n };\n const __w2 = __win || (__target && __target.ownerDocument && __target.ownerDocument.defaultView);\n const __P = __w2 && __w2.Promise;\n __emit('before');\n let __ret;\n try {\n const __maybeFn = (${originalExpression});\n __ret = (typeof __maybeFn === 'function') ? __maybeFn($event) : __maybeFn;\n } catch (e) {\n __emit('error', e);\n throw e;\n }\n // Avoid referencing globals like Promise/globalThis directly in the template expression;\n // Vue may rewrite them to _ctx.* and break at runtime. Use window properties instead.\n if (__P && typeof __P.resolve === 'function') {\n return __P.resolve(__ret)\n .then((v) => { __emit('after'); return v; }, (e) => { __emit('error', e); throw e; });\n }\n if (__ret && typeof __ret.then === 'function') {\n return __ret.then((v) => { __emit('after'); return v; }, (e) => { __emit('error', e); throw e; });\n }\n __emit('after');\n return __ret;\n}`;\n\n clickDirective.exp = {\n type: NodeTypes.SIMPLE_EXPRESSION,\n content: isStatementBody ? statementWrappedHandler : expressionWrappedHandler,\n isStatic: false,\n constType: 0,\n // Preserve location metadata so downstream Vue compiler transforms don't crash.\n loc: exp.loc,\n } as SimpleExpressionNode;\n}\n\n\nlet previousFileName = \"\";\nconst hierarchyMap: HierarchyMap = new Map(); // key is child, value is parent\n/**\n * Creates a NodeTransform that adds data-testid attributes to elements\n */\nexport function createTestIdTransform(\n componentName: string,\n componentHierarchyMap: Map<string, IComponentDependencies>,\n nativeWrappers: NativeWrappersMap = {},\n excludedComponents: string[] = [],\n viewsDirAbs: string,\n options: {\n existingIdBehavior?: \"preserve\" | \"overwrite\" | \"error\";\n testIdAttribute?: string;\n nameCollisionBehavior?: \"error\" | \"warn\" | \"suffix\";\n warn?: (message: string) => void;\n } = {},\n): NodeTransform {\n const existingIdBehavior = options.existingIdBehavior ?? \"preserve\";\n const testIdAttribute = (options.testIdAttribute || \"data-testid\").trim() || \"data-testid\";\n const nameCollisionBehavior = options.nameCollisionBehavior ?? \"suffix\";\n const warn = options.warn;\n\n // Some projects (and dev environments) use symlinks. We want viewsDir containment checks\n // to behave like the filesystem does (real paths), but we must not crash for virtual\n // Vite filenames (e.g. /@fs/...) or any non-existent paths.\n const safeRealpath = (p: string) => {\n try {\n return fs.existsSync(p) ? fs.realpathSync(p) : p;\n } catch {\n return p;\n }\n };\n\n const normalizedViewsDirAbs = path.normalize(safeRealpath(path.resolve(viewsDirAbs)));\n\n // When generating methods incrementally, it’s possible for the same logical test id to be\n // encountered multiple times (e.g. due to wrapper behaviors, template shape, or repeated nodes).\n // Deduplicate by method *content* to avoid duplicate declarations in generated POM classes.\n const generatedMethodContentByComponent = new Map<string, Set<string>>();\n\n // Track the most recent conditional (v-if / v-else-if) hint for a given parent element so\n // adjacent v-else branches can derive a stable semantic hint (e.g. `else personId`).\n const lastConditionalHintByParent = new WeakMap<object, string>();\n\n // Track conditional hints per element so descendants can inherit context when they have\n // an existing data-testid but no other naming signals.\n const conditionalHintByElement = new WeakMap<ElementNode, string>();\n\n // Track conditional hints per IF_BRANCH. This is required because Vue's structural transforms\n // may remove v-if/v-else directives from element.props and instead wrap elements in IF/IF_BRANCH.\n const conditionalHintByIfBranch = new WeakMap<IfBranchNode, string>();\n\n return (node: RootNode | TemplateChildNode, context) => {\n if (excludedComponents.includes(componentName)) {\n return;\n }\n\n // Capture conditional information early (before we reach elements nested under IF_BRANCH).\n if (node.type === NodeTypes.IF) {\n const ifNode = node as IfNode;\n const branches = ifNode.branches ?? [];\n\n let lastHint: string | null = null;\n for (const branch of branches) {\n const cond = (branch.condition ?? null) as (SimpleExpressionNode | CompoundExpressionNode | null);\n\n if (!cond) {\n // else branch\n const hint = lastHint ? `else ${lastHint}` : \"else\";\n conditionalHintByIfBranch.set(branch, hint);\n continue;\n }\n\n const condSource = (cond.type === NodeTypes.SIMPLE_EXPRESSION\n ? (cond as SimpleExpressionNode).content\n : stringifyExpression(cond)).trim();\n const stable = tryExtractStableHintFromConditionalExpressionSource(condSource);\n\n if (stable) {\n conditionalHintByIfBranch.set(branch, stable);\n lastHint = stable;\n } else {\n // Still set something so downstream code can distinguish the branch shape.\n conditionalHintByIfBranch.set(branch, \"if\");\n }\n }\n\n return;\n }\n\n // Only process element nodes\n if (node.type !== NodeTypes.ELEMENT) {\n return;\n }\n\n const actualFileName = `${componentName}.vue`;\n if (previousFileName !== actualFileName) {\n previousFileName = actualFileName;\n hierarchyMap.clear();\n }\n\n const element = node as ElementNode;\n const parentIsRoot = context?.parent?.type === NodeTypes.ROOT;\n const parentElement = (!parentIsRoot && context?.parent?.type === NodeTypes.ELEMENT)\n ? (context.parent as ElementNode)\n : null;\n hierarchyMap.set(element, parentElement);\n\n // Convert any path (including Windows \"C:\\\\...\" and Vite /@fs/ paths) into a\n // normalized POSIX-ish form so `path.posix.*` helpers behave predictably.\n //\n // NOTE: `path.resolve()` on Windows returns backslashes, and `path.posix.basename()`\n // only treats '/' as a separator. If we don't normalize separators first, we can end\n // up treating the entire absolute path as the \"basename\" and generating invalid\n // identifiers like `export class C:\\\\Users\\\\...`.\n const normalizeFilePath = (filePath: string) => path.normalize(safeRealpath(path.resolve(filePath)));\n\n const getParentComponentName = () => {\n const normalizedFilePath = normalizeFilePath(context.filename);\n return path.basename(normalizedFilePath, \".vue\");\n };\n\n const parentComponentName = getParentComponentName();\n\n const normalizedFilePath = normalizeFilePath(context.filename);\n\n // Treat a component as a \"view\" when its .vue file is contained under viewsDir.\n // This uses a real path containment check instead of substring matching.\n const relToViewsDir = path.relative(normalizedViewsDirAbs, normalizedFilePath);\n const isView = !relToViewsDir.startsWith(\"..\") && !path.isAbsolute(relToViewsDir);\n\n const ensureDependencies = (parentComponentName: string) => {\n let dependencies = componentHierarchyMap.get(parentComponentName);\n if (!dependencies) {\n dependencies = {\n filePath: context.filename,\n childrenComponentSet: new Set<string>(),\n usedComponentSet: new Set<string>(),\n dataTestIdSet: new Set(),\n isView,\n methodsContent: \"\",\n };\n componentHierarchyMap.set(parentComponentName, dependencies);\n }\n return dependencies;\n };\n\n // Always register a dependencies entry for the current file.\n // Without this, files that happen to have no component-like tags and no injectable test ids\n // can be omitted from `componentHierarchyMap`, which then causes aggregated POM generation\n // to miss expected exported classes.\n //\n // NOTE: This is intentionally cheap and safe to call repeatedly.\n const dependencies = ensureDependencies(parentComponentName);\n\n const isComponentLikeTag = (tag: string) => {\n // Vue component tags are typically PascalCase or kebab-case.\n // - PascalCase: DxDataGrid\n // - kebab-case: dx-data-grid\n // HTML tags are lowercase and do not contain '-'.\n if (!tag) return false;\n const first = tag.charCodeAt(0);\n const isUpper = first >= 65 && first <= 90;\n return isUpper || tag.includes(\"-\");\n };\n\n // Track all component-like tags used in the template, even when we do not emit a data-testid.\n // This supports per-view helper attachment (e.g. Grid) based on component usage.\n if (isComponentLikeTag(element.tag)) {\n dependencies.usedComponentSet.add(element.tag);\n }\n\n // Opportunistically infer wrapper semantics for simple \"single native input\" components\n // (e.g. CustomInput/CustomTextArea) so they behave like real inputs without requiring\n // explicit configuration in vite.config.ts.\n if (!nativeWrappers[element.tag]) {\n const inferred = tryInferNativeWrapperRoleFromSfc(element.tag);\n if (inferred?.role) {\n // Cache onto the nativeWrappers map so downstream utilities (formatTagName, wrapper transform)\n // see it consistently.\n (nativeWrappers as NativeWrappersMap)[element.tag] = { role: inferred.role };\n }\n }\n\n const getBestAvailableKeyValue = () =>\n getKeyDirectiveValue(element, context)\n || getSelfClosingForDirectiveKeyAttrValue(element)\n || getContainedInVForDirectiveKeyValue(context, element, hierarchyMap);\n\n const bestKeyPlaceholder = getBestAvailableKeyValue();\n\n // If we can prove the v-for iterable is a static literal list, capture the concrete\n // values (e.g. ['One', 'Two']). Downstream codegen can use this to:\n // - emit per-key methods (clickOneButton/clickTwoButton)\n // - narrow `key: string` parameters to a literal union where we still emit keyed methods\n const keyValuesOverride = tryGetContainedInStaticVForSourceLiteralValues(context, element, hierarchyMap);\n\n // Derive a stable semantic hint from conditional directives (v-if/v-else-if/v-else) when available.\n // This helps avoid generic Button/clickButton collisions for elements that provide a data-testid\n // but otherwise have no naming signals (and we intentionally avoid innerText-based naming).\n const parentKey = (!parentIsRoot && context?.parent) ? (context.parent as object) : null;\n const conditional = getConditionalDirectiveInfo(element);\n\n let conditionalHint: string | null = null;\n\n // 1) If the v-if/v-else directive is still present on the element, use that.\n if (conditional && (conditional.kind === \"if\" || conditional.kind === \"else-if\")) {\n conditionalHint = tryExtractStableHintFromConditionalExpressionSource(conditional.source);\n if (conditionalHint && parentKey) {\n lastConditionalHintByParent.set(parentKey, conditionalHint);\n }\n }\n else if (conditional && conditional.kind === \"else\") {\n if (parentKey) {\n const previousHint = lastConditionalHintByParent.get(parentKey) ?? null;\n conditionalHint = previousHint ? `else ${previousHint}` : null;\n }\n }\n\n // 2) If structural transforms already ran, infer from IF_BRANCH wrapper.\n if (!conditionalHint && context?.parent?.type === NodeTypes.IF_BRANCH) {\n const branch = context.parent as IfBranchNode;\n conditionalHint = conditionalHintByIfBranch.get(branch) ?? null;\n\n // Fallback: if we somehow missed the IF node pass (or the branch instance wasn't cached),\n // derive a stable hint directly from the branch condition.\n if (!conditionalHint) {\n const cond = (branch.condition ?? null) as (SimpleExpressionNode | CompoundExpressionNode | null);\n if (!cond) {\n conditionalHint = \"else\";\n } else {\n const condSource = (cond.type === NodeTypes.SIMPLE_EXPRESSION\n ? (cond as SimpleExpressionNode).content\n : stringifyExpression(cond)).trim();\n conditionalHint = tryExtractStableHintFromConditionalExpressionSource(condSource) ?? \"if\";\n }\n }\n }\n\n // 2b) Also consider v-show as contextual disambiguation (common for tab bodies).\n // This is intentionally NOT innerText-based and does not parse data-testid values.\n const showDirective = element.props.find((p): p is DirectiveNode => {\n return p.type === NodeTypes.DIRECTIVE && p.name === \"show\";\n });\n if (showDirective?.exp && (showDirective.exp.type === NodeTypes.SIMPLE_EXPRESSION || showDirective.exp.type === NodeTypes.COMPOUND_EXPRESSION)) {\n const exp = showDirective.exp as SimpleExpressionNode | CompoundExpressionNode;\n const source = (exp.type === NodeTypes.SIMPLE_EXPRESSION\n ? (exp as SimpleExpressionNode).content\n : stringifyExpression(exp)).trim();\n const showHint = tryExtractStableHintFromConditionalExpressionSource(source);\n if (showHint) {\n conditionalHint = conditionalHint ? `${conditionalHint} ${showHint}` : showHint;\n }\n }\n\n // 3) Inherit conditional context from ancestor elements.\n if (!conditionalHint) {\n let cur = hierarchyMap.get(element) || null;\n while (cur) {\n const inherited = conditionalHintByElement.get(cur) ?? null;\n if (inherited) {\n conditionalHint = inherited;\n break;\n }\n cur = hierarchyMap.get(cur) || null;\n }\n }\n\n if (conditionalHint) {\n conditionalHintByElement.set(element, conditionalHint);\n }\n\n // Some branches need a formatted tag suffix / native role. Compute lazily and cache.\n let cachedTagSuffix: string | null = null;\n const getTagSuffix = () => {\n cachedTagSuffix ??= formatTagName(element, nativeWrappers);\n return cachedTagSuffix;\n };\n const getNativeRoleFromTagSuffix = () => getTagSuffix().slice(1);\n\n const getHandlerAttributeValueDataTestId = (handlerAttributeValue: string): AttributeValue => {\n const tagSuffix = getTagSuffix();\n return bestKeyPlaceholder\n ? templateAttributeValue(`${componentName}_${handlerAttributeValue}-${bestKeyPlaceholder}${tagSuffix}`)\n : staticAttributeValue(`${componentName}_${handlerAttributeValue}${tagSuffix}`);\n };\n\n const getClickDataTestId = (clickSuffix: string): AttributeValue => {\n const tagSuffix = getTagSuffix();\n return bestKeyPlaceholder\n ? templateAttributeValue(`${componentName}-${bestKeyPlaceholder}${clickSuffix}${tagSuffix}`)\n : staticAttributeValue(`${componentName}${clickSuffix}${tagSuffix}`);\n };\n\n const getSubmitDataTestId = (identifier: string): string => {\n const tagSuffix = getTagSuffix();\n return `${componentName}-${identifier}${tagSuffix}`;\n };\n\n\n const applyResolvedDataTestIdForElement = (args: {\n preferredGeneratedValue: AttributeValue;\n nativeRoleOverride?: string;\n entryOverrides?: Partial<IDataTestId>;\n addHtmlAttribute?: boolean;\n semanticNameHint?: string;\n semanticNameHintAlternates?: string[];\n pomMergeKey?: string;\n }): void => {\n const nativeRole = args.nativeRoleOverride ?? getNativeRoleFromTagSuffix();\n applyResolvedDataTestId({\n element,\n componentName,\n parentComponentName,\n context,\n contextFilename: context.filename,\n dependencies,\n generatedMethodContentByComponent,\n nativeRole,\n preferredGeneratedValue: args.preferredGeneratedValue,\n bestKeyPlaceholder,\n keyValuesOverride,\n entryOverrides: args.entryOverrides,\n semanticNameHint: args.semanticNameHint,\n semanticNameHintAlternates: args.semanticNameHintAlternates,\n pomMergeKey: args.pomMergeKey,\n addHtmlAttribute: args.addHtmlAttribute ?? true,\n testIdAttribute,\n existingIdBehavior,\n nameCollisionBehavior,\n warn,\n });\n };\n\n // Inline the old nodeShouldBeIgnored gating logic, but compute signals incrementally.\n // Native wrapper detection + option-prefix needs are computed in one place to avoid duplicate checks.\n const { nativeWrappersValue, optionDataTestIdPrefixValue, semanticNameHint } = getNativeWrapperTransformInfo(element, componentName, nativeWrappers);\n\n if (nativeWrappersValue) {\n // Some wrappers (e.g. option-driven selects) require the option prefix even when we have a\n // native wrapper data-testid. Apply the prefix before we return.\n if (optionDataTestIdPrefixValue) {\n upsertAttribute(element, \"option-data-testid-prefix\", optionDataTestIdPrefixValue);\n }\n\n const nativeRole = nativeWrappers[element.tag]?.role ?? element.tag;\n\n // Wrapper-derived hints are often shared (e.g. many branches bind the same v-model path).\n // In strict collision mode, keep the primary hint stable, but provide conditional context\n // as an alternate hint so applyResolvedDataTestId can fall back to it only when needed.\n const primarySemanticHint = semanticNameHint || conditionalHint || undefined;\n const alternates = (nameCollisionBehavior === \"error\" && semanticNameHint && conditionalHint)\n ? [`${semanticNameHint} ${conditionalHint}`]\n : undefined;\n\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue: nativeWrappersValue,\n nativeRoleOverride: nativeRole,\n semanticNameHint: primarySemanticHint,\n semanticNameHintAlternates: alternates,\n });\n return;\n }\n\n // RouterLink / :to is a special case; handle it early.\n const toDirective = nodeHasToDirective(element);\n if (toDirective) {\n const dataTestId = generateToDirectiveDataTestId(componentName, element, toDirective, context, hierarchyMap, nativeWrappers);\n const target = tryResolveToDirectiveTargetComponentName(toDirective);\n const routeNameHint = toDirectiveObjectFieldNameValue(toDirective);\n // IMPORTANT: Do not use innerText as a naming disambiguator here; route target identity\n // should drive merging when multiple elements navigate to the same target.\n const semanticNameHint = routeNameHint || target || conditionalHint || undefined;\n\n const rawTo = (toDirective.exp?.loc?.source ?? \"\").trim();\n const pomMergeKey = routeNameHint\n ? `to:name:${routeNameHint}`\n : (rawTo ? `to:expr:${rawTo}` : undefined);\n\n // If the author already provided a data-testid, the generator may choose not to\n // auto-generate one for :to. In that case, still register the element so we\n // generate the fluent goTo* method using the existing id.\n const existing = tryGetExistingElementDataTestId(element, testIdAttribute);\n\n const preferredGeneratedValue = dataTestId\n ?? (existing ? staticAttributeValue(existing.value) : null);\n\n if (!preferredGeneratedValue) {\n return;\n }\n\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue,\n entryOverrides: target ? { targetPageObjectModelClass: target } : {},\n semanticNameHint,\n pomMergeKey,\n });\n return;\n }\n\n const handlerInfo = nodeHandlerAttributeInfo(element);\n if (handlerInfo) {\n const testId = getHandlerAttributeValueDataTestId(handlerInfo.semanticNameHint);\n\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue: testId,\n semanticNameHint: handlerInfo.semanticNameHint || conditionalHint || undefined,\n pomMergeKey: handlerInfo.mergeKey,\n });\n return;\n }\n\n // From here on out, we only care about:\n // - @click nodes\n // - submit buttons with an id/name\n // - nodes that require option-data-testid-prefix (even if they don't have click/submit)\n const innerText = getInnerText(element) || null;\n const clickDirective = tryGetClickDirective(element);\n if (clickDirective) {\n const clickSuffix = getComposedClickHandlerContent(element, context, innerText, clickDirective, {\n componentName,\n contextFilename: context.filename,\n });\n\n // Derive a semantic hint from the click suffix (which is already derived from AST and/or innerText).\n // This is NOT derived by parsing the final data-testid.\n const clickHint = trimLeadingSeparators(clickSuffix) || undefined;\n const idOrName = getIdOrName(element) || undefined;\n // IMPORTANT: Do not use innerText for semantic naming. When multiple mutually-exclusive\n // elements share the same click handler, we merge by handler identity instead.\n const semanticNameHint = clickHint || idOrName || conditionalHint || undefined;\n\n // Use the same AST-derived click hint as the merge key so wrapper expressions like\n // `() => doThing()` and `doThing()` can still merge.\n const pomMergeKey = clickHint ? `click:hint:${clickHint}` : undefined;\n\n const testId = getClickDataTestId(clickSuffix);\n\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue: testId,\n semanticNameHint,\n pomMergeKey,\n });\n\n // Instrument @click handlers so Playwright can wait on deterministic UI-side events\n // without relying on network inspection.\n if (ENABLE_CLICK_INSTRUMENTATION) {\n tryWrapClickDirectiveForTestEvents(element, testIdAttribute);\n }\n return;\n }\n\n const existingElementDataTestId = tryGetExistingElementDataTestId(element, testIdAttribute);\n if (existingElementDataTestId?.value) {\n // Only generate POM members for existing test ids when the element is something we\n // consider interactive (based on role inferred from tag suffix).\n //\n // This avoids polluting POMs with static content nodes like <label>/<p> that often\n // have data-testid for assertions but should not get click* APIs.\n const inferredRole = getNativeRoleFromTagSuffix().toLowerCase();\n const isRecognizedInteractiveRole = inferredRole === \"button\"\n || inferredRole === \"input\"\n || inferredRole === \"select\"\n || inferredRole === \"vselect\"\n || inferredRole === \"checkbox\"\n || inferredRole === \"toggle\"\n || inferredRole === \"radio\";\n\n if (!isRecognizedInteractiveRole) {\n return;\n }\n\n const identifierHint = getIdOrName(element) || conditionalHint || undefined;\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue: staticAttributeValue(existingElementDataTestId.value),\n semanticNameHint: identifierHint,\n });\n return;\n }\n const isSubmit = (element.props.find((p): p is AttributeNode => p.type === NodeTypes.ATTRIBUTE && p.name === \"type\")?.value?.content === \"submit\");\n if (isSubmit) {\n // Prefer explicit identity (id/name), otherwise fall back to literal inner text.\n const identifier = getIdOrName(element) || innerText;\n if (!identifier) {\n const loc = element.loc?.start;\n const locationHint = loc ? `${loc.line}:${loc.column}` : \"unknown\";\n throw new Error(\n `[vue-pom-generator] submit button appears identifiable but no usable identity could be derived in ${componentName} (${context.filename ?? \"unknown\"}:${locationHint}) — `\n + `id/name were missing/empty and innerText was also missing/invalid`,\n );\n }\n\n const testId = getSubmitDataTestId(identifier);\n\n applyResolvedDataTestIdForElement({\n preferredGeneratedValue: staticAttributeValue(testId),\n semanticNameHint: identifier,\n });\n }\n };\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { performance } from \"node:perf_hooks\";\n\nimport * as compilerDom from \"@vue/compiler-dom\";\nimport { parse as parseSfc } from \"@vue/compiler-sfc\";\nimport type { PluginOption, ViteDevServer } from \"vite\";\n\nimport { generateFiles } from \"../../class-generation\";\nimport { parseRouterFileFromCwd } from \"../../router-introspection\";\nimport { createTestIdTransform } from \"../../transform\";\nimport { setResolveToComponentNameFn, setRouteNameToComponentNameMap, toPascalCase } from \"../../utils\";\nimport type { IComponentDependencies, NativeWrappersMap } from \"../../utils\";\nimport type { VuePomGeneratorLogger } from \"../logger\";\n\ninterface DevProcessorOptions {\n nativeWrappers: NativeWrappersMap;\n excludedComponents: string[];\n viewsDir: string;\n\n projectRootRef: { current: string };\n normalizedBasePagePath: string;\n basePageClassPath: string;\n\n outDir?: string;\n emitLanguages?: Array<\"ts\" | \"csharp\">;\n generateFixtures?: boolean | string | { outDir?: string };\n customPomAttachments?: Array<{ className: string; propertyName: string; attachWhenUsesComponents: string[]; attachTo?: \"views\" | \"components\" | \"both\" }>;\n customPomDir?: string;\n customPomImportAliases?: Record<string, string>;\n testIdAttribute: string;\n\n routerAwarePoms: boolean;\n resolvedRouterEntry?: string;\n\n loggerRef: { current: VuePomGeneratorLogger };\n}\n\nexport function createDevProcessorPlugin(options: DevProcessorOptions): PluginOption {\n const {\n nativeWrappers,\n excludedComponents,\n viewsDir,\n projectRootRef,\n normalizedBasePagePath,\n basePageClassPath,\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n routerAwarePoms,\n resolvedRouterEntry,\n loggerRef,\n } = options;\n\n // Bridge between configureServer (where we have timers/logger) and handleHotUpdate.\n let scheduleVueFileRegen: ((filePath: string, source: \"hmr\" | \"fs\") => void) | null = null;\n\n return {\n name: \"vue-pom-generator-dev\",\n apply: \"serve\",\n\n // Prefer hot-update events over filesystem change events for speed and reliability.\n // This fires when Vite has actually processed the module update.\n handleHotUpdate(ctx) {\n if (!scheduleVueFileRegen)\n return;\n if (!ctx.file.endsWith(\".vue\"))\n return;\n if (!ctx.file.includes(`${path.sep}src${path.sep}`))\n return;\n\n scheduleVueFileRegen(ctx.file, \"hmr\");\n },\n\n configureServer(server: ViteDevServer) {\n // Router introspection (dev-server): mirror the buildStart behavior.\n const routerInitPromise = (async () => {\n if (!routerAwarePoms) {\n setRouteNameToComponentNameMap(new Map());\n setResolveToComponentNameFn(() => null);\n return;\n }\n\n if (!resolvedRouterEntry)\n throw new Error(\"[vue-pom-generator] router.entry is required when router introspection is enabled.\");\n const { routeNameMap, routePathMap } = await parseRouterFileFromCwd(resolvedRouterEntry);\n setRouteNameToComponentNameMap(routeNameMap);\n setResolveToComponentNameFn((to) => {\n if (typeof to === \"string\") {\n return routePathMap.get(to) ?? null;\n }\n\n const maybe = to as { name?: string; path?: string };\n if (typeof maybe.name === \"string\" && maybe.name.length) {\n const key = toPascalCase(maybe.name);\n return routeNameMap.get(key) ?? null;\n }\n if (typeof maybe.path === \"string\" && maybe.path.length) {\n return routePathMap.get(maybe.path) ?? null;\n }\n return null;\n });\n })();\n\n const logInfo = (message: string) => loggerRef.current.info(message);\n const logDebug = (message: string) => loggerRef.current.debug(message);\n\n let scheduleVueFileRegenLocal: ((filePath: string, source: \"hmr\" | \"fs\") => void) | null = null;\n\n const formatMs = (ms: number) => `${ms.toFixed(1)}ms`;\n\n const getViewsDirAbs = () => (path.isAbsolute(viewsDir)\n ? viewsDir\n : path.resolve(projectRootRef.current, viewsDir));\n\n const extractTemplateFromSfc = (source: string, filename?: string): string => {\n const { descriptor } = parseSfc(source, {\n filename: filename ?? \"anonymous.vue\",\n });\n return descriptor.template?.content ?? \"\";\n };\n\n const walkFilesRecursive = (rootDir: string): string[] => {\n const out: string[] = [];\n const stack: string[] = [rootDir];\n while (stack.length) {\n const dir = stack.pop();\n if (!dir) continue;\n let entries: Array<fs.Dirent> = [];\n try {\n entries = fs.readdirSync(dir, { withFileTypes: true });\n }\n catch {\n continue;\n }\n\n for (const ent of entries) {\n if (ent.isDirectory()) {\n if (ent.name === \"node_modules\" || ent.name === \".git\" || ent.name === \"dist\")\n continue;\n stack.push(path.join(dir, ent.name));\n continue;\n }\n if (ent.isFile() && ent.name.endsWith(\".vue\")) {\n out.push(path.join(dir, ent.name));\n }\n }\n }\n return out;\n };\n\n // Build a complete snapshot once, then incrementally update on each changed .vue.\n const snapshotHierarchy = new Map<string, IComponentDependencies>();\n const snapshotVuePathMap = new Map<string, string>();\n const filePathToComponentName = new Map<string, string>();\n\n const getComponentNameForFile = (filePath: string) => {\n const normalized = path.resolve(filePath);\n const existing = filePathToComponentName.get(normalized);\n if (existing)\n return existing;\n const name = path.basename(normalized, \".vue\");\n filePathToComponentName.set(normalized, name);\n return name;\n };\n\n const compileVueFileIntoSnapshot = (filePath: string) => {\n const started = performance.now();\n const absolutePath = path.resolve(filePath);\n const componentName = getComponentNameForFile(absolutePath);\n snapshotVuePathMap.set(componentName, absolutePath);\n\n // Ensure a clean rebuild for this component to avoid stale accumulation.\n snapshotHierarchy.delete(componentName);\n\n let sfc = \"\";\n try {\n sfc = fs.readFileSync(absolutePath, \"utf8\");\n }\n catch {\n return { componentName, ms: performance.now() - started, compiled: false };\n }\n\n const template = extractTemplateFromSfc(sfc, absolutePath);\n if (!template.trim())\n return { componentName, ms: performance.now() - started, compiled: true };\n\n try {\n compilerDom.compile(template, {\n filename: absolutePath,\n prefixIdentifiers: true,\n nodeTransforms: [\n createTestIdTransform(\n componentName,\n snapshotHierarchy,\n nativeWrappers,\n excludedComponents,\n getViewsDirAbs(),\n { existingIdBehavior: \"preserve\", testIdAttribute },\n ),\n ],\n });\n }\n catch {\n // If a template fails to compile, Vite will surface errors during normal dev.\n // We keep the last-known good snapshot entry deleted so the regen reflects current state.\n }\n\n return { componentName, ms: performance.now() - started, compiled: true };\n };\n\n const fullRebuildSnapshotFromFilesystem = () => {\n const srcDir = path.resolve(projectRootRef.current, \"src\");\n if (!fs.existsSync(srcDir))\n return;\n\n const t0 = performance.now();\n snapshotHierarchy.clear();\n snapshotVuePathMap.clear();\n filePathToComponentName.clear();\n\n const vueFiles = walkFilesRecursive(srcDir);\n logInfo(`initial scan: found ${vueFiles.length} .vue files under src/`);\n\n let compiledCount = 0;\n for (const file of vueFiles) {\n const res = compileVueFileIntoSnapshot(file);\n if (res.compiled)\n compiledCount++;\n }\n\n const t1 = performance.now();\n logInfo(`initial compile: ${compiledCount}/${vueFiles.length} files in ${formatMs(t1 - t0)} (components=${snapshotHierarchy.size})`);\n };\n\n const generateAggregatedFromSnapshot = (reason: string) => {\n const t0 = performance.now();\n generateFiles(snapshotHierarchy, snapshotVuePathMap, normalizedBasePagePath, {\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n projectRoot: projectRootRef.current,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n vueRouterFluentChaining: routerAwarePoms,\n routerEntry: resolvedRouterEntry,\n });\n const t1 = performance.now();\n logInfo(`generate(${reason}): components=${snapshotHierarchy.size} in ${formatMs(t1 - t0)}`);\n };\n\n const initialBuildPromise = (async () => {\n const t0 = performance.now();\n await routerInitPromise;\n fullRebuildSnapshotFromFilesystem();\n generateAggregatedFromSnapshot(\"startup\");\n const t1 = performance.now();\n logInfo(`startup total: ${formatMs(t1 - t0)}`);\n })();\n\n const watchedVueGlob = path.resolve(projectRootRef.current, \"src\", \"**\", \"*.vue\");\n const watchedPluginGlob = path.resolve(projectRootRef.current, \"vite-plugins\", \"vue-pom-generator\", \"**\", \"*.ts\");\n server.watcher.add([watchedVueGlob, watchedPluginGlob, basePageClassPath]);\n\n let timer: NodeJS.Timeout | null = null;\n let maxWaitTimer: NodeJS.Timeout | null = null;\n const pendingChangedVueFiles = new Set<string>();\n const pendingDeletedComponents = new Set<string>();\n\n scheduleVueFileRegenLocal = (filePath: string, source: \"hmr\" | \"fs\") => {\n pendingChangedVueFiles.add(filePath);\n logDebug(`queued(${source}): files=${pendingChangedVueFiles.size} deleted=${pendingDeletedComponents.size}`);\n scheduleAggregatedRegen();\n };\n\n scheduleVueFileRegen = scheduleVueFileRegenLocal;\n\n function scheduleAggregatedRegen() {\n const wasEmpty = pendingChangedVueFiles.size === 0 && pendingDeletedComponents.size === 0;\n\n const MAX_WAIT_MS = 750;\n if (!maxWaitTimer) {\n maxWaitTimer = setTimeout(() => {\n if (timer) {\n clearTimeout(timer);\n timer = null;\n }\n maxWaitTimer = null;\n void (async () => {\n const t0 = performance.now();\n await initialBuildPromise;\n\n for (const componentName of pendingDeletedComponents) {\n snapshotHierarchy.delete(componentName);\n snapshotVuePathMap.delete(componentName);\n }\n\n const files = Array.from(pendingChangedVueFiles);\n const deletedCount = pendingDeletedComponents.size;\n pendingChangedVueFiles.clear();\n pendingDeletedComponents.clear();\n\n let compileMs = 0;\n for (const f of files) {\n const res = compileVueFileIntoSnapshot(f);\n compileMs += res.ms;\n }\n\n const t1 = performance.now();\n generateAggregatedFromSnapshot(\"max-wait\");\n const t2 = performance.now();\n\n logInfo(\n `max-wait: files=${files.length} deleted=${deletedCount} `\n + `compile=${formatMs(compileMs)} wall=${formatMs(t1 - t0)} gen=${formatMs(t2 - t1)} total=${formatMs(t2 - t0)}`,\n );\n })();\n }, MAX_WAIT_MS);\n }\n\n if (wasEmpty) {\n const queuedFiles = pendingChangedVueFiles.size;\n const queuedDeletes = pendingDeletedComponents.size;\n logDebug(`queued: files=${queuedFiles} deleted=${queuedDeletes}`);\n }\n\n if (timer)\n clearTimeout(timer);\n timer = setTimeout(() => {\n timer = null;\n if (maxWaitTimer) {\n clearTimeout(maxWaitTimer);\n maxWaitTimer = null;\n }\n\n void (async () => {\n const t0 = performance.now();\n await initialBuildPromise;\n\n for (const componentName of pendingDeletedComponents) {\n snapshotHierarchy.delete(componentName);\n snapshotVuePathMap.delete(componentName);\n }\n\n const files = Array.from(pendingChangedVueFiles);\n const deletedCount = pendingDeletedComponents.size;\n pendingChangedVueFiles.clear();\n pendingDeletedComponents.clear();\n\n let compileMs = 0;\n for (const f of files) {\n const res = compileVueFileIntoSnapshot(f);\n compileMs += res.ms;\n }\n\n const t1 = performance.now();\n generateAggregatedFromSnapshot(files.length || deletedCount ? \"batched\" : \"noop\");\n const t2 = performance.now();\n\n if (files.length || deletedCount) {\n logInfo(\n `batched: files=${files.length} deleted=${deletedCount} `\n + `compile=${formatMs(compileMs)} wall=${formatMs(t1 - t0)} gen=${formatMs(t2 - t1)} total=${formatMs(t2 - t0)}`,\n );\n }\n })();\n }, 75);\n }\n\n server.watcher.on(\"change\", async (changedPath) => {\n const changedAbsPosix = path.posix.normalize(path.resolve(changedPath));\n\n // Ignore generated outputs to prevent infinite rebuild loops.\n const outDirAbsPosix = path.posix.normalize(path.resolve(projectRootRef.current, outDir ?? \"./pom\"));\n if (\n changedAbsPosix.startsWith(`${outDirAbsPosix}/`)\n && (changedAbsPosix.endsWith(\".g.ts\") || changedAbsPosix.endsWith(\".g.ts.map\"))\n ) {\n return;\n }\n\n if (changedAbsPosix.includes(\"/vite-plugins/vue-pom-generator/\")) {\n void server.restart();\n }\n });\n\n server.watcher.on(\"add\", (p) => {\n if (typeof p !== \"string\")\n return;\n if (!p.endsWith(\".vue\") || !p.includes(`${path.sep}src${path.sep}`))\n return;\n void (async () => {\n await initialBuildPromise;\n pendingChangedVueFiles.add(p);\n scheduleAggregatedRegen();\n })();\n });\n\n server.watcher.on(\"unlink\", (p) => {\n if (typeof p !== \"string\")\n return;\n if (!p.endsWith(\".vue\") || !p.includes(`${path.sep}src${path.sep}`))\n return;\n void (async () => {\n await initialBuildPromise;\n const absolutePath = path.resolve(p);\n const componentName = getComponentNameForFile(absolutePath);\n filePathToComponentName.delete(absolutePath);\n pendingDeletedComponents.add(componentName);\n scheduleAggregatedRegen();\n })();\n });\n\n setTimeout(() => {\n // The initial snapshot build/generate is started immediately above.\n }, 250);\n },\n } satisfies PluginOption;\n}\n","/**\r\n * Test ID manifest generator utilities\r\n * Generates TypeScript types and manifests from collected test IDs\r\n */\r\n\r\n/**\r\n * Generates the complete virtual:testids module content\r\n */\r\nexport function generateTestIdsModule(componentTestIds: Map<string, Set<string>>): string {\r\n const manifestEntries = Array.from(componentTestIds.entries())\r\n .sort((a, b) => a[0].localeCompare(b[0]))\r\n .map(([c, set]) => ` ${JSON.stringify(c)}: ${JSON.stringify(Array.from(set).sort())}`)\r\n .join(\",\\n\");\r\n\r\n return `// Virtual module: test id manifest\r\nexport const testIdManifest = {\r\n${manifestEntries}\r\n} as const;\r\nexport type TestIdManifest = typeof testIdManifest;\r\nexport type ComponentName = keyof TestIdManifest;\r\n`;\r\n}\r\n","import type { PluginOption } from \"vite\";\nimport virtualImport from \"vite-plugin-virtual\";\n\nimport { generateTestIdsModule } from \"../../manifest-generator\";\n\nexport function createTestIdsVirtualModulesPlugin(componentTestIds: Map<string, Set<string>>): PluginOption {\n // vite-plugin-virtual has different interop shapes across bundlers; support both.\n const maybeModule = virtualImport as { default?: typeof virtualImport };\n const virtual = maybeModule.default ?? virtualImport;\n\n return virtual({\n \"virtual:testids\": () => generateTestIdsModule(componentTestIds),\n });\n}\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { PluginOption } from \"vite\";\n\nimport { createBuildProcessorPlugin } from \"./support/build-plugin\";\nimport { createDevProcessorPlugin } from \"./support/dev-plugin\";\nimport { createTestIdsVirtualModulesPlugin } from \"./support/virtual-modules\";\nimport type { VuePomGeneratorLogger } from \"./logger\";\nimport type { IComponentDependencies, NativeWrappersMap } from \"../utils\";\n\ninterface SupportFactoryOptions {\n componentTestIds: Map<string, Set<string>>;\n componentHierarchyMap: Map<string, IComponentDependencies>;\n vueFilesPathMap: Map<string, string>;\n nativeWrappers: NativeWrappersMap;\n excludedComponents: string[];\n viewsDir: string;\n\n /** Output directory for generated files (POMs + optional fixtures). */\n outDir?: string;\n\n /** Languages to emit POMs for. */\n emitLanguages?: Array<\"ts\" | \"csharp\">;\n routerAwarePoms: boolean;\n routerEntry?: string;\n\n /** Generate Playwright fixtures alongside generated POMs. */\n generateFixtures?: boolean | string | { outDir?: string };\n customPomAttachments?: Array<{ className: string; propertyName: string; attachWhenUsesComponents: string[]; attachTo?: \"views\" | \"components\" | \"both\" }>;\n projectRootRef: { current: string };\n basePageClassPath?: string;\n customPomDir?: string;\n customPomImportAliases?: Record<string, string>;\n testIdAttribute: string;\n\n loggerRef: { current: VuePomGeneratorLogger };\n}\n\nexport function createSupportPlugins(options: SupportFactoryOptions): PluginOption[] {\n const {\n componentTestIds,\n componentHierarchyMap,\n vueFilesPathMap,\n nativeWrappers,\n excludedComponents,\n viewsDir,\n outDir,\n emitLanguages,\n routerAwarePoms,\n routerEntry,\n generateFixtures,\n customPomAttachments,\n projectRootRef,\n basePageClassPath: basePageClassPathOverride,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n loggerRef,\n } = options;\n\n const resolveRouterEntry = () => {\n if (!routerAwarePoms)\n return undefined;\n if (!routerEntry)\n throw new Error(\"[vue-pom-generator] router.entry is required when router introspection is enabled.\");\n return path.isAbsolute(routerEntry) ? routerEntry : path.resolve(projectRootRef.current, routerEntry);\n };\n\n const resolvedRouterEntry = resolveRouterEntry();\n\n const getDefaultBasePageClassPath = () => {\n // Prefer resolving relative to this package so consumers don't need a repo-specific layout.\n // Works in ESM output.\n try {\n return fileURLToPath(new URL(\"../class-generation/BasePage.ts\", import.meta.url));\n }\n catch {\n // Fallback for CJS output.\n return path.resolve(__dirname, \"..\", \"class-generation\", \"BasePage.ts\");\n }\n };\n\n const basePageClassPath = basePageClassPathOverride ?? getDefaultBasePageClassPath();\n\n // Vite normalizes resolved ids to posix-style paths for plugin hooks.\n const normalizedBasePagePath = path.posix.normalize(basePageClassPath);\n\n const tsProcessor = createBuildProcessorPlugin({\n componentHierarchyMap,\n vueFilesPathMap,\n basePageClassPath,\n normalizedBasePagePath,\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n projectRootRef,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n routerAwarePoms,\n resolvedRouterEntry,\n loggerRef,\n });\n\n const devProcessor = createDevProcessorPlugin({\n nativeWrappers,\n excludedComponents,\n viewsDir,\n projectRootRef,\n normalizedBasePagePath,\n basePageClassPath,\n outDir,\n emitLanguages,\n generateFixtures,\n customPomAttachments,\n customPomDir,\n customPomImportAliases,\n testIdAttribute,\n routerAwarePoms,\n resolvedRouterEntry,\n loggerRef,\n });\n\n const virtualModules = createTestIdsVirtualModulesPlugin(componentTestIds);\n\n return [tsProcessor, devProcessor, virtualModules];\n}\n","import type {\n AttributeNode,\n DirectiveNode,\n ElementNode,\n SimpleExpressionNode,\n VNodeCall,\n} from \"@vue/compiler-core\";\nimport { NodeTypes } from \"@vue/compiler-core\";\nimport { isSimpleExpressionNode } from \"./compiler/ast-guards\";\nimport type { ElementMetadata } from \"./metadata-collector\";\n\nexport type DataTestIdProp = AttributeNode | DirectiveNode | undefined;\n\nexport function findDataTestIdProp(element: ElementNode, attributeName: string = \"data-testid\"): DataTestIdProp {\n return element.props.find(prop =>\n (prop.type === NodeTypes.ATTRIBUTE && prop.name === attributeName)\n || (prop.type === NodeTypes.DIRECTIVE\n && prop.name === \"bind\"\n && prop.arg?.type === NodeTypes.SIMPLE_EXPRESSION\n && prop.arg.content === attributeName),\n ) as AttributeNode | DirectiveNode | undefined;\n}\n\nexport function getTestIdFromProp(prop: DataTestIdProp): string | null {\n if (!prop) {\n return null;\n }\n\n if (prop.type === NodeTypes.ATTRIBUTE) {\n return prop.value ? prop.value.content : null;\n }\n\n if (prop.type === NodeTypes.DIRECTIVE) {\n return prop.exp?.type === NodeTypes.SIMPLE_EXPRESSION ? prop.exp.content : null;\n }\n\n return null;\n}\n\nexport function parseDynamicProps(dynamicProps: string | SimpleExpressionNode | undefined): string[] | undefined {\n if (!dynamicProps) {\n return undefined;\n }\n\n if (typeof dynamicProps === \"string\") {\n // Avoid string.split(); this package enforces AST/structured parsing.\n // Vue sometimes encodes dynamic props as a comma-delimited string.\n const parts: string[] = [];\n let current = \"\";\n for (let i = 0; i < dynamicProps.length; i++) {\n const ch = dynamicProps[i];\n if (ch === \",\") {\n const token = current.trim();\n if (token.length)\n parts.push(token);\n current = \"\";\n continue;\n }\n current += ch;\n }\n const last = current.trim();\n if (last.length)\n parts.push(last);\n return parts;\n }\n\n if (isSimpleExpressionNode(dynamicProps)) {\n const content = dynamicProps.content;\n\n if (content.startsWith(\"[\") && content.endsWith(\"]\")) {\n try {\n return JSON.parse(content);\n }\n catch {\n // Preserve previous behavior differences:\n // - metadata-collector returned [] on parse failure\n // - compiler-wrapper returned [content]\n // We return undefined here and let callers choose a fallback.\n return undefined;\n }\n }\n\n return [content];\n }\n\n return undefined;\n}\n\nexport function tryCreateElementMetadata(args: {\n element: ElementNode;\n semanticNameMap: Map<string, string>;\n debug: boolean;\n debugPrefix: string;\n preferJsonParseFailureAsContentArray: boolean;\n testIdAttribute?: string;\n}): ElementMetadata | null {\n const { element, semanticNameMap, debug, debugPrefix, preferJsonParseFailureAsContentArray } = args;\n const testIdAttribute = (args.testIdAttribute ?? \"data-testid\").trim() || \"data-testid\";\n\n const testIdProp = findDataTestIdProp(element, testIdAttribute);\n if (!testIdProp) {\n return null;\n }\n\n const testId = getTestIdFromProp(testIdProp);\n if (!testId) {\n return null;\n }\n\n if (!element.codegenNode || element.codegenNode.type !== NodeTypes.VNODE_CALL) {\n return null;\n }\n\n const codegenNode = element.codegenNode as VNodeCall;\n const patchFlag = codegenNode.patchFlag;\n\n let dynamicPropsList = parseDynamicProps(codegenNode.dynamicProps);\n\n // Preserve each caller's prior behavior for JSON parse failures.\n if (!dynamicPropsList\n && codegenNode.dynamicProps\n && typeof codegenNode.dynamicProps !== \"string\"\n && isSimpleExpressionNode(codegenNode.dynamicProps)) {\n const content = codegenNode.dynamicProps.content;\n if (content.startsWith(\"[\") && content.endsWith(\"]\")) {\n dynamicPropsList = preferJsonParseFailureAsContentArray ? [content] : [];\n }\n }\n\n const semanticName = semanticNameMap.get(testId);\n if (!semanticName) {\n if (debug) {\n // console.warn(`${debugPrefix} ⚠️ No semantic name found for testId=\"${testId}\"`);\n }\n return null;\n }\n\n const metadata: ElementMetadata = {\n testId,\n semanticName,\n tag: element.tag,\n tagType: element.tagType,\n patchFlag,\n dynamicProps: dynamicPropsList,\n // Decode patch flags (bitwise) - preserved as-is from existing code.\n hasClickHandler: patchFlag ? Boolean(patchFlag & 32) : undefined,\n hasDynamicClass: patchFlag ? Boolean(patchFlag & 2) : undefined,\n hasDynamicStyle: patchFlag ? Boolean(patchFlag & 4) : undefined,\n hasDynamicText: patchFlag ? Boolean(patchFlag & 1) : undefined,\n };\n\n if (debug) {\n console.log(` ${debugPrefix} ✅ <${element.tag}> testId=\"${testId}\"`);\n console.log(` patchFlag: ${patchFlag}`);\n console.log(` dynamicProps: ${dynamicPropsList?.join(\", \") || \"none\"}`);\n }\n\n return metadata;\n}\n","/**\n * Custom Vue Compiler Wrapper\n *\n * Wraps Vue's baseCompile to intercept the AST after transforms complete\n * but before code generation. This allows us to traverse the fully transformed\n * AST and extract codegenNode metadata (patchFlags, dynamicProps) for enhanced\n * Page Object Model generation.\n */\n\nimport type { ElementNode, RootNode, TemplateChildNode, TransformContext } from \"@vue/compiler-core\";\nimport type { CompilerOptions } from \"@vue/compiler-dom\";\nimport type { ElementMetadata } from \"./metadata-collector\";\nimport { NodeTypes } from \"@vue/compiler-core\";\nimport { compile } from \"@vue/compiler-dom\";\nimport { extend } from \"@vue/shared\";\nimport { findDataTestIdProp, tryCreateElementMetadata } from \"./compiler-metadata-utils\";\n\n/**\n * Traverses the AST and extracts metadata from elements with data-testid attributes\n */\nfunction extractMetadataFromAST(\n ast: RootNode,\n componentName: string,\n metadataMap: Map<string, Map<string, ElementMetadata>>,\n semanticNameMap: Map<string, string>,\n testIdAttribute: string,\n): void {\n const componentMetadata = new Map<string, ElementMetadata>();\n\n function traverseNode(node: RootNode | TemplateChildNode): void {\n if (node.type === NodeTypes.ELEMENT) {\n const element = node as ElementNode;\n\n const testIdAttr = findDataTestIdProp(element, testIdAttribute);\n if (testIdAttr) {\n const metadata = tryCreateElementMetadata({\n element,\n semanticNameMap,\n debug: false,\n debugPrefix: \"[compiler-wrapper]\",\n preferJsonParseFailureAsContentArray: true,\n testIdAttribute,\n });\n\n if (metadata) {\n componentMetadata.set(metadata.testId, metadata);\n }\n }\n\n // Traverse children\n if (element.children) {\n for (const child of element.children) {\n traverseNode(child);\n }\n }\n }\n else if (node.type === NodeTypes.IF) {\n // Traverse v-if branches\n for (const branch of node.branches) {\n traverseNode(branch);\n }\n }\n else if (node.type === NodeTypes.IF_BRANCH || node.type === NodeTypes.FOR) {\n // Traverse conditional/loop children\n if (node.children) {\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n else if (node.type === NodeTypes.ROOT) {\n // Traverse root children\n for (const child of node.children) {\n traverseNode(child);\n }\n }\n }\n\n traverseNode(ast);\n\n if (componentMetadata.size > 0) {\n metadataMap.set(componentName, componentMetadata);\n }\n}\n\n/**\n * Custom compile function that wraps Vue's baseCompile\n * Extracts metadata after transform but before generate\n */\nexport function compileWithMetadataExtraction(\n source: string,\n options: CompilerOptions,\n _componentName: string,\n _metadataMap: Map<string, Map<string, ElementMetadata>>,\n _debug: boolean,\n): ReturnType<typeof compile> {\n // Call Vue's baseCompile which internally does: parse -> transform -> generate\n const result = compile(source, options);\n\n // The result contains the generated code, but we need the AST\n // Unfortunately, baseCompile doesn't expose the AST after transform\n // We need to recreate the transform pipeline manually\n\n return result;\n}\n\n/**\n * Custom compile function that manually runs parse -> transform -> extract -> generate\n */\nexport function compileWithMetadataExtractionManual(\n source: string,\n options: CompilerOptions,\n componentName: string,\n metadataMap: Map<string, Map<string, ElementMetadata>>,\n semanticNameMap: Map<string, string>,\n testIdAttribute: string = \"data-testid\",\n): ReturnType<typeof compile> {\n const normalizedTestIdAttribute = (testIdAttribute ?? \"data-testid\").trim() || \"data-testid\";\n // IMPORTANT:\n // Use `@vue/compiler-dom`'s `compile()` (not `baseCompile`) so DOM-specific\n // transforms (especially directive transforms like `v-show`) are preserved.\n //\n // We append a final root-level nodeTransform that registers an exit hook to\n // run *after* the rest of the transform pipeline, allowing us to extract\n // metadata from the fully transformed AST.\n const result = compile(\n source,\n extend({}, options, {\n nodeTransforms: [\n ...(options.nodeTransforms || []),\n (node: RootNode | TemplateChildNode, _context: TransformContext) => {\n if (node.type !== NodeTypes.ROOT)\n return;\n\n return () => {\n extractMetadataFromAST(node as RootNode, componentName, metadataMap, semanticNameMap, normalizedTestIdAttribute);\n };\n },\n ],\n }),\n );\n\n return result;\n}\n","import path from \"node:path\";\n\nimport type { Options as VuePluginOptions } from \"@vitejs/plugin-vue\";\nimport vue from \"@vitejs/plugin-vue\";\nimport type { PluginOption } from \"vite\";\nimport * as compilerDom from \"@vue/compiler-dom\";\nimport type { CompilerOptions, RootNode, TemplateChildNode, TransformContext } from \"@vue/compiler-core\";\nimport { NodeTypes } from \"@vue/compiler-core\";\n\nimport { compileWithMetadataExtractionManual } from \"../compiler-wrapper\";\nimport type { ElementMetadata } from \"../metadata-collector\";\nimport { createTestIdTransform } from \"../transform\";\nimport type { IComponentDependencies, NativeWrappersMap } from \"../utils\";\n\nimport type { VuePomGeneratorLogger } from \"./logger\";\nimport type { PomNameCollisionBehavior } from \"./types\";\n\ninterface InternalFactoryOptions {\n vueOptions?: VuePluginOptions;\n existingIdBehavior: \"preserve\" | \"overwrite\" | \"error\";\n nameCollisionBehavior: PomNameCollisionBehavior;\n nativeWrappers: NativeWrappersMap;\n elementMetadata: Map<string, Map<string, ElementMetadata>>;\n semanticNameMap: Map<string, string>;\n componentHierarchyMap: Map<string, IComponentDependencies>;\n vueFilesPathMap: Map<string, string>;\n excludedComponents: string[];\n getViewsDirAbs: () => string;\n testIdAttribute: string;\n loggerRef: { current: VuePomGeneratorLogger };\n}\n\nexport function createVuePluginWithTestIds(options: InternalFactoryOptions): PluginOption {\n const {\n vueOptions,\n existingIdBehavior,\n nameCollisionBehavior,\n nativeWrappers,\n elementMetadata,\n semanticNameMap,\n componentHierarchyMap,\n vueFilesPathMap,\n excludedComponents,\n getViewsDirAbs,\n testIdAttribute,\n loggerRef,\n } = options;\n\n const userTemplate = vueOptions?.template ?? {};\n const userCompilerOptions = userTemplate.compilerOptions ?? {};\n const userNodeTransforms = userCompilerOptions.nodeTransforms ?? [];\n\n // Vue compiler runs nodeTransforms for every node in a template.\n // We need a per-file transform instance so state accumulates across nodes.\n const perFileTransform = new Map<string, ReturnType<typeof createTestIdTransform>>();\n\n const templateCompilerOptions = {\n ...userCompilerOptions,\n // Ensures compiler-core runs `transformExpression` (in non-browser builds),\n // which parses directive expressions via @babel/parser and attaches `exp.ast`.\n // This improves reliability for AST-based consumers (like our data-testid generator).\n prefixIdentifiers: true,\n nodeTransforms: [\n ...userNodeTransforms,\n (node: RootNode | TemplateChildNode, context: TransformContext) => {\n if (!context.filename)\n return;\n const componentName = path.basename(context.filename, \".vue\");\n\n // Root is visited first; treat it as the start of a new compilation run for this SFC.\n if (node.type === NodeTypes.ROOT) {\n // HMR/dev rebuilds can re-run template transforms for the same SFC multiple times.\n // Reset the component entry once per run to avoid stale/duplicate methods.\n componentHierarchyMap.delete(componentName);\n vueFilesPathMap.set(componentName, context.filename);\n\n perFileTransform.set(\n componentName,\n createTestIdTransform(\n componentName,\n componentHierarchyMap,\n nativeWrappers,\n excludedComponents,\n getViewsDirAbs(),\n {\n existingIdBehavior,\n testIdAttribute,\n nameCollisionBehavior,\n warn: (message) => loggerRef.current.warn(message),\n },\n ),\n );\n }\n\n let transform = perFileTransform.get(componentName);\n if (!transform) {\n // Safety net: create a transform if root wasn't observed for some reason.\n componentHierarchyMap.delete(componentName);\n vueFilesPathMap.set(componentName, context.filename);\n transform = createTestIdTransform(\n componentName,\n componentHierarchyMap,\n nativeWrappers,\n excludedComponents,\n getViewsDirAbs(),\n {\n existingIdBehavior,\n testIdAttribute,\n nameCollisionBehavior,\n warn: (message) => loggerRef.current.warn(message),\n },\n );\n perFileTransform.set(componentName, transform);\n }\n\n return transform(node, context);\n },\n ],\n };\n\n const template = {\n ...userTemplate,\n compiler: {\n // Preserve the full compiler-dom module behavior (directiveTransforms, nodeTransforms, etc.).\n // We only override `compile` to run our metadata extraction after transforms.\n ...compilerDom,\n compile(source: string, compilerOptions: CompilerOptions) {\n const componentName = compilerOptions.filename\n ? path.basename(compilerOptions.filename, \".vue\")\n : \"Unknown\";\n return compileWithMetadataExtractionManual(\n source,\n compilerOptions,\n componentName,\n elementMetadata,\n semanticNameMap,\n testIdAttribute,\n );\n },\n },\n compilerOptions: templateCompilerOptions,\n };\n\n return vue({\n ...vueOptions,\n template,\n } as VuePluginOptions);\n}\n","import type { Logger as ViteLogger } from \"vite\";\n\nexport type VuePomGeneratorVerbosity = \"silent\" | \"info\" | \"debug\";\n\nexport interface VuePomGeneratorLogger {\n info: (message: string) => void;\n debug: (message: string) => void;\n warn: (message: string) => void;\n}\n\nexport const VUE_POM_GENERATOR_LOG_PREFIX = \"[vue-pom-generator]\" as const;\n\nfunction normalize(message: string): string {\n const trimmed = (message ?? \"\").trim();\n if (!trimmed)\n return VUE_POM_GENERATOR_LOG_PREFIX;\n if (trimmed.startsWith(VUE_POM_GENERATOR_LOG_PREFIX))\n return trimmed;\n return `${VUE_POM_GENERATOR_LOG_PREFIX} ${trimmed}`;\n}\n\nexport function createLogger(options: {\n verbosity: VuePomGeneratorVerbosity;\n viteLogger?: ViteLogger;\n}): VuePomGeneratorLogger {\n const { verbosity, viteLogger } = options;\n\n const sinkInfo = (msg: string) => {\n if (viteLogger) {\n viteLogger.info(normalize(msg));\n return;\n }\n console.log(normalize(msg));\n };\n\n const sinkWarn = (msg: string) => {\n if (viteLogger) {\n viteLogger.warn(normalize(msg));\n return;\n }\n console.warn(normalize(msg));\n };\n\n const sinkDebug = (msg: string) => {\n // No dedicated debug channel in Vite logger; info is fine when verbosity=debug.\n if (viteLogger) {\n viteLogger.info(normalize(msg));\n return;\n }\n console.log(normalize(msg));\n };\n\n return {\n info(message: string) {\n if (verbosity === \"silent\")\n return;\n sinkInfo(message);\n },\n debug(message: string) {\n if (verbosity !== \"debug\")\n return;\n sinkDebug(message);\n },\n warn(message: string) {\n if (verbosity === \"silent\")\n return;\n sinkWarn(message);\n },\n };\n}\n","import path from \"node:path\";\nimport process from \"node:process\";\n\nimport type { PluginOption, ResolvedConfig } from \"vite\";\n\nimport { createSupportPlugins } from \"./support-plugins\";\nimport { createTestIdsVirtualModulesPlugin } from \"./support/virtual-modules\";\nimport type { ExistingIdBehavior, PomNameCollisionBehavior, VuePomGeneratorPluginOptions } from \"./types\";\nimport { createVuePluginWithTestIds } from \"./vue-plugin\";\nimport { createLogger } from \"./logger\";\nimport type { VuePomGeneratorLogger, VuePomGeneratorVerbosity } from \"./logger\";\n\nimport type { ElementMetadata } from \"../metadata-collector\";\nimport type { IComponentDependencies, NativeWrappersMap } from \"../utils\";\n\nfunction assertNonEmptyString(value: string | undefined | null, name: string): asserts value is string {\n if (!value || !value.trim()) {\n throw new Error(`${name} must be a non-empty string.`);\n }\n}\n\nfunction resolveFromProjectRoot(projectRoot: string, maybePath: string): string {\n return path.isAbsolute(maybePath) ? maybePath : path.resolve(projectRoot, maybePath);\n}\n\nexport function createVuePomGeneratorPlugins(options: VuePomGeneratorPluginOptions = {}): PluginOption[] {\n const injection = options.injection ?? {};\n type GenerationConfig = NonNullable<Exclude<VuePomGeneratorPluginOptions[\"generation\"], false>>;\n\n const generationSetting = options.generation;\n const generationOptions: GenerationConfig | null = generationSetting === false ? null : (generationSetting ?? {});\n const generationEnabled = generationOptions !== null;\n\n const verbosity: VuePomGeneratorVerbosity = options.logging?.verbosity ?? \"info\";\n\n const vueOptions = options.vueOptions;\n\n const viewsDir = injection.viewsDir ?? \"src/views\";\n const nativeWrappers = (injection.nativeWrappers ?? {}) as NativeWrappersMap;\n const excludedComponents = injection.excludeComponents ?? [];\n const testIdAttribute = (injection.attribute ?? \"data-testid\").trim() || \"data-testid\";\n const existingIdBehavior: ExistingIdBehavior = injection.existingIdBehavior ?? \"preserve\";\n\n const outDir = (generationOptions?.outDir ?? \"tests/playwright/generated\").trim();\n const emitLanguages: Array<\"ts\" | \"csharp\"> = (generationOptions?.emit && generationOptions.emit.length)\n ? generationOptions.emit\n : [\"ts\"];\n const nameCollisionBehavior: PomNameCollisionBehavior = generationOptions?.nameCollisionBehavior ?? \"suffix\";\n const routerEntry = generationOptions?.router?.entry;\n const generateFixtures = generationOptions?.playwright?.fixtures;\n const customPoms = generationOptions?.playwright?.customPoms;\n\n const resolvedCustomPomAttachments = customPoms?.attachments ?? [];\n const resolvedCustomPomDir = customPoms?.dir ?? \"tests/playwright/pom/custom\";\n const resolvedCustomPomImportAliases = customPoms?.importAliases;\n\n const basePageClassPathOverride = generationOptions?.basePageClassPath;\n\n // Shared state: initialized with process.cwd(), then updated in configResolved.\n const projectRootRef = { current: process.cwd() };\n const loggerRef: { current: VuePomGeneratorLogger } = {\n current: createLogger({ verbosity }),\n };\n\n const configPlugin: PluginOption = {\n name: \"vue-pom-generator-config\",\n enforce: \"pre\",\n configResolved(config: ResolvedConfig) {\n projectRootRef.current = config.root;\n loggerRef.current = createLogger({ verbosity, viteLogger: config.logger });\n\n // Fail-fast validation.\n assertNonEmptyString(testIdAttribute, \"[vue-pom-generator] injection.attribute\");\n assertNonEmptyString(viewsDir, \"[vue-pom-generator] injection.viewsDir\");\n\n if (generationEnabled) {\n assertNonEmptyString(outDir, \"[vue-pom-generator] generation.outDir\");\n\n if (generationOptions?.router) {\n assertNonEmptyString(routerEntry, \"[vue-pom-generator] generation.router.entry\");\n }\n }\n\n // Small but helpful diagnostics.\n loggerRef.current.debug(`projectRoot=${projectRootRef.current}`);\n },\n };\n\n const getViewsDirAbs = () => resolveFromProjectRoot(projectRootRef.current, viewsDir);\n\n const componentTestIds = new Map<string, Set<string>>();\n const elementMetadata = new Map<string, Map<string, ElementMetadata>>();\n const semanticNameMap = new Map<string, string>();\n const componentHierarchyMap = new Map<string, IComponentDependencies>();\n const vueFilesPathMap = new Map<string, string>();\n\n const vuePlugin = createVuePluginWithTestIds({\n vueOptions,\n existingIdBehavior,\n nameCollisionBehavior,\n nativeWrappers,\n elementMetadata,\n semanticNameMap,\n componentHierarchyMap,\n vueFilesPathMap,\n excludedComponents,\n getViewsDirAbs,\n testIdAttribute,\n loggerRef,\n });\n\n if (!generationEnabled) {\n const virtualModules = createTestIdsVirtualModulesPlugin(componentTestIds);\n return [configPlugin, vuePlugin, virtualModules];\n }\n\n const routerAwarePoms = typeof routerEntry === \"string\" && routerEntry.trim().length > 0;\n\n const supportPlugins = createSupportPlugins({\n componentTestIds,\n componentHierarchyMap,\n vueFilesPathMap,\n nativeWrappers,\n excludedComponents,\n viewsDir,\n outDir,\n emitLanguages,\n routerAwarePoms,\n routerEntry,\n generateFixtures,\n projectRootRef,\n basePageClassPath: basePageClassPathOverride,\n customPomAttachments: resolvedCustomPomAttachments,\n customPomDir: resolvedCustomPomDir,\n customPomImportAliases: resolvedCustomPomImportAliases,\n testIdAttribute,\n loggerRef,\n });\n\n return [configPlugin, vuePlugin, ...supportPlugins];\n}\n\nexport default createVuePomGeneratorPlugins;\n"],"names":["upperFirst","path","toDirectiveObjectFieldNameValue","hierarchyMap","node","parts","raw","removeByKeySegment","isNavigation","needsKey","generatedName","added","header","base","propBase","propName","exp","source","parseSfc","parseTemplate","testIdExpression","normalizedFilePath","parentComponentName","dependencies","semanticNameHint","resolveRouterEntry"],"mappings":"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"}