{"record":{"id":"ee7c47bddd7f4f66","repo":"grafana/k6","slug":"typing-q-in-q-w","errorCode":null,"errorMessage":"typing %q in %q: %w","messagePattern":"typing %q in %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/frame.go","lineNumber":1905,"sourceCode":"\tjs := `() => document.title`\n\tv, err := f.Evaluate(js)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"getting frame title: %w\", err)\n\t}\n\ts, ok := v.(string)\n\tif !ok {\n\t\treturn \"\", fmt.Errorf(\"getting frame title: expected string, got %T\", v)\n\t}\n\n\treturn s, nil\n}\n\n// Type text on the first element found matches the selector.\nfunc (f *Frame) Type(selector, text string, popts *FrameTypeOptions) error {\n\tf.log.Debugf(\"Frame:Type\", \"fid:%s furl:%q sel:%q text:%q\", f.ID(), f.URL(), selector, text)\n\n\tif err := f.typ(selector, text, popts); err != nil {\n\t\treturn fmt.Errorf(\"typing %q in %q: %w\", text, selector, err)\n\t}\n\n\tapplySlowMo(f.ctx)\n\n\treturn nil\n}\n\nfunc (f *Frame) typ(selector, text string, opts *FrameTypeOptions) error {\n\ttypeText := func(apiCtx context.Context, handle *ElementHandle) (any, error) {\n\t\treturn nil, handle.typ(apiCtx, text, opts.ToKeyboardOptions())\n\t}\n\tact := f.newAction(\n\t\tselector, DOMElementStateAttached, opts.Strict, typeText,\n\t\t[]string{}, false, withRetry, opts.NoWaitAfter, opts.Timeout,\n\t)\n\tif _, err := call(f.ctx, act, opts.Timeout); err != nil {\n\t\treturn errorFromDOMError(err)\n\t}","sourceCodeStart":1887,"sourceCodeEnd":1923,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/frame.go#L1887-L1923","documentation":"Frame.Type() wraps the internal type-text action as 'typing \"<text>\" in \"<selector>\": <cause>'. The cause is the real error: element wait timeout, actionability failure (hidden/disabled), mid-typing detach, or keyboard event dispatch failing because the frame died.","triggerScenarios":"frame.type(sel, text) where the element never appears within timeout; element not visible/enabled with force=false; element re-rendered mid-typing (React controlled input); strict-mode multi-match; page navigated while typing.","commonSituations":"Typing into inputs behind overlays; typing into inputs whose value is wiped by framework re-render; wrong selector; slow CI exceeding the default 30s timeout.","solutions":["Wait first: await frame.waitForSelector(sel, { state: 'visible' }) then type().","For controlled inputs that re-render, prefer fill() (single set) or type with small delay and verify the final value.","Use { timeout: 60_000 } on slow environments and a selector that matches exactly one element.","Use { force: true } only if the invisibility is a styling artifact you control."],"exampleFix":"// before\nawait frame.type('#email', 'a@b.c'); // input hidden by wizard step\n\n// after\nawait frame.waitForSelector('#email', { state: 'visible' });\nawait frame.type('#email', 'a@b.c', { timeout: 60_000 });","handlingStrategy":"validation","validationCode":"await frame.waitForSelector(sel, { state: 'visible', timeout: 60_000 });","typeGuard":null,"tryCatchPattern":"try { await frame.type(sel, text, { timeout: 60_000 }); }\ncatch (e) { if (/typing .* in/.test(e.message)) { /* inspect cause: timeout vs re-render vs strict */ } throw e; }","preventionTips":["Wait for visible inputs before typing","Prefer fill() for controlled inputs that re-render","Verify the final input value after typing into framework inputs"],"tags":["browser","keyboard","actionability","timeout","selector"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}