feat(select): allow to select options by value/label/id/index (#46)
This commit is contained in:
parent
6fcb4d2f30
commit
7783400156
61
docs/api.md
61
docs/api.md
|
|
@ -1615,16 +1615,29 @@ Page is guaranteed to have a main frame which persists during navigations.
|
||||||
> **NOTE** Screenshots take at least 1/6 second on OS X. See https://crbug.com/741689 for discussion.
|
> **NOTE** Screenshots take at least 1/6 second on OS X. See https://crbug.com/741689 for discussion.
|
||||||
|
|
||||||
#### page.select(selector, ...values)
|
#### page.select(selector, ...values)
|
||||||
- `selector` <[string]> A [selector] to query page for
|
- `selector` <[string]> A [selector] to query page for.
|
||||||
- `...values` <...[string]> Values of options to select. If the `<select>` has the `multiple` attribute, all values are considered, otherwise only the first one is taken into account.
|
- `...values` <...[string]|[Object]> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
|
||||||
|
- `value` <[string]> Matches by `option.value`.
|
||||||
|
- `label` <[string]> Matches by `option.label`.
|
||||||
|
- `id` <[string]> Matches by `option.id`.
|
||||||
|
- `index` <[number]> Matches by the index.
|
||||||
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
||||||
|
|
||||||
Triggers a `change` and `input` event once all the provided options have been selected.
|
Triggers a `change` and `input` event once all the provided options have been selected.
|
||||||
If there's no `<select>` element matching `selector`, the method throws an error.
|
If there's no `<select>` element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
page.select('select#colors', 'blue'); // single selection
|
// single selection matching the value
|
||||||
page.select('select#colors', 'red', 'green', 'blue'); // multiple selections
|
page.select('select#colors', 'blue');
|
||||||
|
|
||||||
|
// single selection matching both the value and the label
|
||||||
|
page.select('select#colors', { value: 'blue', label: 'Blue' });
|
||||||
|
|
||||||
|
// multiple selection
|
||||||
|
page.select('select#colors', 'red', 'green', 'blue');
|
||||||
|
|
||||||
|
// multiple selection for blue, red and second option
|
||||||
|
page.select('select#colors', { value: 'blue' }, { index: 2 }, 'red');
|
||||||
```
|
```
|
||||||
|
|
||||||
Shortcut for [page.mainFrame().select()](#frameselectselector-values)
|
Shortcut for [page.mainFrame().select()](#frameselectselector-values)
|
||||||
|
|
@ -2809,16 +2822,29 @@ If the name is empty, returns the id attribute instead.
|
||||||
- returns: <?[Frame]> Parent frame, if any. Detached frames and main frames return `null`.
|
- returns: <?[Frame]> Parent frame, if any. Detached frames and main frames return `null`.
|
||||||
|
|
||||||
#### frame.select(selector, ...values)
|
#### frame.select(selector, ...values)
|
||||||
- `selector` <[string]> A [selector] to query frame for
|
- `selector` <[string]> A [selector] to query frame for.
|
||||||
- `...values` <...[string]> Values of options to select. If the `<select>` has the `multiple` attribute, all values are considered, otherwise only the first one is taken into account.
|
- `...values` <...[string]|[Object]> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
|
||||||
|
- `value` <[string]> Matches by `option.value`.
|
||||||
|
- `label` <[string]> Matches by `option.label`.
|
||||||
|
- `id` <[string]> Matches by `option.id`.
|
||||||
|
- `index` <[number]> Matches by the index.
|
||||||
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
||||||
|
|
||||||
Triggers a `change` and `input` event once all the provided options have been selected.
|
Triggers a `change` and `input` event once all the provided options have been selected.
|
||||||
If there's no `<select>` element matching `selector`, the method throws an error.
|
If there's no `<select>` element matching `selector`, the method throws an error.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
frame.select('select#colors', 'blue'); // single selection
|
// single selection matching the value
|
||||||
frame.select('select#colors', 'red', 'green', 'blue'); // multiple selections
|
frame.select('select#colors', 'blue');
|
||||||
|
|
||||||
|
// single selection matching both the value and the label
|
||||||
|
frame.select('select#colors', { value: 'blue', label: 'Blue' });
|
||||||
|
|
||||||
|
// multiple selection
|
||||||
|
frame.select('select#colors', 'red', 'green', 'blue');
|
||||||
|
|
||||||
|
// multiple selection matching blue, red and second option
|
||||||
|
frame.select('select#colors', { value: 'blue' }, { index: 2 }, 'red');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### frame.setContent(html[, options])
|
#### frame.setContent(html[, options])
|
||||||
|
|
@ -3523,15 +3549,28 @@ This method scrolls element into view if needed, and then uses [page.screenshot]
|
||||||
If the element is detached from DOM, the method throws an error.
|
If the element is detached from DOM, the method throws an error.
|
||||||
|
|
||||||
#### elementHandle.select(...values)
|
#### elementHandle.select(...values)
|
||||||
- `...values` <...[string]> Values of options to select. If the `<select>` has the `multiple` attribute, all values are considered, otherwise only the first one is taken into account.
|
- `...values` <...[string]|[Object]> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
|
||||||
|
- `value` <[string]> Matches by `option.value`.
|
||||||
|
- `label` <[string]> Matches by `option.label`.
|
||||||
|
- `id` <[string]> Matches by `option.id`.
|
||||||
|
- `index` <[number]> Matches by the index.
|
||||||
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
- returns: <[Promise]<[Array]<[string]>>> An array of option values that have been successfully selected.
|
||||||
|
|
||||||
Triggers a `change` and `input` event once all the provided options have been selected.
|
Triggers a `change` and `input` event once all the provided options have been selected.
|
||||||
If element is not a `<select>` element, the method throws an error.
|
If element is not a `<select>` element, the method throws an error.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
handle.select('blue'); // single selection
|
// single selection matching the value
|
||||||
handle.select('red', 'green', 'blue'); // multiple selections
|
handle.select('blue');
|
||||||
|
|
||||||
|
// single selection matching both the value and the label
|
||||||
|
handle.select({ value: 'blue', label: 'Blue' });
|
||||||
|
|
||||||
|
// multiple selection
|
||||||
|
handle.select('red', 'green', 'blue');
|
||||||
|
|
||||||
|
// multiple selection for blue, red and second option
|
||||||
|
handle.select({ value: 'blue' }, { index: 2 }, 'red');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### elementHandle.toString()
|
#### elementHandle.toString()
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ import { ExecutionContext } from './ExecutionContext';
|
||||||
import { Frame } from './Frame';
|
import { Frame } from './Frame';
|
||||||
import { FrameManager } from './FrameManager';
|
import { FrameManager } from './FrameManager';
|
||||||
import { assert, helper } from '../helper';
|
import { assert, helper } from '../helper';
|
||||||
import { ElementHandle, JSHandle, ClickOptions, PointerActionOptions, MultiClickOptions } from './JSHandle';
|
import { ElementHandle, JSHandle, ClickOptions, PointerActionOptions, MultiClickOptions, SelectOption } from './JSHandle';
|
||||||
import { LifecycleWatcher } from './LifecycleWatcher';
|
import { LifecycleWatcher } from './LifecycleWatcher';
|
||||||
import { TimeoutSettings } from '../TimeoutSettings';
|
import { TimeoutSettings } from '../TimeoutSettings';
|
||||||
const readFileAsync = helper.promisify(fs.readFile);
|
const readFileAsync = helper.promisify(fs.readFile);
|
||||||
|
|
@ -322,7 +322,7 @@ export class DOMWorld {
|
||||||
await handle.dispose();
|
await handle.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async select(selector: string, ...values: string[]): Promise<string[]> {
|
async select(selector: string, ...values: (string | SelectOption)[]): Promise<string[]> {
|
||||||
const handle = await this.$(selector);
|
const handle = await this.$(selector);
|
||||||
assert(handle, 'No node found for selector: ' + selector);
|
assert(handle, 'No node found for selector: ' + selector);
|
||||||
const result = await handle.select(...values);
|
const result = await handle.select(...values);
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ import { CDPSession } from './Connection';
|
||||||
import { DOMWorld } from './DOMWorld';
|
import { DOMWorld } from './DOMWorld';
|
||||||
import { ExecutionContext } from './ExecutionContext';
|
import { ExecutionContext } from './ExecutionContext';
|
||||||
import { FrameManager } from './FrameManager';
|
import { FrameManager } from './FrameManager';
|
||||||
import { ClickOptions, ElementHandle, JSHandle, MultiClickOptions, PointerActionOptions } from './JSHandle';
|
import { ClickOptions, ElementHandle, JSHandle, MultiClickOptions, PointerActionOptions, SelectOption } from './JSHandle';
|
||||||
import { Response } from './NetworkManager';
|
import { Response } from './NetworkManager';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@ export class Frame {
|
||||||
return this._secondaryWorld.hover(selector, options);
|
return this._secondaryWorld.hover(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(selector: string, ...values: string[]): Promise<string[]>{
|
select(selector: string, ...values: (string | SelectOption)[]): Promise<string[]>{
|
||||||
return this._secondaryWorld.select(selector, ...values);
|
return this._secondaryWorld.select(selector, ...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,13 @@ export type MultiClickOptions = PointerActionOptions & {
|
||||||
button?: Button;
|
button?: Button;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type SelectOption = {
|
||||||
|
value?: string;
|
||||||
|
id?: string;
|
||||||
|
label?: string;
|
||||||
|
index?: number;
|
||||||
|
};
|
||||||
|
|
||||||
export function createJSHandle(context: ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject) {
|
export function createJSHandle(context: ExecutionContext, remoteObject: Protocol.Runtime.RemoteObject) {
|
||||||
const frame = context.frame();
|
const frame = context.frame();
|
||||||
if (remoteObject.subtype === 'node' && frame) {
|
if (remoteObject.subtype === 'node' && frame) {
|
||||||
|
|
@ -317,24 +324,45 @@ export class ElementHandle extends JSHandle {
|
||||||
return this._performPointerAction(point => this._page.mouse.tripleclick(point.x, point.y, options), options);
|
return this._performPointerAction(point => this._page.mouse.tripleclick(point.x, point.y, options), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async select(...values: string[]): Promise<string[]> {
|
async select(...values: (string | SelectOption)[]): Promise<string[]> {
|
||||||
for (const value of values)
|
const options = values.map(value => typeof value === 'object' ? value : { value });
|
||||||
assert(helper.isString(value), 'Values must be strings. Found value "' + value + '" of type "' + (typeof value) + '"');
|
for (const option of options) {
|
||||||
return this.evaluate((element: HTMLSelectElement, values: string[]) => {
|
if (option.value !== undefined)
|
||||||
|
assert(helper.isString(option.value), 'Values must be strings. Found value "' + option.value + '" of type "' + (typeof option.value) + '"');
|
||||||
|
if (option.label !== undefined)
|
||||||
|
assert(helper.isString(option.label), 'Labels must be strings. Found label "' + option.label + '" of type "' + (typeof option.label) + '"');
|
||||||
|
if (option.id !== undefined)
|
||||||
|
assert(helper.isString(option.id), 'Ids must be strings. Found id "' + option.id + '" of type "' + (typeof option.id) + '"');
|
||||||
|
if (option.index !== undefined)
|
||||||
|
assert(helper.isNumber(option.index), 'Indices must be numbers. Found index "' + option.index + '" of type "' + (typeof option.index) + '"');
|
||||||
|
}
|
||||||
|
return this.evaluate((element: HTMLSelectElement, optionsToSelect: SelectOption[]) => {
|
||||||
if (element.nodeName.toLowerCase() !== 'select')
|
if (element.nodeName.toLowerCase() !== 'select')
|
||||||
throw new Error('Element is not a <select> element.');
|
throw new Error('Element is not a <select> element.');
|
||||||
|
|
||||||
const options = Array.from(element.options);
|
const options = Array.from(element.options);
|
||||||
element.value = undefined;
|
element.value = undefined;
|
||||||
for (const option of options) {
|
for (let index = 0; index < options.length; index++) {
|
||||||
option.selected = values.includes(option.value);
|
const option = options[index];
|
||||||
|
option.selected = optionsToSelect.some(optionToSelect => {
|
||||||
|
let matches = true;
|
||||||
|
if (optionToSelect.value !== undefined)
|
||||||
|
matches = matches && optionToSelect.value === option.value;
|
||||||
|
if (optionToSelect.label !== undefined)
|
||||||
|
matches = matches && optionToSelect.label === option.label;
|
||||||
|
if (optionToSelect.id !== undefined)
|
||||||
|
matches = matches && optionToSelect.id === option.id;
|
||||||
|
if (optionToSelect.index !== undefined)
|
||||||
|
matches = matches && optionToSelect.index === index;
|
||||||
|
return matches;
|
||||||
|
});
|
||||||
if (option.selected && !element.multiple)
|
if (option.selected && !element.multiple)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
element.dispatchEvent(new Event('input', { 'bubbles': true }));
|
element.dispatchEvent(new Event('input', { 'bubbles': true }));
|
||||||
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
||||||
return options.filter(option => option.selected).map(option => option.value);
|
return options.filter(option => option.selected).map(option => option.value);
|
||||||
}, values);
|
}, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fill(value: string): Promise<void> {
|
async fill(value: string): Promise<void> {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ import { PDF } from './features/pdf';
|
||||||
import { Frame } from './Frame';
|
import { Frame } from './Frame';
|
||||||
import { FrameManager, FrameManagerEvents } from './FrameManager';
|
import { FrameManager, FrameManagerEvents } from './FrameManager';
|
||||||
import { Keyboard, Mouse } from './Input';
|
import { Keyboard, Mouse } from './Input';
|
||||||
import { ClickOptions, createJSHandle, ElementHandle, JSHandle, MultiClickOptions, PointerActionOptions } from './JSHandle';
|
import { ClickOptions, createJSHandle, ElementHandle, JSHandle, MultiClickOptions, PointerActionOptions, SelectOption } from './JSHandle';
|
||||||
import { NetworkManagerEvents, Response } from './NetworkManager';
|
import { NetworkManagerEvents, Response } from './NetworkManager';
|
||||||
import { Protocol } from './protocol';
|
import { Protocol } from './protocol';
|
||||||
import { getExceptionMessage, releaseObject, valueFromRemoteObject } from './protocolHelper';
|
import { getExceptionMessage, releaseObject, valueFromRemoteObject } from './protocolHelper';
|
||||||
|
|
@ -715,7 +715,7 @@ export class Page extends EventEmitter {
|
||||||
return this.mainFrame().hover(selector, options);
|
return this.mainFrame().hover(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
select(selector: string, ...values: string[]): Promise<string[]> {
|
select(selector: string, ...values: (string | SelectOption)[]): Promise<string[]> {
|
||||||
return this.mainFrame().select(selector, ...values);
|
return this.mainFrame().select(selector, ...values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<option value="purple">Purple</option>
|
<option value="purple">Purple</option>
|
||||||
<option value="red">Red</option>
|
<option value="red">Red</option>
|
||||||
<option value="violet">Violet</option>
|
<option value="violet">Violet</option>
|
||||||
<option value="white">White</option>
|
<option value="white" id="whiteOption">White</option>
|
||||||
<option value="yellow">Yellow</option>
|
<option value="yellow">Yellow</option>
|
||||||
</select>
|
</select>
|
||||||
<script>
|
<script>
|
||||||
|
|
|
||||||
|
|
@ -890,6 +890,41 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
expect(await page.evaluate(() => result.onInput)).toEqual(['blue']);
|
expect(await page.evaluate(() => result.onInput)).toEqual(['blue']);
|
||||||
expect(await page.evaluate(() => result.onChange)).toEqual(['blue']);
|
expect(await page.evaluate(() => result.onChange)).toEqual(['blue']);
|
||||||
});
|
});
|
||||||
|
it('should select single option by value', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { value: 'blue' });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['blue']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['blue']);
|
||||||
|
});
|
||||||
|
it('should select single option by label', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { label: 'Indigo' });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['indigo']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['indigo']);
|
||||||
|
});
|
||||||
|
it('should select single option by id', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { id: 'whiteOption' });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['white']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['white']);
|
||||||
|
});
|
||||||
|
it('should select single option by index', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { index: 2 });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['brown']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['brown']);
|
||||||
|
});
|
||||||
|
it('should select single option by multiple attributes', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { value: 'green', label: 'Green' });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['green']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['green']);
|
||||||
|
});
|
||||||
|
it('should not select single option when some attributes do not match', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.select('select', { value: 'green', label: 'Brown' });
|
||||||
|
expect(await page.evaluate(() => document.querySelector('select').value)).toEqual('');
|
||||||
|
});
|
||||||
it('should select only first option', async({page, server}) => {
|
it('should select only first option', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/select.html');
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
await page.select('select', 'blue', 'green', 'red');
|
await page.select('select', 'blue', 'green', 'red');
|
||||||
|
|
@ -912,6 +947,13 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
expect(await page.evaluate(() => result.onInput)).toEqual(['blue', 'green', 'red']);
|
expect(await page.evaluate(() => result.onInput)).toEqual(['blue', 'green', 'red']);
|
||||||
expect(await page.evaluate(() => result.onChange)).toEqual(['blue', 'green', 'red']);
|
expect(await page.evaluate(() => result.onChange)).toEqual(['blue', 'green', 'red']);
|
||||||
});
|
});
|
||||||
|
it('should select multiple options with attributes', async({page, server}) => {
|
||||||
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
|
await page.evaluate(() => makeMultiple());
|
||||||
|
await page.select('select', 'blue', { label: 'Green' }, { index: 4 });
|
||||||
|
expect(await page.evaluate(() => result.onInput)).toEqual(['blue', 'gray', 'green']);
|
||||||
|
expect(await page.evaluate(() => result.onChange)).toEqual(['blue', 'gray', 'green']);
|
||||||
|
});
|
||||||
it('should respect event bubbling', async({page, server}) => {
|
it('should respect event bubbling', async({page, server}) => {
|
||||||
await page.goto(server.PREFIX + '/input/select.html');
|
await page.goto(server.PREFIX + '/input/select.html');
|
||||||
await page.select('select', 'blue');
|
await page.select('select', 'blue');
|
||||||
|
|
@ -958,15 +1000,49 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF
|
||||||
await page.select('select');
|
await page.select('select');
|
||||||
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||||
});
|
});
|
||||||
it('should throw if passed in non-strings', async({page, server}) => {
|
it('should throw if passed wrong types', async({page, server}) => {
|
||||||
|
let error;
|
||||||
await page.setContent('<select><option value="12"/></select>');
|
await page.setContent('<select><option value="12"/></select>');
|
||||||
let error = null;
|
|
||||||
|
error = null;
|
||||||
try {
|
try {
|
||||||
await page.select('select', 12);
|
await page.select('select', 12);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
error = e;
|
error = e;
|
||||||
}
|
}
|
||||||
expect(error.message).toContain('Values must be strings');
|
expect(error.message).toContain('Values must be strings');
|
||||||
|
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
await page.select('select', { value: 12 });
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Values must be strings');
|
||||||
|
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
await page.select('select', { label: 12 });
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Labels must be strings');
|
||||||
|
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
await page.select('select', { id: 12 });
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Ids must be strings');
|
||||||
|
|
||||||
|
error = null;
|
||||||
|
try {
|
||||||
|
await page.select('select', { index: '12' });
|
||||||
|
} catch (e) {
|
||||||
|
error = e;
|
||||||
|
}
|
||||||
|
expect(error.message).toContain('Indices must be numbers');
|
||||||
});
|
});
|
||||||
// @see https://github.com/GoogleChrome/puppeteer/issues/3327
|
// @see https://github.com/GoogleChrome/puppeteer/issues/3327
|
||||||
it.skip(FFOX || WEBKIT)('should work when re-defining top-level Event class', async({page, server}) => {
|
it.skip(FFOX || WEBKIT)('should work when re-defining top-level Event class', async({page, server}) => {
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ class MDOutline {
|
||||||
const properties = [];
|
const properties = [];
|
||||||
const comment = str.substring(str.indexOf('<') + type.length + 2).trim();
|
const comment = str.substring(str.indexOf('<') + type.length + 2).trim();
|
||||||
// Strings have enum values instead of properties
|
// Strings have enum values instead of properties
|
||||||
if (!type.includes('string')) {
|
if (type !== 'string' && type !== 'string|number' && type !== 'string|Array<string>' && type !== 'Array<string>') {
|
||||||
for (const childElement of element.querySelectorAll(':scope > ul > li')) {
|
for (const childElement of element.querySelectorAll(':scope > ul > li')) {
|
||||||
const property = parseProperty(childElement);
|
const property = parseProperty(childElement);
|
||||||
property.required = property.comment.includes('***required***');
|
property.required = property.comment.includes('***required***');
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue