From c6d5bc3081845911475e36e20617a2c17e10a350 Mon Sep 17 00:00:00 2001 From: Joel Einbinder Date: Wed, 25 Nov 2020 03:29:20 -0800 Subject: [PATCH] test(drag): more tests for drag and drop (#4508) --- test/assets/drag-n-drop.html | 1 - test/drag.spec.ts | 161 +++++++++++++++++++++++++++++++++++ test/mouse.spec.ts | 13 +-- 3 files changed, 162 insertions(+), 13 deletions(-) create mode 100644 test/drag.spec.ts diff --git a/test/assets/drag-n-drop.html b/test/assets/drag-n-drop.html index 8189c49257..f43583e7c9 100644 --- a/test/assets/drag-n-drop.html +++ b/test/assets/drag-n-drop.html @@ -28,7 +28,6 @@ function drop_handler(ev) { ev.preventDefault(); var data = ev.dataTransfer.getData("text"); ev.target.appendChild(document.getElementById(data)); - ev.dataTransfer.clearData(); } diff --git a/test/drag.spec.ts b/test/drag.spec.ts new file mode 100644 index 0000000000..6c665c3b33 --- /dev/null +++ b/test/drag.spec.ts @@ -0,0 +1,161 @@ +/** + * Copyright (c) Microsoft Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ElementHandle } from '..'; +import { it, expect, describe } from './fixtures'; +import { attachFrame } from './utils'; + +describe('Drag and drop', test => { + test.fixme(); +}, () => { + it('should work', async ({server, page, context}) => { + await page.goto(server.PREFIX + '/drag-n-drop.html'); + await page.hover('#source'); + await page.mouse.down(); + await page.hover('#target'); + await page.mouse.up(); + expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target + }); + + it('should send the right events', async ({server, page, isFirefox}) => { + 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'); + await page.mouse.up(); + expect(await events.jsonValue()).toEqual([ + 'mousemove', + 'mousedown', + isFirefox ? 'dragstart' : 'mousemove', + isFirefox ? 'mousemove' : 'dragstart', + 'dragenter', + 'dragover', + 'drop', + 'dragend', + ]); + }); + + it('should cancel on escape', async ({server, page, isFirefox}) => { + 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'); + 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', + isFirefox ? 'dragstart' : 'mousemove', + isFirefox ? 'mousemove' : 'dragstart', + 'dragenter', + 'dragover', + 'dragend', + 'mouseup', + ]); + }); + + it('should drag into an iframe', async ({server, page, isFirefox}) => { + await page.goto(server.PREFIX + '/drag-n-drop.html'); + const frame = await attachFrame(page, 'oopif',server.CROSS_PROCESS_PREFIX + '/drag-n-drop.html'); + const pageEvents = await trackEvents(await page.$('body')); + const frameEvents = await trackEvents(await frame.$('body')); + await page.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 pageEvents.jsonValue()).toEqual([ + 'mousemove', + 'mousedown', + isFirefox ? 'dragstart' : 'mousemove', + isFirefox ? 'mousemove' : 'dragstart', + ]); + expect(await frameEvents.jsonValue()).toEqual([ + 'dragenter', + 'dragover', + 'drop', + ]); + }); + + it('should drag out of an iframe', async ({server, page}) => { + await page.goto(server.PREFIX + '/drag-n-drop.html'); + const frame = await attachFrame(page, 'oopif',server.CROSS_PROCESS_PREFIX + '/drag-n-drop.html'); + const pageEvents = await trackEvents(await page.$('body')); + const frameEvents = await trackEvents(await frame.$('body')); + await frame.hover('#source'); + await page.mouse.down(); + await page.hover('#target'); + await page.mouse.up(); + expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target + expect(await frameEvents.jsonValue()).toEqual([ + 'mousemove', + 'mousedown', + 'dragstart', + ]); + expect(await pageEvents.jsonValue()).toEqual([ + 'dragenter', + 'dragover', + 'drop', + ]); + }); + + it('should drag through a navigation', async ({server, page, isFirefox}) => { + await page.goto(server.PREFIX + '/drag-n-drop.html'); + const beforeNavigationEvents = await trackEvents(await page.$('body')); + await page.hover('#source'); + await page.mouse.down(); + // start the drag + await page.mouse.move(50, 50); + + expect(await beforeNavigationEvents.jsonValue()).toEqual([ + 'mousemove', + 'mousedown', + isFirefox ? 'dragstart' : 'mousemove', + isFirefox ? 'mousemove' : 'dragstart', + 'dragenter', + 'dragover', + ]); + + await page.reload(); + const afterNavigationEvents = await trackEvents(await page.$('body')); + + await page.hover('#target'); + await page.mouse.up(); + + expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target + expect(await afterNavigationEvents.jsonValue()).toEqual([ + 'dragenter', + 'dragover', + 'drop', + ]); + }); + + 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; + } +}); diff --git a/test/mouse.spec.ts b/test/mouse.spec.ts index a240a7afeb..6ad9b621a6 100644 --- a/test/mouse.spec.ts +++ b/test/mouse.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { it, expect, describe } from './fixtures'; +import { it, expect } from './fixtures'; function dimensions() { const rect = document.querySelector('textarea').getBoundingClientRect(); @@ -184,14 +184,3 @@ it('should work with mobile viewports and cross process navigations', (test, { b expect(await page.evaluate('result')).toEqual({x: 30, y: 40}); await context.close(); }); - -describe.skip('Drag and Drop', function() { - it('should work', async ({server, page}) => { - await page.goto(server.PREFIX + '/drag-n-drop.html'); - await page.hover('#source'); - await page.mouse.down(); - await page.hover('#target'); - await page.mouse.up(); - expect(await page.$eval('#target', target => target.contains(document.querySelector('#source')))).toBe(true); // could not find source in target - }); -});