feat(api): introduce setChecked convenience method (#8525)

This commit is contained in:
Pavel Feldman 2021-08-29 20:00:40 -07:00 committed by GitHub
parent dd31f3bd43
commit e574f4b7fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 406 additions and 0 deletions

View File

@ -20,6 +20,7 @@ Here is the complete list of actionability checks performed for each action:
| check | Yes | Yes | Yes | Yes | Yes | - |
| click | Yes | Yes | Yes | Yes | Yes | - |
| dblclick | Yes | Yes | Yes | Yes | Yes | - |
| setChecked | Yes | Yes | Yes | Yes | Yes | - |
| tap | Yes | Yes | Yes | Yes | Yes | - |
| uncheck | Yes | Yes | Yes | Yes | Yes | - |
| hover | Yes | Yes | Yes | Yes | - | - |

View File

@ -743,6 +743,29 @@ content.
### option: ElementHandle.selectText.force = %%-input-force-%%
### option: ElementHandle.selectText.timeout = %%-input-timeout-%%
## async method: ElementHandle.setChecked
This method checks or unchecks an element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method throws.
1. If the element already has the right checked state, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
1. Ensure that the element is now checked or unchecked. If not, this method throws.
When all steps combined have not finished during the specified [`option: timeout`], this method throws a
[TimeoutError]. Passing zero timeout disables this.
### param: ElementHandle.setChecked.checked = %%-input-checked-%%
### option: ElementHandle.setChecked.force = %%-input-force-%%
### option: ElementHandle.setChecked.noWaitAfter = %%-input-no-wait-after-%%
### option: ElementHandle.setChecked.position = %%-input-position-%%
### option: ElementHandle.setChecked.strict = %%-input-strict-%%
### option: ElementHandle.setChecked.timeout = %%-input-timeout-%%
### option: ElementHandle.setChecked.trial = %%-input-trial-%%
## async method: ElementHandle.setInputFiles
This method expects `elementHandle` to point to an

View File

@ -1097,6 +1097,34 @@ await frame.SelectOptionAsync("select#colors", new[] { "red", "green", "blue" })
### option: Frame.selectOption.strict = %%-input-strict-%%
### option: Frame.selectOption.timeout = %%-input-timeout-%%
## async method: Frame.setChecked
This method checks or unchecks an element matching [`param: selector`] by performing the following steps:
1. Find an element matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
1. If the element already has the right checked state, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
1. Ensure that the element is now checked or unchecked. If not, this method throws.
When all steps combined have not finished during the specified [`option: timeout`], this method throws a
[TimeoutError]. Passing zero timeout disables this.
### param: Frame.setChecked.selector = %%-input-selector-%%
### param: Frame.setChecked.checked = %%-input-checked-%%
### option: Frame.setChecked.force = %%-input-force-%%
### option: Frame.setChecked.noWaitAfter = %%-input-no-wait-after-%%
### option: Frame.setChecked.position = %%-input-position-%%
### option: Frame.setChecked.strict = %%-input-strict-%%
### option: Frame.setChecked.timeout = %%-input-timeout-%%
### option: Frame.setChecked.trial = %%-input-trial-%%
## async method: Frame.setContent
### param: Frame.setContent.html

View File

@ -799,6 +799,29 @@ content.
### option: Locator.selectText.force = %%-input-force-%%
### option: Locator.selectText.timeout = %%-input-timeout-%%
## async method: Locator.setChecked
This method checks or unchecks an element by performing the following steps:
1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
1. If the element already has the right checked state, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
1. Ensure that the element is now checked or unchecked. If not, this method throws.
When all steps combined have not finished during the specified [`option: timeout`], this method throws a
[TimeoutError]. Passing zero timeout disables this.
### param: Locator.setChecked.checked = %%-input-checked-%%
### option: Locator.setChecked.force = %%-input-force-%%
### option: Locator.setChecked.noWaitAfter = %%-input-no-wait-after-%%
### option: Locator.setChecked.position = %%-input-position-%%
### option: Locator.setChecked.strict = %%-input-strict-%%
### option: Locator.setChecked.timeout = %%-input-timeout-%%
### option: Locator.setChecked.trial = %%-input-trial-%%
## async method: Locator.setInputFiles
This method expects `element` to point to an

View File

@ -2676,6 +2676,34 @@ Shortcut for main frame's [`method: Frame.selectOption`].
### option: Page.selectOption.strict = %%-input-strict-%%
### option: Page.selectOption.timeout = %%-input-timeout-%%
## async method: Page.setChecked
This method checks or unchecks an element matching [`param: selector`] by performing the following steps:
1. Find an element matching [`param: selector`]. If there is none, wait until a matching element is attached to
the DOM.
1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
1. If the element already has the right checked state, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`] option is
set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [`property: Page.mouse`] to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`] option is set.
1. Ensure that the element is now checked or unchecked. If not, this method throws.
When all steps combined have not finished during the specified [`option: timeout`], this method throws a
[TimeoutError]. Passing zero timeout disables this.
Shortcut for main frame's [`method: Frame.setChecked`].
### param: Page.setChecked.selector = %%-input-selector-%%
### param: Page.setChecked.checked = %%-input-checked-%%
### option: Page.setChecked.force = %%-input-force-%%
### option: Page.setChecked.noWaitAfter = %%-input-no-wait-after-%%
### option: Page.setChecked.position = %%-input-position-%%
### option: Page.setChecked.strict = %%-input-strict-%%
### option: Page.setChecked.timeout = %%-input-timeout-%%
### option: Page.setChecked.trial = %%-input-trial-%%
## async method: Page.setContent
### param: Page.setContent.html

View File

@ -117,6 +117,11 @@ Clicks on the source element at this point relative to the top-left corner of th
Drops on the target element at this point relative to the top-left corner of the element's padding box. If not specified, some visible point of the element is used.
## input-checked
- `checked` <[boolean]>
Whether to check or uncheck the checkbox.
## query-selector
- `selector` <[string]>

View File

@ -217,6 +217,13 @@ export class ElementHandle<T extends Node = Node> extends JSHandle<T> implements
});
}
async setChecked(checked: boolean, options?: channels.ElementHandleCheckOptions) {
if (checked)
await this.check(options);
else
await this.uncheck(options);
}
async boundingBox(): Promise<Rect | null> {
return this._wrapApiCall(async (channel: channels.ElementHandleChannel) => {
const value = (await channel.boundingBox()).value;

View File

@ -437,6 +437,13 @@ export class Frame extends ChannelOwner<channels.FrameChannel, channels.FrameIni
});
}
async setChecked(selector: string, checked: boolean, options?: channels.FrameCheckOptions) {
if (checked)
await this.check(selector, options);
else
await this.uncheck(selector, options);
}
async waitForTimeout(timeout: number) {
return this._wrapApiCall(async (channel: channels.FrameChannel) => {
await new Promise(fulfill => setTimeout(fulfill, timeout));

View File

@ -177,6 +177,13 @@ export class Locator implements api.Locator {
return this._withElement((h, timeout) => h.selectText({ ...options, timeout }), options.timeout);
}
async setChecked(checked: boolean, options?: channels.ElementHandleCheckOptions) {
if (checked)
await this.check(options);
else
await this.uncheck(options);
}
async setInputFiles(files: string | FilePayload | string[] | FilePayload[], options: channels.ElementHandleSetInputFilesOptions = {}) {
return this._frame.setInputFiles(this._selector, files, { strict: true, ...options });
}

View File

@ -603,6 +603,10 @@ export class Page extends ChannelOwner<channels.PageChannel, channels.PageInitia
return this._mainFrame.uncheck(selector, options);
}
async setChecked(selector: string, checked: boolean, options?: channels.FrameCheckOptions) {
return this._mainFrame.setChecked(selector, checked, options);
}
async waitForTimeout(timeout: number) {
return this._mainFrame.waitForTimeout(timeout);
}

View File

@ -54,6 +54,15 @@ it('should check the box', async ({ page }) => {
expect(await page.evaluate('checkbox.checked')).toBe(true);
});
it('should check the box using setChecked', async ({ page }) => {
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
const input = await page.$('input');
await input.setChecked(true);
expect(await page.evaluate('checkbox.checked')).toBe(true);
await input.setChecked(false);
expect(await page.evaluate('checkbox.checked')).toBe(false);
});
it('should uncheck the box', async ({ page }) => {
await page.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
const input = await page.$('input');

View File

@ -55,6 +55,15 @@ it('should check the box', async ({ page }) => {
expect(await page.evaluate('checkbox.checked')).toBe(true);
});
it('should check the box using setChecked', async ({ page }) => {
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
const input = page.locator('input');
await input.setChecked(true);
expect(await page.evaluate('checkbox.checked')).toBe(true);
await input.setChecked(false);
expect(await page.evaluate('checkbox.checked')).toBe(false);
});
it('should uncheck the box', async ({ page }) => {
await page.setContent(`<input id='checkbox' type='checkbox' checked></input>`);
const input = page.locator('input');

View File

@ -131,3 +131,11 @@ it('trial run should not uncheck', async ({page}) => {
await page.uncheck('input', { trial: true });
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
});
it('should check the box using setChecked', async ({page}) => {
await page.setContent(`<input id='checkbox' type='checkbox'></input>`);
await page.setChecked('input', true);
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(true);
await page.setChecked('input', false);
expect(await page.evaluate(() => window['checkbox'].checked)).toBe(false);
});

247
types/types.d.ts vendored
View File

@ -2897,6 +2897,71 @@ export interface Page {
timeout?: number;
}): Promise<Array<string>>;
/**
* This method checks or unchecks an element matching `selector` by performing the following steps:
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
* 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
* 1. If the element already has the right checked state, this method returns immediately.
* 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If the
* element is detached during the checks, the whole action is retried.
* 1. Scroll the element into view if needed.
* 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the element.
* 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
* 1. Ensure that the element is now checked or unchecked. If not, this method throws.
*
* When all steps combined have not finished during the specified `timeout`, this method throws a [TimeoutError]. Passing
* zero timeout disables this.
*
* Shortcut for main frame's
* [frame.setChecked(selector, checked[, options])](https://playwright.dev/docs/api/class-frame#frame-set-checked).
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
* @param checked Whether to check or uncheck the checkbox.
* @param options
*/
setChecked(selector: string, checked: boolean, options?: {
/**
* Whether to bypass the [actionability](https://playwright.dev/docs/actionability) checks. Defaults to `false`.
*/
force?: boolean;
/**
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
* inaccessible pages. Defaults to `false`.
*/
noWaitAfter?: boolean;
/**
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
* element.
*/
position?: {
x: number;
y: number;
};
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
* element, the call throws an exception.
*/
strict?: boolean;
/**
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
* using the
* [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout)
* or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods.
*/
timeout?: number;
/**
* When set, this method only performs the [actionability](https://playwright.dev/docs/actionability) checks and skips the action. Defaults to
* `false`. Useful to wait until the element is ready for the action without performing it.
*/
trial?: boolean;
}): Promise<void>;
/**
* @param html HTML markup to assign to the page.
* @param options
@ -5254,6 +5319,68 @@ export interface Frame {
timeout?: number;
}): Promise<Array<string>>;
/**
* This method checks or unchecks an element matching `selector` by performing the following steps:
* 1. Find an element matching `selector`. If there is none, wait until a matching element is attached to the DOM.
* 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
* 1. If the element already has the right checked state, this method returns immediately.
* 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If the
* element is detached during the checks, the whole action is retried.
* 1. Scroll the element into view if needed.
* 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the element.
* 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
* 1. Ensure that the element is now checked or unchecked. If not, this method throws.
*
* When all steps combined have not finished during the specified `timeout`, this method throws a [TimeoutError]. Passing
* zero timeout disables this.
* @param selector A selector to search for an element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](https://playwright.dev/docs/selectors) for more details.
* @param checked Whether to check or uncheck the checkbox.
* @param options
*/
setChecked(selector: string, checked: boolean, options?: {
/**
* Whether to bypass the [actionability](https://playwright.dev/docs/actionability) checks. Defaults to `false`.
*/
force?: boolean;
/**
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
* inaccessible pages. Defaults to `false`.
*/
noWaitAfter?: boolean;
/**
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
* element.
*/
position?: {
x: number;
y: number;
};
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
* element, the call throws an exception.
*/
strict?: boolean;
/**
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
* using the
* [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout)
* or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods.
*/
timeout?: number;
/**
* When set, this method only performs the [actionability](https://playwright.dev/docs/actionability) checks and skips the action. Defaults to
* `false`. Useful to wait until the element is ready for the action without performing it.
*/
trial?: boolean;
}): Promise<void>;
/**
* @param html HTML markup to assign to the page.
* @param options
@ -7866,6 +7993,66 @@ export interface ElementHandle<T=Node> extends JSHandle<T> {
timeout?: number;
}): Promise<void>;
/**
* This method checks or unchecks an element by performing the following steps:
* 1. Ensure that element is a checkbox or a radio input. If not, this method throws.
* 1. If the element already has the right checked state, this method returns immediately.
* 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If the
* element is detached during the checks, the whole action is retried.
* 1. Scroll the element into view if needed.
* 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the element.
* 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
* 1. Ensure that the element is now checked or unchecked. If not, this method throws.
*
* When all steps combined have not finished during the specified `timeout`, this method throws a [TimeoutError]. Passing
* zero timeout disables this.
* @param checked Whether to check or uncheck the checkbox.
* @param options
*/
setChecked(checked: boolean, options?: {
/**
* Whether to bypass the [actionability](https://playwright.dev/docs/actionability) checks. Defaults to `false`.
*/
force?: boolean;
/**
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
* inaccessible pages. Defaults to `false`.
*/
noWaitAfter?: boolean;
/**
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
* element.
*/
position?: {
x: number;
y: number;
};
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
* element, the call throws an exception.
*/
strict?: boolean;
/**
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
* using the
* [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout)
* or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods.
*/
timeout?: number;
/**
* When set, this method only performs the [actionability](https://playwright.dev/docs/actionability) checks and skips the action. Defaults to
* `false`. Useful to wait until the element is ready for the action without performing it.
*/
trial?: boolean;
}): Promise<void>;
/**
* This method expects `elementHandle` to point to an
* [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).
@ -9063,6 +9250,66 @@ export interface Locator {
timeout?: number;
}): Promise<void>;
/**
* This method checks or unchecks an element by performing the following steps:
* 1. Ensure that matched element is a checkbox or a radio input. If not, this method throws.
* 1. If the element already has the right checked state, this method returns immediately.
* 1. Wait for [actionability](https://playwright.dev/docs/actionability) checks on the matched element, unless `force` option is set. If the
* element is detached during the checks, the whole action is retried.
* 1. Scroll the element into view if needed.
* 1. Use [page.mouse](https://playwright.dev/docs/api/class-page#page-mouse) to click in the center of the element.
* 1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
* 1. Ensure that the element is now checked or unchecked. If not, this method throws.
*
* When all steps combined have not finished during the specified `timeout`, this method throws a [TimeoutError]. Passing
* zero timeout disables this.
* @param checked Whether to check or uncheck the checkbox.
* @param options
*/
setChecked(checked: boolean, options?: {
/**
* Whether to bypass the [actionability](https://playwright.dev/docs/actionability) checks. Defaults to `false`.
*/
force?: boolean;
/**
* Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
* opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
* inaccessible pages. Defaults to `false`.
*/
noWaitAfter?: boolean;
/**
* A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
* element.
*/
position?: {
x: number;
y: number;
};
/**
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
* element, the call throws an exception.
*/
strict?: boolean;
/**
* Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
* using the
* [browserContext.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-browsercontext#browser-context-set-default-timeout)
* or [page.setDefaultTimeout(timeout)](https://playwright.dev/docs/api/class-page#page-set-default-timeout) methods.
*/
timeout?: number;
/**
* When set, this method only performs the [actionability](https://playwright.dev/docs/actionability) checks and skips the action. Defaults to
* `false`. Useful to wait until the element is ready for the action without performing it.
*/
trial?: boolean;
}): Promise<void>;
/**
* This method expects `element` to point to an
* [input element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input).