diff --git a/tests/assets/drag-n-drop.html b/tests/assets/drag-n-drop.html index f43583e7c9..b73154a58f 100644 --- a/tests/assets/drag-n-drop.html +++ b/tests/assets/drag-n-drop.html @@ -1,14 +1,28 @@ diff --git a/tests/page/page-drag.spec.ts b/tests/page/page-drag.spec.ts index b87e60851a..e41eabf8e1 100644 --- a/tests/page/page-drag.spec.ts +++ b/tests/page/page-drag.spec.ts @@ -37,18 +37,88 @@ it.describe('Drag and drop', () => { await page.mouse.down(); await page.hover('#target'); await page.mouse.up(); - expect(await events.jsonValue()).toEqual([ - 'mousemove', - 'mousedown', - browserName === 'firefox' ? 'dragstart' : 'mousemove', - browserName === 'firefox' ? 'mousemove' : 'dragstart', - 'dragenter', - 'dragover', - 'drop', + expect(await events.jsonValue()).toEqual(browserName === 'firefox' ? [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'dragstart at 121;87', + 'mousemove at 241;351', + 'dragenter at 0;0', + 'dragover at 0;0', + 'drop at 0;0', + 'dragend', + ] : [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'mousemove at 241;351', + 'dragstart at 121;87', + 'dragenter at 241;351', + 'dragover at 241;351', + 'drop at 241;351', 'dragend', ]); }); + it('should not send dragover on the first mousemove', async ({ server, page, browserName }) => { + it.fixme(browserName !== 'chromium'); + + await page.goto(server.PREFIX + '/drag-n-drop.html'); + const events = await trackEvents(await page.$('body')); + await page.hover('#source'); + await page.mouse.down(); + await page.hover('#target'); + expect(await events.jsonValue()).toEqual(browserName === 'firefox' ? [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'dragstart at 121;87', + 'mousemove at 241;351', + 'dragenter at 0;0', + ] : [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'mousemove at 241;351', + 'dragstart at 121;87', + 'dragenter at 241;351', + ]); + }); + + it('should work inside iframe', async ({ page, server, browserName }) => { + await page.goto(server.EMPTY_PAGE); + const frame = await attachFrame(page, 'myframe', server.PREFIX + '/drag-n-drop.html'); + await page.$eval('iframe', iframe => { + iframe.style.width = '500px'; + iframe.style.height = '600px'; + iframe.style.marginLeft = '80px'; + iframe.style.marginTop = '60px'; + }); + const pageEvents = await trackEvents(await page.$('body')); + const frameEvents = await trackEvents(await frame.$('body')); + await frame.hover('#source'); + await page.mouse.down(); + await frame.hover('#target'); + await page.mouse.up(); + expect(await frame.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target + expect(await frameEvents.jsonValue()).toEqual(browserName === 'firefox' ? [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'dragstart at 121;87', + 'mousemove at 241;351', + 'dragenter at 0;0', + 'dragover at 0;0', + 'drop at 0;0', + 'dragend', + ] : [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'mousemove at 241;351', + 'dragstart at 121;87', + 'dragenter at 241;351', + 'dragover at 241;351', + 'drop at 241;351', + 'dragend', + ]); + expect(await pageEvents.jsonValue()).toEqual([]); + }); + it('should cancel on escape', async ({ server, page, browserName }) => { await page.goto(server.PREFIX + '/drag-n-drop.html'); const events = await trackEvents(await page.$('body')); @@ -58,15 +128,24 @@ it.describe('Drag and drop', () => { await page.keyboard.press('Escape'); await page.mouse.up(); expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(false); // found source in target - expect(await events.jsonValue()).toEqual([ - 'mousemove', - 'mousedown', - browserName === 'firefox' ? 'dragstart' : 'mousemove', - browserName === 'firefox' ? 'mousemove' : 'dragstart', - 'dragenter', - browserName !== 'chromium' ? 'dragover' : null, + expect(await events.jsonValue()).toEqual(browserName === 'firefox' ? [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'dragstart at 121;87', + 'mousemove at 241;351', + 'dragenter at 0;0', + 'dragover at 0;0', 'dragend', - 'mouseup', + 'mouseup at 241;351', + ] : [ + 'mousemove at 121;87', + 'mousedown at 121;87', + 'mousemove at 241;351', + 'dragstart at 121;87', + 'dragenter at 241;351', + browserName === 'chromium' ? null : 'dragover at 241;351', + 'dragend', + 'mouseup at 241;351', ].filter(Boolean)); }); @@ -76,9 +155,15 @@ it.describe('Drag and drop', () => { it('should drag into an iframe', async ({ server, page, browserName }) => { await page.goto(server.PREFIX + '/drag-n-drop.html'); const frame = await attachFrame(page, 'oopif', server.PREFIX + '/drag-n-drop.html'); + await page.$eval('iframe', iframe => { + iframe.style.width = '500px'; + iframe.style.height = '600px'; + iframe.style.marginLeft = '500px'; + iframe.style.marginTop = '60px'; + }); + await page.waitForTimeout(5000); const pageEvents = await trackEvents(await page.$('body')); const frameEvents = await trackEvents(await frame.$('body')); - await page.pause(); await page.hover('#source'); await page.mouse.down(); await frame.hover('#target'); @@ -111,6 +196,7 @@ it.describe('Drag and drop', () => { 'mousemove', 'mousedown', 'dragstart', + 'dragend', ]); expect(await pageEvents.jsonValue()).toEqual([ 'dragenter', @@ -210,7 +296,7 @@ it.describe('Drag and drop', () => { await page.mouse.down(); await page.mouse.move(60, 60); await page.mouse.up(); - expect(await eventsHandle.jsonValue()).toEqual(['mousemove', 'mousedown', 'mousemove', 'mouseup']); + expect(await eventsHandle.jsonValue()).toEqual(['mousemove at 20;20', 'mousedown at 20;20', 'mousemove at 50;50', 'mouseup at 50;50']); }); it('should work if a frame is stalled', async ({ page, server, toImpl }) => { @@ -276,20 +362,6 @@ it.describe('Drag and drop', () => { await page.locator('#source').dragTo(page.locator('#target')); expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target }); - - async function trackEvents(target: ElementHandle) { - const eventsHandle = await target.evaluateHandle(target => { - const events: string[] = []; - for (const event of [ - 'mousedown', 'mousemove', 'mouseup', - 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'dragexit', - 'drop' - ]) - target.addEventListener(event, () => events.push(event), false); - return events; - }); - return eventsHandle; - } }); it('should work if not doing a drag', async ({ page }) => { @@ -298,7 +370,7 @@ it('should work if not doing a drag', async ({ page }) => { await page.mouse.down(); await page.mouse.move(100, 100); await page.mouse.up(); - expect(await eventsHandle.jsonValue()).toEqual(['mousemove', 'mousedown', 'mousemove', 'mouseup']); + expect(await eventsHandle.jsonValue()).toEqual(['mousemove at 50;50', 'mousedown at 50;50', 'mousemove at 100;100', 'mouseup at 100;100']); }); it('should report event.buttons', async ({ page, browserName }) => { @@ -338,8 +410,15 @@ async function trackEvents(target: ElementHandle) { 'mousedown', 'mousemove', 'mouseup', 'dragstart', 'dragend', 'dragover', 'dragenter', 'dragleave', 'dragexit', 'drop' - ]) - target.addEventListener(event, () => events.push(event), false); + ]) { + target.addEventListener(event, (e: PointerEvent) => { + // Browsers are all over the place with dragend position. + if (event === 'dragend') + events.push('dragend'); + else + events.push(`${event} at ${e.clientX};${e.clientY}`); + }, false); + } return events; }); return eventsHandle;