fix(selectors): make selectOptions work for labels (#4402)

This commit is contained in:
Yury Semikhatsky 2020-11-11 15:33:23 -08:00 committed by GitHub
parent 138680f93c
commit 5702eca1f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 10 deletions

View File

@ -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);
}

View File

@ -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');