{"record":{"id":"312217c4ddc30fbc","repo":"grafana/k6","slug":"attr-name-must-be-one-of-values-map-v","errorCode":null,"errorMessage":"\"${attr.name}\" must be one of ${values.map((v) => JSON.stringify(v)).join(\", \")}","messagePattern":"\"(.+?)\" must be one of (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/js/injected_script.js","lineNumber":1154,"sourceCode":"    skipSpaces();\n  }\n  if (!EOL)\n    syntaxError(void 0);\n  if (!result.name && !result.attributes.length)\n    throw new InvalidSelectorError(`Error while parsing selector \\`${selector}\\` - selector cannot be empty`);\n  return result;\n}\n\n// packages/injected/src/roleSelectorEngine.ts\nvar kSupportedAttributes = [\"selected\", \"checked\", \"pressed\", \"expanded\", \"level\", \"disabled\", \"name\", \"include-hidden\"];\nkSupportedAttributes.sort();\nfunction validateSupportedRole(attr, roles, role) {\n  if (!roles.includes(role))\n    throw new Error(`\"${attr}\" attribute is only supported for roles: ${roles.slice().sort().map((role2) => `\"${role2}\"`).join(\", \")}`);\n}\nfunction validateSupportedValues(attr, values) {\n  if (attr.op !== \"<truthy>\" && !values.includes(attr.value))\n    throw new Error(`\"${attr.name}\" must be one of ${values.map((v) => JSON.stringify(v)).join(\", \")}`);\n}\nfunction validateSupportedOp(attr, ops) {\n  if (!ops.includes(attr.op))\n    throw new Error(`\"${attr.name}\" does not support \"${attr.op}\" matcher`);\n}\nfunction validateAttributes(attrs, role) {\n  const options = { role };\n  for (const attr of attrs) {\n    switch (attr.name) {\n      case \"checked\": {\n        validateSupportedRole(attr.name, kAriaCheckedRoles, role);\n        validateSupportedValues(attr, [true, false, \"mixed\"]);\n        validateSupportedOp(attr, [\"<truthy>\", \"=\"]);\n        options.checked = attr.op === \"<truthy>\" ? true : attr.value;\n        break;\n      }\n      case \"pressed\": {\n        validateSupportedRole(attr.name, kAriaPressedRoles, role);","sourceCodeStart":1136,"sourceCodeEnd":1172,"githubUrl":"https://github.com/grafana/k6/blob/01ffac6f245854c1b8adc6a69857c76a15f90022/internal/js/modules/k6/browser/common/js/injected_script.js#L1136-L1172","documentation":"Frame.Hover() (frame.go:1265) wraps the internal pointer action failure with 'hovering %q'. Hover is a pointer action: it waits for the element to be attached and visible, computes its point, performs hit-target checking, and moves the mouse. The wrapped error can be a selector timeout, strict-mode violation, 'element is not visible', hit-target mismatch (another element intercepts the point), or frame detachment during the action.","triggerScenarios":"Element not found before opts.Timeout; element exists but is hidden (display:none, zero size, outside scroll container); another overlay (cookie banner, tooltip, sticky header) intercepts the pointer at the element's point; navigation detaches the frame mid-hover.","commonSituations":"Hovering menu items of dropdowns that only render after a prior hover step; fixed-position overlays blocking the target on small viewports; animations leaving elements at 0x0; stale selectors after UI redesign.","solutions":["Ensure the element is visible and stable first: await page.locator(sel).waitFor({ state: 'visible' }).","Dismiss blocking overlays (cookie banners, modals) before hovering.","Set an explicit viewport large enough via browser launch options so the element is not clipped.","If the target is animated, wait for a sentinel element that appears when the animation ends.","Increase timeout per call: page.hover(sel, { timeout: 60000 })."],"exampleFix":"// before\nawait page.hover('.menu-item');\n\n// after\nconst item = page.locator('.menu-item');\nawait item.waitFor({ state: 'visible', timeout: 10000 });\nawait item.hover();","handlingStrategy":"try-catch","validationCode":"const item = page.locator('.menu-item');\nawait item.waitFor({ state: 'visible', timeout: 5000 }); // hover needs a visible element","typeGuard":null,"tryCatchPattern":"try {\n  await page.hover(sel, { timeout: 10000 });\n} catch (e) {\n  const msg = String(e);\n  if (msg.includes('not visible') || msg.includes('timed out')) {\n    throw new Error(`hover target missing/hidden: ${sel}`);\n  }\n  throw e;\n}","preventionTips":["Dismiss overlays (cookie banners, tooltips) before hover steps.","Ensure the viewport (browser launch options) shows the element.","Hover parent items first so child menus are rendered."],"tags":["k6","browser","frame","hover","pointer","timeout"],"backgroundTag":"element-not-found-timeout","analyzedSha":"01ffac6f245854c1b8adc6a69857c76a15f90022","analyzedAt":"2026-08-18T03:05:52.393Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}