Brief summary
The Tester interface is the callback type for Selection.filter(), Selection.is() and Selection.not(). It declares the second parameter as an Element:
export interface Tester {
(index: number, element: Element): boolean;
}
At runtime, however, k6/html invokes these callbacks with a Selection, not an Element. Because Selection does not expose Element-only members such as querySelector, code that type-checks against these definitions throws at runtime:
TypeError: Object has no member 'querySelector'
k6 version
v2.0.0
OS
all
Docker version and image (if applicable)
No response
Steps to reproduce the problem
With test plan
import { parseHTML } from 'k6/html';
export default function () {
const doc = parseHTML('<div class="c"><a href="/x">John</a></div>');
doc.find('div.c').filter((_i, el) => el.querySelector('a[href]') != null);
}
you already see the issue. The code compiles cleanly (TS thinks el is an Element, which has querySelector) but throws at runtime because el is actually a Selection and you get
TypeError: Object has no member 'querySelector'
Why this is a type bug (not version-specific)
- The official
Selection.filter() documentation example uses el.text() — a Selection method — inside the callback:
https://grafana.com/docs/k6/latest/javascript-api/k6-html/selection/selection-filter/
- The definitions are internally inconsistent:
Mapper (the Selection.map() callback, which also receives a Selection) is already correctly typed with Selection, while Tester is not.
- Reproduces identically on k6 v1.3.0 and v2.0.0, so it is independent of the k6 binary version.
Expected behaviour
Type Tester callback's second parameter as a Selection:
export interface Tester {
(index: number, selection: Selection): boolean;
}
Actual behaviour
Type the Tester callback's second parameter is typed as an Element even though it is not
Brief summary
The
Testerinterface is the callback type forSelection.filter(),Selection.is()andSelection.not(). It declares the second parameter as anElement:At runtime, however, k6/html invokes these callbacks with a
Selection, not anElement. BecauseSelectiondoes not exposeElement-only members such asquerySelector, code that type-checks against these definitions throws at runtime:k6 version
v2.0.0
OS
all
Docker version and image (if applicable)
No response
Steps to reproduce the problem
With test plan
you already see the issue. The code compiles cleanly (TS thinks
elis an Element, which has querySelector) but throws at runtime becauseelis actually a Selection and you getTypeError: Object has no member 'querySelector'Why this is a type bug (not version-specific)
Selection.filter()documentation example usesel.text()— aSelectionmethod — inside the callback:https://grafana.com/docs/k6/latest/javascript-api/k6-html/selection/selection-filter/
Mapper(theSelection.map()callback, which also receives aSelection) is already correctly typed withSelection, whileTesteris not.Expected behaviour
Type
Testercallback's second parameter as aSelection:Actual behaviour
Type the
Testercallback's second parameter is typed as anElementeven though it is not