mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
fix: parse empty options in <select> (#8489)
This commit is contained in:
parent
f64ec2051b
commit
b30f3f44cd
@ -766,7 +766,7 @@ export class ElementHandle<
|
|||||||
* one is taken into account.
|
* one is taken into account.
|
||||||
*/
|
*/
|
||||||
async select(...values: string[]): Promise<string[]> {
|
async select(...values: string[]): Promise<string[]> {
|
||||||
for (const value of values)
|
for (const value of values) {
|
||||||
assert(
|
assert(
|
||||||
helper.isString(value),
|
helper.isString(value),
|
||||||
'Values must be strings. Found value "' +
|
'Values must be strings. Found value "' +
|
||||||
@ -775,26 +775,38 @@ export class ElementHandle<
|
|||||||
typeof value +
|
typeof value +
|
||||||
'"'
|
'"'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return this.evaluate<(element: Element, values: string[]) => string[]>(
|
return this.evaluate((element: Element, vals: string[]): string[] => {
|
||||||
(element, values) => {
|
const values = new Set(vals);
|
||||||
if (!(element instanceof HTMLSelectElement))
|
if (!(element instanceof HTMLSelectElement)) {
|
||||||
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 selectedValues = new Set<string>();
|
||||||
element.value = '';
|
if (!element.multiple) {
|
||||||
for (const option of options) {
|
for (const option of element.options) {
|
||||||
option.selected = values.includes(option.value);
|
option.selected = false;
|
||||||
if (option.selected && !element.multiple) break;
|
}
|
||||||
|
for (const option of element.options) {
|
||||||
|
if (values.has(option.value)) {
|
||||||
|
option.selected = true;
|
||||||
|
selectedValues.add(option.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const option of element.options) {
|
||||||
|
option.selected = values.has(option.value);
|
||||||
|
if (option.selected) {
|
||||||
|
selectedValues.add(option.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
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
|
return [...selectedValues.values()];
|
||||||
.filter((option) => option.selected)
|
}, values);
|
||||||
.map((option) => option.value);
|
|
||||||
},
|
|
||||||
values
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<select>
|
<select>
|
||||||
|
<option value="">Empty</option>
|
||||||
<option value="black">Black</option>
|
<option value="black">Black</option>
|
||||||
<option value="blue">Blue</option>
|
<option value="blue">Blue</option>
|
||||||
<option value="brown">Brown</option>
|
<option value="brown">Brown</option>
|
||||||
|
@ -1887,12 +1887,13 @@ describe('Page', function () {
|
|||||||
await page.select('select', 'blue', 'black', 'magenta');
|
await page.select('select', 'blue', 'black', 'magenta');
|
||||||
await page.select('select');
|
await page.select('select');
|
||||||
expect(
|
expect(
|
||||||
await page.$eval('select', (select: HTMLSelectElement) =>
|
await page.$eval(
|
||||||
Array.from(select.options).every(
|
'select',
|
||||||
(option: HTMLOptionElement) => !option.selected
|
(select: HTMLSelectElement) =>
|
||||||
|
Array.from(select.options).filter((option) => option.selected)[0]
|
||||||
|
.value
|
||||||
)
|
)
|
||||||
)
|
).toEqual('');
|
||||||
).toEqual(true);
|
|
||||||
});
|
});
|
||||||
it('should throw if passed in non-strings', async () => {
|
it('should throw if passed in non-strings', async () => {
|
||||||
const { page } = getTestState();
|
const { page } = getTestState();
|
||||||
|
Loading…
Reference in New Issue
Block a user