diff --git a/lib/Page.js b/lib/Page.js index 0f079a9f104dc..f2b3ffdb2e2a0 100644 --- a/lib/Page.js +++ b/lib/Page.js @@ -732,9 +732,8 @@ class Page extends EventEmitter { } else { element.value = values.shift(); } - - element.dispatchEvent(new Event('change')); - element.dispatchEvent(new Event('input')); + element.dispatchEvent(new Event('input', { 'bubbles': true })); + element.dispatchEvent(new Event('change', { 'bubbles': true })); }, values); } diff --git a/test/assets/input/select.html b/test/assets/input/select.html index 44a80b466bbb8..879a537a766fe 100644 --- a/test/assets/input/select.html +++ b/test/assets/input/select.html @@ -25,6 +25,8 @@ window.result = { onInput: null, onChange: null, + onBubblingChange: null, + onBubblingInput: null, }; let select = document.querySelector('select'); @@ -50,6 +52,18 @@ return option.value; }); }, false); + + document.body.addEventListener('input', () => { + result.onBubblingInput = Array.from(select.querySelectorAll('option:checked')).map((option) => { + return option.value; + }); + }, false); + + document.body.addEventListener('change', () => { + result.onBubblingChange = Array.from(select.querySelectorAll('option:checked')).map((option) => { + return option.value; + }); + }, false); diff --git a/test/test.js b/test/test.js index fd992e84ea4e1..93235d69d3e8d 100644 --- a/test/test.js +++ b/test/test.js @@ -2244,6 +2244,13 @@ describe('Page', function() { expect(await page.evaluate(() => result.onChange)).toEqual(['blue', 'green', 'red']); })); + it('should respect event bubbling', SX(async function() { + await page.goto(PREFIX + '/input/select.html'); + await page.select('select', 'blue'); + expect(await page.evaluate(() => result.onBubblingInput)).toEqual(['blue']); + expect(await page.evaluate(() => result.onBubblingChange)).toEqual(['blue']); + })); + it('should work with no options', SX(async function() { await page.goto(PREFIX + '/input/select.html'); await page.evaluate(() => makeEmpty());