{"record":{"id":"dd7112ef1e1035f0","repo":"grafana/k6","slug":"w-dd7112","errorCode":null,"errorMessage":"%w","messagePattern":"%w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/js/modules/k6/browser/common/keyboard.go","lineNumber":347,"sourceCode":"\t\t\t\treturn fmt.Errorf(\"pressing key: %w\", err)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif err := k.insertText(string(c)); err != nil {\n\t\t\treturn fmt.Errorf(\"inserting text: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc wait(ctx context.Context, delay int64) error {\n\tt := time.NewTimer(time.Duration(delay) * time.Millisecond)\n\tselect {\n\tcase <-ctx.Done():\n\t\tif !t.Stop() {\n\t\t\t<-t.C\n\t\t}\n\t\treturn fmt.Errorf(\"%w\", ContextErr(ctx))\n\tcase <-t.C:\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":329,"sourceCodeEnd":353,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/js/modules/k6/browser/common/keyboard.go#L329-L353","documentation":"Returned by the internal wait() helper used for keyboard Delay options: the context was canceled (or its deadline exceeded) while sleeping between keystrokes, so ContextErr(ctx) — context.Canceled / context.DeadlineExceeded, with any cancel cause appended — is passed through unchanged (fmt.Errorf(\"%w\", ...)). It aborts Type/Press waits before the next key is sent.","triggerScenarios":"type(text, {delay: 500}) where the cumulative delay exceeds the k6 iteration timeout or browser timeout; press(key, {delay: N}) where the page/browser context closes during the delay; scenario teardown canceling ctx mid-wait.","commonSituations":"Realistic-human typing delays (50–200ms per char) on long strings colliding with tight timeout options; end-of-iteration cancellation while a Type call is still sleeping; ctx canceled by page.close() with a pending delayed key.","solutions":["Budget delays: total ≈ len(text) * delay must stay well under the timeout option and iteration duration","Use insertText() for long strings when no per-key events are needed","Raise the timeout option (browser option) or shorten per-char delay","Treat context.Canceled at teardown as expected: end typing before closing pages"],"exampleFix":"// before\nawait page.type('#bio', longText, { delay: 200 }); // 200ms * 500 chars = 100s > timeout\n\n// after\nawait page.keyboard.insertText(longText);         // no delays\n// or: await page.type('#bio', longText, { delay: 5 });","handlingStrategy":"validation","validationCode":"const totalWaitMs = chars * delayMs; // cumulative wait() sleeps before each key\nif (totalWaitMs > actionTimeoutMs * 0.8 || totalWaitMs > remainingIterationMs) {\n  throw new Error('typing delay budget exceeds timeout — lower delay or use insertText()');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await page.keyboard.type(text, { delay });\n} catch (e) {\n  if (/context deadline exceeded|context canceled/.test(e.message)) {\n    console.warn('typing aborted by timeout/cancel during delay — finishing with insertText');\n    await page.keyboard.insertText(text); // best-effort completion without delays\n  } else throw e;\n}","preventionTips":["Treat delay as multiplicative: n chars * delay ms of pure waiting","Finish all typed input before page.close() or scenario end — cancelation during a delay surfaces raw context errors","Raise the browser timeout option when realistic typing delays are required"],"tags":["browser","keyboard","timeout","context-canceled","typing"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}