{"record":{"id":"302bc110acf8112c","repo":"grafana/k6","slug":"parsing-click-options-w","errorCode":null,"errorMessage":"parsing click options: %w","messagePattern":"parsing click options: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/browser/mapping.go","lineNumber":45,"sourceCode":"\tvar (\n\t\trt  = vu.Runtime()\n\t\tobj = rt.NewObject()\n\t)\n\tfor k, v := range m {\n\t\tif err := obj.Set(k, rt.ToValue(v)); err != nil {\n\t\t\tk6common.Throw(rt, k6ext.BrowserError(fmt.Errorf(\"mapping: %w\", err)))\n\t\t}\n\t}\n\n\treturn obj\n}\n\nfunc parseFrameClickOptions(\n\tctx context.Context, opts sobek.Value, defaultTimeout time.Duration,\n) (*common.FrameClickOptions, error) {\n\tcopts := common.NewFrameClickOptions(defaultTimeout)\n\tif err := copts.Parse(ctx, opts); err != nil {\n\t\treturn nil, fmt.Errorf(\"parsing click options: %w\", err)\n\t}\n\treturn copts, nil\n}\n\nfunc ConvertSelectOptionValues(rt *sobek.Runtime, values sobek.Value) ([]any, error) {\n\tif k6common.IsNullish(values) {\n\t\treturn nil, nil\n\t}\n\n\tvar (\n\t\topts []any\n\t\tt    = values.Export()\n\t)\n\tswitch values.ExportType().Kind() {\n\tcase reflect.Slice:\n\t\tvar sl []any\n\t\tif err := rt.ExportTo(values, &sl); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"options: expected array, got %T\", values)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/browser/mapping.go#L27-L63","documentation":"parseFrameClickOptions is the shared helper behind click-style mappings (locator.click, frame.click, page.click — and the same FrameClickOptions type serves dblclick/contextMenu paths), building FrameClickOptions from ElementHandleClickOptions, which embeds the strict pointer parser. The live error path is position: it must export to map[string]float64, so click({ position: ... }) with a string or non-numeric coordinates fails as 'parsing click options: <export error>'. Other keys (button, modifiers handled elsewhere, force, noWaitAfter, trial, timeout, strict) are coerced leniently.","triggerScenarios":"click({ position: 'center' }) — unsupported literal; click({ position: { x: '50', y: '50' } }) — string coordinates; click({ position: [50, 50] }) — array instead of {x, y}; click('50ms') — scalar in the opts slot.","commonSituations":"Clicking canvas or map elements with coordinates sourced from JSON that arrive as strings; porting Playwright examples that use explicit positions; passing a timeout string positionally like older k6 examples.","solutions":["Omit position to click the element center, or pass numeric coordinates: click({ position: { x: 50, y: 50 } })","Coerce string coordinates with Number() before the call","Pass timeout inside the options object as a number: { timeout: 5000 }","Keep only supported keys: position, button, modifiers, force, noWaitAfter, trial, strict, timeout"],"exampleFix":"// before\nawait page.locator('#map').click({ position: 'center', timeout: '5s' });\n\n// after\nawait page.locator('#map').click({ timeout: 5000 }); // center by default\n// or\nawait page.locator('#map').click({ position: { x: 50, y: 50 }, timeout: 5000 });","handlingStrategy":"validation","validationCode":"function assertClickOpts(opts) {\n  if (opts === null || opts === undefined) return;\n  if (typeof opts !== 'object' || Array.isArray(opts)) {\n    throw new TypeError('click options must be a plain object');\n  }\n  if ('position' in opts && opts.position !== undefined) {\n    const p = opts.position;\n    if (typeof p !== 'object' || p === null || Array.isArray(p) ||\n        typeof p.x !== 'number' || typeof p.y !== 'number') {\n      throw new TypeError(\"click position must be { x: number, y: number }; 'center' or string coords are not supported\");\n    }\n  }\n  if ('timeout' in opts && typeof opts.timeout !== 'number') {\n    throw new TypeError('click timeout must be a number (ms)');\n  }\n}","typeGuard":"function isPointerPosition(v) {\n  return typeof v === 'object' && v !== null && !Array.isArray(v) &&\n    typeof v.x === 'number' && Number.isFinite(v.x) &&\n    typeof v.y === 'number' && Number.isFinite(v.y);\n}","tryCatchPattern":"try {\n  await locator.click(opts); // same guard applies to frame.click / page.click\n} catch (e) {\n  if (/parsing click options/.test(String(e.message))) {\n    throw new Error(`Bad click options (check position/timeout types): ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["Click without position to hit the element center","Pass positions only as { x: number, y: number } with numeric values","Run coordinates from JSON through Number() before use"],"tags":["k6","browser","click","options","position"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}