fix(types): fix waitForSelector typing to not union null when appropriate (#6344)

Previously when options were defined, but no `state` key was provided,
the types would return null as an option. Even though the default state
is `visible` and shouldn't allow `null`.

Tests updated to fail appropriately and new tests added for this case.
This commit is contained in:
Jason Harwig 2021-05-05 15:03:27 -05:00 committed by GitHub
parent 8d66edf6b3
commit 42a5566653
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 12 deletions

4
types/types.d.ts vendored
View file

@ -21,10 +21,10 @@ import { Readable } from 'stream';
import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs'; import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs';
type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & { type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & {
state: 'visible'|'attached'; state?: 'visible'|'attached';
}; };
type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelectorOptions & { type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelectorOptions & {
state: 'visible'|'attached'; state?: 'visible'|'attached';
}; };
/** /**

View file

@ -20,10 +20,10 @@ import { Readable } from 'stream';
import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs'; import { Serializable, EvaluationArgument, PageFunction, PageFunctionOn, SmartHandle, ElementHandleForTag, BindingSource } from './structs';
type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & { type PageWaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & {
state: 'visible'|'attached'; state?: 'visible'|'attached';
}; };
type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelectorOptions & { type ElementHandleWaitForSelectorOptionsNotHidden = ElementHandleWaitForSelectorOptions & {
state: 'visible'|'attached'; state?: 'visible'|'attached';
}; };
export interface Page { export interface Page {

View file

@ -675,47 +675,58 @@ playwright.chromium.launch().then(async browser => {
} }
} }
type AssertCanBeNull<T> = null extends T ? true : false
const frameLikes = [page, frame]; const frameLikes = [page, frame];
for (const frameLike of frameLikes) { for (const frameLike of frameLikes) {
{ {
const handle = await frameLike.waitForSelector('body'); const handle = await frameLike.waitForSelector('body');
const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true; const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = false; const canBeNull: AssertCanBeNull<typeof handle> = false
}
{
const handle = await frameLike.waitForSelector('body', {timeout: 0});
const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true;
const canBeNull: AssertCanBeNull<typeof handle> = false;
} }
{ {
const state = Math.random() > .5 ? 'attached' : 'visible'; const state = Math.random() > .5 ? 'attached' : 'visible';
const handle = await frameLike.waitForSelector('body', {state}); const handle = await frameLike.waitForSelector('body', {state});
const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true; const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = false; const canBeNull: AssertCanBeNull<typeof handle> = false;
} }
{ {
const handle = await frameLike.waitForSelector('body', {state: 'hidden'}); const handle = await frameLike.waitForSelector('body', {state: 'hidden'});
const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true; const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = true; const canBeNull: AssertCanBeNull<typeof handle> = true;
} }
{ {
const state = Math.random() > .5 ? 'hidden' : 'visible'; const state = Math.random() > .5 ? 'hidden' : 'visible';
const handle = await frameLike.waitForSelector('body', {state}); const handle = await frameLike.waitForSelector('body', {state});
const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true; const bodyAssertion: AssertType<playwright.ElementHandle<HTMLBodyElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = true; const canBeNull: AssertCanBeNull<typeof handle> = true;
} }
{ {
const handle = await frameLike.waitForSelector('something-strange'); const handle = await frameLike.waitForSelector('something-strange');
const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true; const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = false; const canBeNull: AssertCanBeNull<typeof handle> = false;
}
{
const handle = await frameLike.waitForSelector('something-strange', {timeout: 0});
const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true;
const canBeNull: AssertCanBeNull<typeof handle> = false;
} }
{ {
const state = Math.random() > .5 ? 'attached' : 'visible'; const state = Math.random() > .5 ? 'attached' : 'visible';
const handle = await frameLike.waitForSelector('something-strange', {state}); const handle = await frameLike.waitForSelector('something-strange', {state});
const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true; const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = false; const canBeNull: AssertCanBeNull<typeof handle> = false;
} }
{ {
const state = Math.random() > .5 ? 'hidden' : 'visible'; const state = Math.random() > .5 ? 'hidden' : 'visible';
const handle = await frameLike.waitForSelector('something-strange', {state}); const handle = await frameLike.waitForSelector('something-strange', {state});
const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true; const elementAssertion: AssertType<playwright.ElementHandle<HTMLElement|SVGElement>, typeof handle> = true;
const canBeNull: AssertType<null, typeof handle> = true; const canBeNull: AssertCanBeNull<typeof handle> = true;
} }
} }