feat(puppeteer-core): Infer element type from complex selector (#9253)
**What kind of change does this PR introduce?** Better type inference. **Did you add tests for your changes?** ~Not yet.~ Yes. **If relevant, did you update the documentation?** Not yet. **Summary** <!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? --> <!-- Try to link to an open issue for more information. --> Currently methods that return an element handle, i.e. `.$`, `.waitForSelector` attempt to infer the node element type from the selector string. However, this only works when the selector is an exact match of the element tag, i.e. a selector `"a"` would be inferred as `HTMLAnchorElement` . And not when the selector is complex, i.e. selectors `"a#some-id"`, `div > a`, `a:nth-child(2)` would all fallback on `Element`. This is due to simply looking up the the selector in `HTMLElementTagNameMap` and `SVGElementTagNameMap` without any attempt to parse the selector string. This PR is an attempt to do so. **Does this PR introduce a breaking change?** <!-- If this PR introduces a breaking change, please describe the impact and a migration path for existing applications. --> This could break existing incorrect assertions using the `as` keyword. **Other information** ~This PR introduces a dependency on the `type-fest` package.~ This PR is far from complete (no tests, no docs). Put out early for feedback and discussion. Co-authored-by: Alex Rudenko <OrKoN@users.noreply.github.com>
This commit is contained in:
parent
16784fc8cb
commit
bef1061c06
@ -7,10 +7,12 @@ sidebar_label: NodeFor
|
||||
#### Signature:
|
||||
|
||||
```typescript
|
||||
export declare type NodeFor<Selector extends string> =
|
||||
Selector extends keyof HTMLElementTagNameMap
|
||||
? HTMLElementTagNameMap[Selector]
|
||||
: Selector extends keyof SVGElementTagNameMap
|
||||
? SVGElementTagNameMap[Selector]
|
||||
: Element;
|
||||
export declare type NodeFor<ComplexSelector extends string> =
|
||||
TypeSelectorOfComplexSelector<ComplexSelector> extends infer TypeSelector
|
||||
? TypeSelector extends keyof HTMLElementTagNameMap
|
||||
? HTMLElementTagNameMap[TypeSelector]
|
||||
: TypeSelector extends keyof SVGElementTagNameMap
|
||||
? SVGElementTagNameMap[TypeSelector]
|
||||
: Element
|
||||
: never;
|
||||
```
|
||||
|
@ -67,9 +67,100 @@ export type EvaluateFunc<T extends unknown[]> = (
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export type NodeFor<Selector extends string> =
|
||||
Selector extends keyof HTMLElementTagNameMap
|
||||
? HTMLElementTagNameMap[Selector]
|
||||
: Selector extends keyof SVGElementTagNameMap
|
||||
? SVGElementTagNameMap[Selector]
|
||||
: Element;
|
||||
export type NodeFor<ComplexSelector extends string> =
|
||||
TypeSelectorOfComplexSelector<ComplexSelector> extends infer TypeSelector
|
||||
? TypeSelector extends keyof HTMLElementTagNameMap
|
||||
? HTMLElementTagNameMap[TypeSelector]
|
||||
: TypeSelector extends keyof SVGElementTagNameMap
|
||||
? SVGElementTagNameMap[TypeSelector]
|
||||
: Element
|
||||
: never;
|
||||
|
||||
type TypeSelectorOfComplexSelector<ComplexSelector extends string> =
|
||||
CompoundSelectorsOfComplexSelector<ComplexSelector> extends infer CompoundSelectors
|
||||
? CompoundSelectors extends NonEmptyReadonlyArray<string>
|
||||
? Last<CompoundSelectors> extends infer LastCompoundSelector
|
||||
? LastCompoundSelector extends string
|
||||
? TypeSelectorOfCompoundSelector<LastCompoundSelector>
|
||||
: never
|
||||
: never
|
||||
: unknown
|
||||
: never;
|
||||
|
||||
type TypeSelectorOfCompoundSelector<CompoundSelector extends string> =
|
||||
SplitWithDelemiters<
|
||||
CompoundSelector,
|
||||
BeginSubclassSelectorTokens
|
||||
> extends infer CompoundSelectorTokens
|
||||
? CompoundSelectorTokens extends [infer TypeSelector, ...any[]]
|
||||
? TypeSelector extends ''
|
||||
? unknown
|
||||
: TypeSelector
|
||||
: never
|
||||
: never;
|
||||
|
||||
type Last<Arr extends NonEmptyReadonlyArray<unknown>> = Arr extends [
|
||||
infer Head,
|
||||
...infer Tail
|
||||
]
|
||||
? Tail extends NonEmptyReadonlyArray<unknown>
|
||||
? Last<Tail>
|
||||
: Head
|
||||
: never;
|
||||
|
||||
type NonEmptyReadonlyArray<T> = [T, ...(readonly T[])];
|
||||
|
||||
type CompoundSelectorsOfComplexSelector<ComplexSelector extends string> =
|
||||
SplitWithDelemiters<
|
||||
ComplexSelector,
|
||||
CombinatorTokens
|
||||
> extends infer IntermediateTokens
|
||||
? IntermediateTokens extends readonly string[]
|
||||
? Drop<IntermediateTokens, ''>
|
||||
: never
|
||||
: never;
|
||||
|
||||
type SplitWithDelemiters<
|
||||
Input extends string,
|
||||
Delemiters extends readonly string[]
|
||||
> = Delemiters extends [infer FirstDelemiter, ...infer RestDelemiters]
|
||||
? FirstDelemiter extends string
|
||||
? RestDelemiters extends readonly string[]
|
||||
? FlatmapSplitWithDelemiters<Split<Input, FirstDelemiter>, RestDelemiters>
|
||||
: never
|
||||
: never
|
||||
: [Input];
|
||||
|
||||
type BeginSubclassSelectorTokens = ['.', '#', '[', ':'];
|
||||
|
||||
type CombinatorTokens = [' ', '>', '+', '~', '|', '|'];
|
||||
|
||||
type Drop<Arr extends readonly unknown[], Remove> = Arr extends [
|
||||
infer Head,
|
||||
...infer Tail
|
||||
]
|
||||
? Head extends Remove
|
||||
? Drop<Tail, Remove>
|
||||
: [Head, ...Drop<Tail, Remove>]
|
||||
: [];
|
||||
|
||||
type FlatmapSplitWithDelemiters<
|
||||
Inputs extends readonly string[],
|
||||
Delemiters extends readonly string[]
|
||||
> = Inputs extends [infer FirstInput, ...infer RestInputs]
|
||||
? FirstInput extends string
|
||||
? RestInputs extends readonly string[]
|
||||
? [
|
||||
...SplitWithDelemiters<FirstInput, Delemiters>,
|
||||
...FlatmapSplitWithDelemiters<RestInputs, Delemiters>
|
||||
]
|
||||
: never
|
||||
: never
|
||||
: [];
|
||||
|
||||
type Split<
|
||||
Input extends string,
|
||||
Delemiter extends string
|
||||
> = Input extends `${infer Prefix}${Delemiter}${infer Suffix}`
|
||||
? [Prefix, ...Split<Suffix, Delemiter>]
|
||||
: [Input];
|
||||
|
@ -4,31 +4,897 @@ import {expectNotType, expectType} from 'tsd';
|
||||
declare const handle: ElementHandle;
|
||||
|
||||
{
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(await handle.$('a'));
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('a'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('a#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('a#id'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('a.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('a.class'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('a[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('a:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('a:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(await handle.$('div'));
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div#id'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div.class'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('some-custom'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$(''));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('#id'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('.class'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('[attr=value]'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$(':pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$(':func(arg)'));
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div > a'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div > div'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('div > #id'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('div > .class'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > [attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > :pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > :func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div > a'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLAnchorElement> | null>(
|
||||
await handle.$('div > a:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(await handle.$('div > div'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div#id')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div.class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div[attr=value]')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div:psuedo-class')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<HTMLDivElement> | null>(
|
||||
await handle.$('div > div:func(arg)')
|
||||
);
|
||||
expectNotType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('div > #id'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(await handle.$('div > .class'));
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > [attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > :pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<ElementHandle<Element> | null>(
|
||||
await handle.$('div > :func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(await handle.$$('a'));
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('a'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('a#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('a#id'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('a.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('a.class'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('a[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('a:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('a:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(await handle.$$('div'));
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('div'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('div#id'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$('some-custom'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$(''));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$('#id'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$('.class'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$(':pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$(':func(arg)'));
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('div > a'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$('div > #id'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > .class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > [attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > :pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > :func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(await handle.$$('div > a'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLAnchorElement>>>(
|
||||
await handle.$$('div > a:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > a:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div#id')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div.class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div[attr=value]')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div:psuedo-class')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<HTMLDivElement>>>(
|
||||
await handle.$$('div > div:func(arg)')
|
||||
);
|
||||
expectNotType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > div:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom#id')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom.class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom[attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom:pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > some-custom:func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(await handle.$$('div > #id'));
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > .class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > [attr=value]')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > :pseudo-class')
|
||||
);
|
||||
}
|
||||
{
|
||||
expectType<Array<ElementHandle<Element>>>(
|
||||
await handle.$$('div > :func(arg)')
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
144
test-d/NodeFor.test-d.ts
Normal file
144
test-d/NodeFor.test-d.ts
Normal file
@ -0,0 +1,144 @@
|
||||
import type {NodeFor} from 'puppeteer';
|
||||
import {expectType, expectNotType} from 'tsd';
|
||||
|
||||
declare const nodeFor: <Selector extends string>(
|
||||
selector: Selector
|
||||
) => NodeFor<Selector>;
|
||||
|
||||
{
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('a'));
|
||||
expectNotType<Element>(nodeFor('a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('a#ignored'));
|
||||
expectNotType<Element>(nodeFor('a#ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('a.ignored'));
|
||||
expectNotType<Element>(nodeFor('a.ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('a[ignored'));
|
||||
expectNotType<Element>(nodeFor('a[ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('a:ignored'));
|
||||
expectNotType<Element>(nodeFor('a:ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored a'));
|
||||
expectNotType<Element>(nodeFor('ignored a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored a#ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored a#ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored a.ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored a.ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored a[ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored a[ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored a:ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored a:ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored > a'));
|
||||
expectNotType<Element>(nodeFor('ignored > a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored > a#ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored > a#ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored > a.ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored > a.ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored > a[ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored > a[ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored > a:ignored'));
|
||||
expectNotType<Element>(nodeFor('ignored > a:ignored'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored + a'));
|
||||
expectNotType<Element>(nodeFor('ignored + a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored ~ a'));
|
||||
expectNotType<Element>(nodeFor('ignored ~ a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(nodeFor('ignored | a'));
|
||||
expectNotType<Element>(nodeFor('ignored | a'));
|
||||
}
|
||||
{
|
||||
expectType<HTMLAnchorElement>(
|
||||
nodeFor('ignored ignored > ignored + ignored | a#ignore')
|
||||
);
|
||||
expectNotType<Element>(
|
||||
nodeFor('ignored ignored > ignored + ignored | a#ignore')
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
{
|
||||
expectType<Element>(nodeFor(''));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('#ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('.ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('[ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor(':ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored #ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored .ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored [ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored :ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored > #ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored > .ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored > [ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored > :ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored + #ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored ~ #ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(nodeFor('ignored | #ignored'));
|
||||
}
|
||||
{
|
||||
expectType<Element>(
|
||||
nodeFor('ignored ignored > ignored ~ ignored + ignored | #ignored')
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user