mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-14 21:53:35 +03:00
fix(selectors): make selectOptions work for labels (#4402)
This commit is contained in:
parent
138680f93c
commit
5702eca1f2
@ -227,14 +227,14 @@ export class InjectedScript {
|
||||
}
|
||||
|
||||
selectOptions(node: Node, optionsToSelect: (Node | { value?: string, label?: string, index?: number })[]): string[] | 'error:notconnected' | FatalDOMError {
|
||||
if (node.nodeName.toLowerCase() !== 'select')
|
||||
return 'error:notselect';
|
||||
if (!node.isConnected)
|
||||
const element = this.findLabelTarget(node as Element);
|
||||
if (!element || !element.isConnected)
|
||||
return 'error:notconnected';
|
||||
const element = node as HTMLSelectElement;
|
||||
|
||||
const options = Array.from(element.options);
|
||||
element.value = undefined as any;
|
||||
if (element.nodeName.toLowerCase() !== 'select')
|
||||
return 'error:notselect';
|
||||
const select = element as HTMLSelectElement;
|
||||
const options = Array.from(select.options);
|
||||
select.value = undefined as any;
|
||||
for (let index = 0; index < options.length; index++) {
|
||||
const option = options[index];
|
||||
option.selected = optionsToSelect.some(optionToSelect => {
|
||||
@ -249,11 +249,11 @@ export class InjectedScript {
|
||||
matches = matches && optionToSelect.index === index;
|
||||
return matches;
|
||||
});
|
||||
if (option.selected && !element.multiple)
|
||||
if (option.selected && !select.multiple)
|
||||
break;
|
||||
}
|
||||
element.dispatchEvent(new Event('input', { 'bubbles': true }));
|
||||
element.dispatchEvent(new Event('change', { 'bubbles': true }));
|
||||
select.dispatchEvent(new Event('input', { 'bubbles': true }));
|
||||
select.dispatchEvent(new Event('change', { 'bubbles': true }));
|
||||
return options.filter(option => option.selected).map(option => option.value);
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,26 @@ it('should select multiple options with attributes', async ({page, server}) => {
|
||||
expect(await page.evaluate(() => window['result'].onChange)).toEqual(['blue', 'gray', 'green']);
|
||||
});
|
||||
|
||||
it('should select options with sibling label', async ({page, server}) => {
|
||||
await page.setContent(`<label for=pet-select>Choose a pet</label>
|
||||
<select id='pet-select'>
|
||||
<option value='dog'>Dog</option>
|
||||
<option value='cat'>Cat</option>
|
||||
</select>`);
|
||||
await page.selectOption('text=Choose a pet', 'cat');
|
||||
expect(await page.$eval('select', select => select.options[select.selectedIndex].text)).toEqual('Cat');
|
||||
});
|
||||
|
||||
it('should select options with outer label', async ({page, server}) => {
|
||||
await page.setContent(`<label for=pet-select>Choose a pet
|
||||
<select id='pet-select'>
|
||||
<option value='dog'>Dog</option>
|
||||
<option value='cat'>Cat</option>
|
||||
</select></label>`);
|
||||
await page.selectOption('text=Choose a pet', 'cat');
|
||||
expect(await page.$eval('select', select => select.options[select.selectedIndex].text)).toEqual('Cat');
|
||||
});
|
||||
|
||||
it('should respect event bubbling', async ({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/select.html');
|
||||
await page.selectOption('select', 'blue');
|
||||
|
Loading…
Reference in New Issue
Block a user