mirror of
https://github.com/microsoft/playwright.git
synced 2025-06-26 21:40:17 +00:00
fix(waitForSelector): use raf polling instead of mutation (#2047)
MutationObserver does not work with mutations in the shadow, so we cannot use it for selectors that pierce shadows.
This commit is contained in:
parent
9f62f29946
commit
4afd39117a
@ -145,8 +145,7 @@ export class Selectors {
|
||||
_waitForSelectorTask(selector: string, waitFor: 'attached' | 'detached' | 'visible' | 'hidden', deadline: number): { world: 'main' | 'utility', task: (context: dom.FrameExecutionContext) => Promise<js.JSHandle> } {
|
||||
const parsed = this._parseSelector(selector);
|
||||
const task = async (context: dom.FrameExecutionContext) => context.evaluateHandleInternal(({ evaluator, parsed, waitFor, timeout }) => {
|
||||
const polling = (waitFor === 'attached' || waitFor === 'detached') ? 'mutation' : 'raf';
|
||||
return evaluator.injected.poll(polling, timeout, () => {
|
||||
return evaluator.injected.poll('raf', timeout, () => {
|
||||
const element = evaluator.querySelector(parsed, document);
|
||||
switch (waitFor) {
|
||||
case 'attached':
|
||||
@ -166,7 +165,7 @@ export class Selectors {
|
||||
_dispatchEventTask(selector: string, type: string, eventInit: Object, deadline: number): (context: dom.FrameExecutionContext) => Promise<js.JSHandle> {
|
||||
const parsed = this._parseSelector(selector);
|
||||
const task = async (context: dom.FrameExecutionContext) => context.evaluateHandleInternal(({ evaluator, parsed, type, eventInit, timeout }) => {
|
||||
return evaluator.injected.poll('mutation', timeout, () => {
|
||||
return evaluator.injected.poll('raf', timeout, () => {
|
||||
const element = evaluator.querySelector(parsed, document);
|
||||
if (element)
|
||||
evaluator.injected.dispatchEvent(element, type, eventInit);
|
||||
|
||||
@ -79,6 +79,24 @@ describe('Page.dispatchEvent(click)', function() {
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => window.clicked)).toBeTruthy();
|
||||
});
|
||||
it('should dispatch click when node is added in shadow dom', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const watchdog = page.dispatchEvent('span', 'click');
|
||||
await page.evaluate(() => {
|
||||
const div = document.createElement('div');
|
||||
div.attachShadow({mode: 'open'});
|
||||
document.body.appendChild(div);
|
||||
});
|
||||
await page.evaluate(() => new Promise(f => setTimeout(f, 100)));
|
||||
await page.evaluate(() => {
|
||||
const span = document.createElement('span');
|
||||
span.textContent = 'Hello from shadow';
|
||||
span.addEventListener('click', () => window.clicked = true);
|
||||
document.querySelector('div').shadowRoot.appendChild(span);
|
||||
});
|
||||
await watchdog;
|
||||
expect(await page.evaluate(() => window.clicked)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.dispatchEvent(drag)', function() {
|
||||
|
||||
@ -192,6 +192,23 @@ describe('Frame.waitForSelector', function() {
|
||||
const tagName = await eHandle.getProperty('tagName').then(e => e.jsonValue());
|
||||
expect(tagName).toBe('DIV');
|
||||
});
|
||||
it('should resolve promise when node is added in shadow dom', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const watchdog = page.waitForSelector('span');
|
||||
await page.evaluate(() => {
|
||||
const div = document.createElement('div');
|
||||
div.attachShadow({mode: 'open'});
|
||||
document.body.appendChild(div);
|
||||
});
|
||||
await page.evaluate(() => new Promise(f => setTimeout(f, 100)));
|
||||
await page.evaluate(() => {
|
||||
const span = document.createElement('span');
|
||||
span.textContent = 'Hello from shadow';
|
||||
document.querySelector('div').shadowRoot.appendChild(span);
|
||||
});
|
||||
const handle = await watchdog;
|
||||
expect(await handle.evaluate(e => e.textContent)).toBe('Hello from shadow');
|
||||
});
|
||||
it('should work when node is added through innerHTML', async({page, server}) => {
|
||||
await page.goto(server.EMPTY_PAGE);
|
||||
const watchdog = page.waitForSelector('h3 div');
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user