grafana/k6 · error
clicking on %q: %w
Error message
clicking on %q: %w
What it means
Frame.Click() runs a pointer action that first waits for an element matching the selector to be attached, visible, stable and enabled (per injected_script.js checks) within opts.Timeout, then dispatches mouse events. This error wraps any failure of that pipeline — most commonly a wait timeout ('timed out after Nms' from the injected script) or a DOM error surfaced by errorFromDOMError.
Source
Thrown at internal/js/modules/k6/browser/common/frame.go:609
// ChildFrames returns a list of child frames.
func (f *Frame) ChildFrames() []*Frame {
f.childFramesMu.RLock()
defer f.childFramesMu.RUnlock()
l := make([]*Frame, 0, len(f.childFrames))
for child := range f.childFrames {
l = append(l, child)
}
return l
}
// Click clicks the first element found that matches selector.
func (f *Frame) Click(selector string, opts *FrameClickOptions) error {
f.log.Debugf("Frame:Click", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
if err := f.click(selector, opts); err != nil {
return fmt.Errorf("clicking on %q: %w", selector, err)
}
applySlowMo(f.ctx)
return nil
}
func (f *Frame) click(selector string, opts *FrameClickOptions) error {
click := func(apiCtx context.Context, handle *ElementHandle, p *Position) (any, error) {
return nil, handle.click(p, opts.ToMouseClickOptions())
}
act := f.newPointerAction(
selector, DOMElementStateAttached, opts.Strict, click, &opts.ElementHandleBasePointerOptions,
)
if _, err := call(f.ctx, act, opts.Timeout); err != nil {
return errorFromDOMError(err)
}
View on GitHub (pinned to 93accf6570)
Solutions
- Wait first: await page.waitForSelector(sel, { state: 'visible', timeout: 30000 }) then click, or pass a larger { timeout: ... } to click itself.
- Make the selector unique (data-testid) to avoid strict-mode ambiguity.
- Handle overlays: close/dismiss the overlay, or scroll the element into view before clicking.
- If the element is intentionally non-actionable in tests, assert with try-catch instead of letting the iteration abort.
Example fix
// before
page.click('#submit'); // fails: button under cookie banner
// after
await page.waitForSelector('#submit', { state: 'visible', timeout: 30000 });
page.click('#submit', { timeout: 30000 }); Defensive patterns
Strategy: validation
Validate before calling
await page.waitForSelector(sel, { state: 'visible', timeout: 30000 });
// optionally verify uniqueness for strict mode:
const n = page.evaluate('(s) => document.querySelectorAll(s).length', sel); Try / catch
try {
page.click(sel, { timeout: 30000 });
} catch (e) {
if (/timed out/.test(e.message)) { /* retry or mark element-not-ready */ }
throw e;
} Prevention
- Prefer data-testid selectors for uniqueness.
- Pass an explicit timeout larger than worst-case render time.
- Dismiss known overlays (cookie banners) as a setup step.
When it happens
Trigger: Selector matches nothing, matches multiple elements with strict:true, or the element stays hidden/covered by an overlay (cookie banner, spinner) so actionability checks time out; opts.Timeout set lower than render time; navigation destroys the execution context mid-action.
Common situations: SPA renders the target late (client-side hydration); a modal or toast overlays the button; default action timeout lowered via options (timeout in browser options); strict-mode selectors that match a list (e.g. '.btn' with several buttons); iframe content while the caller used the main frame.
Related errors
- clicking on element: %w
- checking %q: %w
- double clicking on %q: %w
- pressing %q on %q: %w
- typing %q in %q: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/fcdf4561542f638d.
Report an issue: GitHub.