mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat(Page.select): return selected options from Page.select (#1099)
This patch teaches Page.select to return an array of actually selected options. If no option is selected, an empty array will be returned.
This commit is contained in:
parent
9f19641a3d
commit
e70f98ddb9
@ -929,7 +929,7 @@ Shortcut for [page.mainFrame().executionContext().queryObjects(prototypeHandle)]
|
|||||||
#### 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]> 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.
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]<[Array]<[string]>>> Returns 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.
|
||||||
|
15
lib/Page.js
15
lib/Page.js
@ -779,22 +779,19 @@ class Page extends EventEmitter {
|
|||||||
/**
|
/**
|
||||||
* @param {string} selector
|
* @param {string} selector
|
||||||
* @param {!Array<string>} values
|
* @param {!Array<string>} values
|
||||||
|
* @return {!Promise<!Array<string>>}
|
||||||
*/
|
*/
|
||||||
async select(selector, ...values) {
|
async select(selector, ...values) {
|
||||||
await this.$eval(selector, (element, values) => {
|
return await this.$eval(selector, (element, values) => {
|
||||||
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;
|
||||||
if (element.multiple) {
|
for (const option of options)
|
||||||
for (const option of options)
|
option.selected = values.includes(option.value);
|
||||||
option.selected = values.includes(option.value);
|
|
||||||
} else {
|
|
||||||
element.value = values.shift();
|
|
||||||
}
|
|
||||||
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);
|
||||||
}, values);
|
}, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
58
test/test.js
58
test/test.js
@ -2712,27 +2712,53 @@ describe('Page', function() {
|
|||||||
expect(await page.evaluate(() => result.onBubblingChange)).toEqual(['blue']);
|
expect(await page.evaluate(() => result.onBubblingChange)).toEqual(['blue']);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should work with no options', SX(async function() {
|
it('should throw when element is not a <select>', SX(async function() {
|
||||||
await page.goto(PREFIX + '/input/select.html');
|
|
||||||
await page.evaluate(() => makeEmpty());
|
|
||||||
await page.select('select', '42');
|
|
||||||
expect(await page.evaluate(() => result.onInput)).toEqual([]);
|
|
||||||
expect(await page.evaluate(() => result.onChange)).toEqual([]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should not select a non-existent option', SX(async function() {
|
|
||||||
await page.goto(PREFIX + '/input/select.html');
|
|
||||||
await page.select('select', '42');
|
|
||||||
expect(await page.evaluate(() => result.onInput)).toEqual([]);
|
|
||||||
expect(await page.evaluate(() => result.onChange)).toEqual([]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should throw', SX(async function() {
|
|
||||||
let error = null;
|
let error = null;
|
||||||
await page.goto(PREFIX + '/input/select.html');
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
await page.select('body', '').catch(e => error = e);
|
await page.select('body', '').catch(e => error = e);
|
||||||
expect(error.message).toContain('Element is not a <select> element.');
|
expect(error.message).toContain('Element is not a <select> element.');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should return [] on no matched values', SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
const result = await page.select('select','42','abc');
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should return an array of matched values', SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
await page.evaluate(() => makeMultiple());
|
||||||
|
const result = await page.select('select','blue','black','magenta');
|
||||||
|
expect(result.reduce((accumulator,current) => ['blue', 'black', 'magenta'].includes(current) && accumulator, true)).toEqual(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should return an array of one element when multiple is not set', SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
const result = await page.select('select','42','blue','black','magenta');
|
||||||
|
expect(result.length).toEqual(1);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should return [] on no values',SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
const result = await page.select('select');
|
||||||
|
expect(result).toEqual([]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should deselect all options when passed no values for a multiple select',SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
await page.evaluate(() => makeMultiple());
|
||||||
|
await page.select('select','blue','black','magenta');
|
||||||
|
await page.select('select');
|
||||||
|
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should deselect all options when passed no values for a select without multiple',SX(async function() {
|
||||||
|
await page.goto(PREFIX + '/input/select.html');
|
||||||
|
await page.select('select','blue','black','magenta');
|
||||||
|
await page.select('select');
|
||||||
|
expect(await page.$eval('select', select => Array.from(select.options).every(option => !option.selected))).toEqual(true);
|
||||||
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Tracing', function() {
|
describe('Tracing', function() {
|
||||||
|
Loading…
Reference in New Issue
Block a user