diff --git a/docs/api/puppeteer.elementhandle.drag.md b/docs/api/puppeteer.elementhandle.drag.md index 8ae241c97b1..801f4222d40 100644 --- a/docs/api/puppeteer.elementhandle.drag.md +++ b/docs/api/puppeteer.elementhandle.drag.md @@ -4,7 +4,7 @@ sidebar_label: ElementHandle.drag # ElementHandle.drag() method -This method creates and captures a dragevent from the element. +Drags an element over the given element or point. #### Signature: @@ -12,18 +12,20 @@ This method creates and captures a dragevent from the element. class ElementHandle { drag( this: ElementHandle, - target: Point - ): Promise; + target: Point | ElementHandle + ): Promise; } ``` ## Parameters -| Parameter | Type | Description | -| --------- | ------------------------------------------------------------ | ----------- | -| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | -| target | [Point](./puppeteer.point.md) | | +| Parameter | Type | Description | +| --------- | --------------------------------------------------------------------------------------------- | ----------- | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | +| target | [Point](./puppeteer.point.md) \| [ElementHandle](./puppeteer.elementhandle.md)<Element> | | **Returns:** -Promise<Protocol.Input.DragData> +Promise<Protocol.Input.DragData \| void> + +DEPRECATED. When drag interception is enabled, the drag payload is returned. diff --git a/docs/api/puppeteer.elementhandle.draganddrop.md b/docs/api/puppeteer.elementhandle.draganddrop.md index 48e8e3f05ac..7449ff8eaaf 100644 --- a/docs/api/puppeteer.elementhandle.draganddrop.md +++ b/docs/api/puppeteer.elementhandle.draganddrop.md @@ -4,7 +4,9 @@ sidebar_label: ElementHandle.dragAndDrop # ElementHandle.dragAndDrop() method -This method triggers a dragenter, dragover, and drop on the element. +> Warning: This API is now obsolete. +> +> Use `ElementHandle.drop` instead. #### Signature: diff --git a/docs/api/puppeteer.elementhandle.dragenter.md b/docs/api/puppeteer.elementhandle.dragenter.md index c2d620d9f0b..371518b8b55 100644 --- a/docs/api/puppeteer.elementhandle.dragenter.md +++ b/docs/api/puppeteer.elementhandle.dragenter.md @@ -4,7 +4,9 @@ sidebar_label: ElementHandle.dragEnter # ElementHandle.dragEnter() method -This method creates a `dragenter` event on the element. +> Warning: This API is now obsolete. +> +> Do not use. `dragenter` will automatically be performed during dragging. #### Signature: diff --git a/docs/api/puppeteer.elementhandle.dragover.md b/docs/api/puppeteer.elementhandle.dragover.md index 86bbf8d958a..003e8a95eac 100644 --- a/docs/api/puppeteer.elementhandle.dragover.md +++ b/docs/api/puppeteer.elementhandle.dragover.md @@ -4,7 +4,9 @@ sidebar_label: ElementHandle.dragOver # ElementHandle.dragOver() method -This method creates a `dragover` event on the element. +> Warning: This API is now obsolete. +> +> Do not use. `dragover` will automatically be performed during dragging. #### Signature: diff --git a/docs/api/puppeteer.elementhandle.drop.md b/docs/api/puppeteer.elementhandle.drop.md index 82536f4c19a..a48303e108c 100644 --- a/docs/api/puppeteer.elementhandle.drop.md +++ b/docs/api/puppeteer.elementhandle.drop.md @@ -4,7 +4,7 @@ sidebar_label: ElementHandle.drop # ElementHandle.drop() method -This method triggers a drop on the element. +Drops the given element onto the current one. #### Signature: @@ -12,17 +12,17 @@ This method triggers a drop on the element. class ElementHandle { drop( this: ElementHandle, - data?: Protocol.Input.DragData + element: ElementHandle ): Promise; } ``` ## Parameters -| Parameter | Type | Description | -| --------- | ------------------------------------------------------------ | ------------ | -| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | -| data | Protocol.Input.DragData | _(Optional)_ | +| Parameter | Type | Description | +| --------- | ------------------------------------------------------------ | ----------- | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | +| element | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | **Returns:** diff --git a/docs/api/puppeteer.elementhandle.drop_1.md b/docs/api/puppeteer.elementhandle.drop_1.md new file mode 100644 index 00000000000..cae89f8de0f --- /dev/null +++ b/docs/api/puppeteer.elementhandle.drop_1.md @@ -0,0 +1,31 @@ +--- +sidebar_label: ElementHandle.drop_1 +--- + +# ElementHandle.drop() method + +> Warning: This API is now obsolete. +> +> No longer supported. + +#### Signature: + +```typescript +class ElementHandle { + drop( + this: ElementHandle, + data?: Protocol.Input.DragData + ): Promise; +} +``` + +## Parameters + +| Parameter | Type | Description | +| --------- | ------------------------------------------------------------ | ------------ | +| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | | +| data | Protocol.Input.DragData | _(Optional)_ | + +**Returns:** + +Promise<void> diff --git a/docs/api/puppeteer.elementhandle.md b/docs/api/puppeteer.elementhandle.md index 495ec5142e8..a247ff59479 100644 --- a/docs/api/puppeteer.elementhandle.md +++ b/docs/api/puppeteer.elementhandle.md @@ -61,11 +61,12 @@ The constructor for this class is marked as internal. Third-party code should no | [clickablePoint(offset)](./puppeteer.elementhandle.clickablepoint.md) | | Returns the middle point within an element unless a specific offset is provided. | | [contentFrame(this)](./puppeteer.elementhandle.contentframe.md) | | Resolves the frame associated with the element, if any. Always exists for HTMLIFrameElements. | | [contentFrame()](./puppeteer.elementhandle.contentframe_1.md) | | | -| [drag(this, target)](./puppeteer.elementhandle.drag.md) | | This method creates and captures a dragevent from the element. | -| [dragAndDrop(this, target, options)](./puppeteer.elementhandle.draganddrop.md) | | This method triggers a dragenter, dragover, and drop on the element. | -| [dragEnter(this, data)](./puppeteer.elementhandle.dragenter.md) | | This method creates a dragenter event on the element. | -| [dragOver(this, data)](./puppeteer.elementhandle.dragover.md) | | This method creates a dragover event on the element. | -| [drop(this, data)](./puppeteer.elementhandle.drop.md) | | This method triggers a drop on the element. | +| [drag(this, target)](./puppeteer.elementhandle.drag.md) | | Drags an element over the given element or point. | +| [dragAndDrop(this, target, options)](./puppeteer.elementhandle.draganddrop.md) | | | +| [dragEnter(this, data)](./puppeteer.elementhandle.dragenter.md) | | | +| [dragOver(this, data)](./puppeteer.elementhandle.dragover.md) | | | +| [drop(this, element)](./puppeteer.elementhandle.drop.md) | | Drops the given element onto the current one. | +| [drop(this, data)](./puppeteer.elementhandle.drop_1.md) | | | | [focus()](./puppeteer.elementhandle.focus.md) | | Calls [focus](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus) on the element. | | [hover(this)](./puppeteer.elementhandle.hover.md) | | This method scrolls element into view if needed, and then uses [Page](./puppeteer.page.md) to hover over the center of the element. If the element is detached from DOM, the method throws an error. | | [isHidden()](./puppeteer.elementhandle.ishidden.md) | | Checks if an element is hidden using the same mechanism as [ElementHandle.waitForSelector()](./puppeteer.elementhandle.waitforselector.md). | diff --git a/docs/api/puppeteer.page.isdraginterceptionenabled.md b/docs/api/puppeteer.page.isdraginterceptionenabled.md index ff01da1cd6f..b04eda2bf22 100644 --- a/docs/api/puppeteer.page.isdraginterceptionenabled.md +++ b/docs/api/puppeteer.page.isdraginterceptionenabled.md @@ -4,6 +4,10 @@ sidebar_label: Page.isDragInterceptionEnabled # Page.isDragInterceptionEnabled() method +> Warning: This API is now obsolete. +> +> We no longer support intercepting drag payloads. Use the new drag APIs found on [ElementHandle](./puppeteer.elementhandle.md) to drag (or just use the [Page.mouse](./puppeteer.page.mouse.md)). + `true` if drag events are being intercepted, `false` otherwise. #### Signature: diff --git a/docs/api/puppeteer.page.setdraginterception.md b/docs/api/puppeteer.page.setdraginterception.md index 60ee774eeca..219e271af6d 100644 --- a/docs/api/puppeteer.page.setdraginterception.md +++ b/docs/api/puppeteer.page.setdraginterception.md @@ -4,6 +4,10 @@ sidebar_label: Page.setDragInterception # Page.setDragInterception() method +> Warning: This API is now obsolete. +> +> We no longer support intercepting drag payloads. Use the new drag APIs found on [ElementHandle](./puppeteer.elementhandle.md) to drag (or just use the [Page.mouse](./puppeteer.page.mouse.md)). + #### Signature: ```typescript @@ -21,7 +25,3 @@ class Page { **Returns:** Promise<void> - -## Remarks - -Activating drag interception enables the `Input.drag`, methods This provides the capability to capture drag events emitted on the page, which can then be used to simulate drag-and-drop. diff --git a/packages/puppeteer-core/src/api/ElementHandle.ts b/packages/puppeteer-core/src/api/ElementHandle.ts index 5e9ccd16043..f7d5479a3bb 100644 --- a/packages/puppeteer-core/src/api/ElementHandle.ts +++ b/packages/puppeteer-core/src/api/ElementHandle.ts @@ -31,6 +31,7 @@ import {KeyInput} from '../common/USKeyboardLayout.js'; import {isString, withSourcePuppeteerURLIfNone} from '../common/util.js'; import {assert} from '../util/assert.js'; import {AsyncIterableUtil} from '../util/AsyncIterableUtil.js'; +import {throwIfDisposed} from '../util/decorators.js'; import { KeyboardTypeOptions, @@ -731,59 +732,134 @@ export abstract class ElementHandle< } /** - * This method creates and captures a dragevent from the element. + * Drags an element over the given element or point. + * + * @returns DEPRECATED. When drag interception is enabled, the drag payload is + * returned. */ + @throwIfDisposed() + @ElementHandle.bindIsolatedHandle async drag( this: ElementHandle, - target: Point - ): Promise; - async drag(this: ElementHandle): Promise { - throw new Error('Not implemented'); + target: Point | ElementHandle + ): Promise { + await this.scrollIntoViewIfNeeded(); + const page = this.frame.page(); + if (page.isDragInterceptionEnabled()) { + const source = await this.clickablePoint(); + if (target instanceof ElementHandle) { + target = await target.clickablePoint(); + } + return await page.mouse.drag(source, target); + } + try { + if (!page._isDragging) { + page._isDragging = true; + await this.hover(); + await page.mouse.down(); + } + if (target instanceof ElementHandle) { + await target.hover(); + } else { + await page.mouse.move(target.x, target.y); + } + } catch (error) { + page._isDragging = false; + throw error; + } } /** - * This method creates a `dragenter` event on the element. + * @deprecated Do not use. `dragenter` will automatically be performed during dragging. */ + @throwIfDisposed() + @ElementHandle.bindIsolatedHandle async dragEnter( this: ElementHandle, - data?: Protocol.Input.DragData - ): Promise; - async dragEnter(this: ElementHandle): Promise { - throw new Error('Not implemented'); + data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} + ): Promise { + const page = this.frame.page(); + await this.scrollIntoViewIfNeeded(); + const target = await this.clickablePoint(); + await page.mouse.dragEnter(target, data); } /** - * This method creates a `dragover` event on the element. + * @deprecated Do not use. `dragover` will automatically be performed during dragging. */ + @throwIfDisposed() + @ElementHandle.bindIsolatedHandle async dragOver( this: ElementHandle, - data?: Protocol.Input.DragData - ): Promise; - async dragOver(this: ElementHandle): Promise { - throw new Error('Not implemented'); + data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} + ): Promise { + const page = this.frame.page(); + await this.scrollIntoViewIfNeeded(); + const target = await this.clickablePoint(); + await page.mouse.dragOver(target, data); } /** - * This method triggers a drop on the element. + * Drops the given element onto the current one. + */ + async drop( + this: ElementHandle, + element: ElementHandle + ): Promise; + + /** + * @deprecated No longer supported. */ async drop( this: ElementHandle, data?: Protocol.Input.DragData ): Promise; - async drop(this: ElementHandle): Promise { - throw new Error('Not implemented'); + + /** + * @internal + */ + @throwIfDisposed() + @ElementHandle.bindIsolatedHandle + async drop( + this: ElementHandle, + dataOrElement: ElementHandle | Protocol.Input.DragData = { + items: [], + dragOperationsMask: 1, + } + ): Promise { + const page = this.frame.page(); + if ('items' in dataOrElement) { + await this.scrollIntoViewIfNeeded(); + const destination = await this.clickablePoint(); + await page.mouse.drop(destination, dataOrElement); + } else { + // Note if the rest errors, we still want dragging off because the errors + // is most likely something implying the mouse is no longer dragging. + await dataOrElement.drag(this); + page._isDragging = false; + await page.mouse.up(); + } } /** - * This method triggers a dragenter, dragover, and drop on the element. + * @deprecated Use `ElementHandle.drop` instead. */ + @throwIfDisposed() + @ElementHandle.bindIsolatedHandle async dragAndDrop( this: ElementHandle, target: ElementHandle, options?: {delay: number} - ): Promise; - async dragAndDrop(this: ElementHandle): Promise { - throw new Error('Not implemented'); + ): Promise { + const page = this.frame.page(); + assert( + page.isDragInterceptionEnabled(), + 'Drag Interception is not enabled!' + ); + await this.scrollIntoViewIfNeeded(); + const startPoint = await this.clickablePoint(); + const targetPoint = await target.clickablePoint(); + await page.mouse.dragAndDrop(startPoint, targetPoint, options); } /** diff --git a/packages/puppeteer-core/src/api/Page.ts b/packages/puppeteer-core/src/api/Page.ts index ae0fb49f275..16bf050d695 100644 --- a/packages/puppeteer-core/src/api/Page.ts +++ b/packages/puppeteer-core/src/api/Page.ts @@ -509,6 +509,11 @@ export abstract class Page extends EventEmitter implements AsyncDisposable, Disposable { + /** + * @internal + */ + _isDragging = false; + #requestHandlers = new WeakMap, Handler>(); /** @@ -527,6 +532,10 @@ export abstract class Page /** * `true` if drag events are being intercepted, `false` otherwise. + * + * @deprecated We no longer support intercepting drag payloads. Use the new + * drag APIs found on {@link ElementHandle} to drag (or just use the + * {@link Page.mouse}). */ isDragInterceptionEnabled(): boolean { throw new Error('Not implemented'); @@ -791,10 +800,9 @@ export abstract class Page /** * @param enabled - Whether to enable drag interception. * - * @remarks - * Activating drag interception enables the `Input.drag`, - * methods This provides the capability to capture drag events emitted - * on the page, which can then be used to simulate drag-and-drop. + * @deprecated We no longer support intercepting drag payloads. Use the new + * drag APIs found on {@link ElementHandle} to drag (or just use the + * {@link Page.mouse}). */ async setDragInterception(enabled: boolean): Promise; async setDragInterception(): Promise { diff --git a/packages/puppeteer-core/src/common/ElementHandle.ts b/packages/puppeteer-core/src/common/ElementHandle.ts index 9c6f2baa001..d5f5389a17a 100644 --- a/packages/puppeteer-core/src/common/ElementHandle.ts +++ b/packages/puppeteer-core/src/common/ElementHandle.ts @@ -17,7 +17,7 @@ import {Protocol} from 'devtools-protocol'; import {CDPSession} from '../api/CDPSession.js'; -import {AutofillData, ElementHandle, Point} from '../api/ElementHandle.js'; +import {AutofillData, ElementHandle} from '../api/ElementHandle.js'; import {Page, ScreenshotOptions} from '../api/Page.js'; import {assert} from '../util/assert.js'; import {throwIfDisposed} from '../util/decorators.js'; @@ -103,74 +103,6 @@ export class CdpElementHandle< } } - /** - * This method creates and captures a dragevent from the element. - */ - @throwIfDisposed() - @ElementHandle.bindIsolatedHandle - override async drag( - this: CdpElementHandle, - target: Point - ): Promise { - assert( - this.#page.isDragInterceptionEnabled(), - 'Drag Interception is not enabled!' - ); - await this.scrollIntoViewIfNeeded(); - const start = await this.clickablePoint(); - return await this.#page.mouse.drag(start, target); - } - - @throwIfDisposed() - @ElementHandle.bindIsolatedHandle - override async dragEnter( - this: CdpElementHandle, - data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} - ): Promise { - await this.scrollIntoViewIfNeeded(); - const target = await this.clickablePoint(); - await this.#page.mouse.dragEnter(target, data); - } - - @throwIfDisposed() - @ElementHandle.bindIsolatedHandle - override async dragOver( - this: CdpElementHandle, - data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} - ): Promise { - await this.scrollIntoViewIfNeeded(); - const target = await this.clickablePoint(); - await this.#page.mouse.dragOver(target, data); - } - - @throwIfDisposed() - @ElementHandle.bindIsolatedHandle - override async drop( - this: CdpElementHandle, - data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1} - ): Promise { - await this.scrollIntoViewIfNeeded(); - const destination = await this.clickablePoint(); - await this.#page.mouse.drop(destination, data); - } - - @throwIfDisposed() - @ElementHandle.bindIsolatedHandle - override async dragAndDrop( - this: CdpElementHandle, - target: CdpElementHandle, - options?: {delay: number} - ): Promise { - assert( - this.#page.isDragInterceptionEnabled(), - 'Drag Interception is not enabled!' - ); - await this.scrollIntoViewIfNeeded(); - const startPoint = await this.clickablePoint(); - const targetPoint = await target.clickablePoint(); - await this.#page.mouse.dragAndDrop(startPoint, targetPoint, options); - } - @throwIfDisposed() @ElementHandle.bindIsolatedHandle override async uploadFile( diff --git a/packages/puppeteer-core/src/common/bidi/Page.ts b/packages/puppeteer-core/src/common/bidi/Page.ts index af31fbfd0b6..27832648249 100644 --- a/packages/puppeteer-core/src/common/bidi/Page.ts +++ b/packages/puppeteer-core/src/common/bidi/Page.ts @@ -702,6 +702,10 @@ export class BidiPage extends Page { 'default' in pptrFunction ? pptrFunction.default : pptrFunction ); } + + override isDragInterceptionEnabled(): boolean { + return false; + } } function isConsoleLogEntry( diff --git a/test/TestExpectations.json b/test/TestExpectations.json index cb7e2127ca8..2a405121e06 100644 --- a/test/TestExpectations.json +++ b/test/TestExpectations.json @@ -41,6 +41,24 @@ "parameters": ["webDriverBiDi"], "expectations": ["PASS"] }, + { + "testIdPattern": "[drag-and-drop.spec] *", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["webDriverBiDi"], + "expectations": ["PASS"] + }, + { + "testIdPattern": "[drag-and-drop.spec] *", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["firefox"], + "expectations": ["FAIL"] + }, + { + "testIdPattern": "[drag-and-drop.spec] Legacy Drag n' Drop *", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["webDriverBiDi"], + "expectations": ["SKIP"] + }, { "testIdPattern": "[elementhandle.spec] *", "platforms": ["darwin", "linux", "win32"], @@ -1691,6 +1709,12 @@ "parameters": ["cdp", "firefox"], "expectations": ["FAIL"] }, + { + "testIdPattern": "[drag-and-drop.spec] Drag n' Drop should drag and drop", + "platforms": ["darwin", "linux", "win32"], + "parameters": ["cdp", "chrome"], + "expectations": ["FAIL"] + }, { "testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.boundingBox should handle nested frames", "platforms": ["darwin", "linux", "win32"], diff --git a/test/assets/input/drag-and-drop.html b/test/assets/input/drag-and-drop.html index bc376a50451..b77870c4ad8 100644 --- a/test/assets/input/drag-and-drop.html +++ b/test/assets/input/drag-and-drop.html @@ -13,24 +13,21 @@
drag me
+
0
diff --git a/test/src/drag-and-drop.spec.ts b/test/src/drag-and-drop.spec.ts index 103cee81d7f..1b38f31e391 100644 --- a/test/src/drag-and-drop.spec.ts +++ b/test/src/drag-and-drop.spec.ts @@ -14,11 +14,23 @@ * limitations under the License. */ +import assert from 'assert'; + import expect from 'expect'; import {getTestState, setupTestBrowserHooks} from './mocha-utils.js'; -describe('Input.drag', function () { +async function getDragState() { + const {page} = await getTestState({skipLaunch: true}); + return parseInt( + await page.$eval('#drag-state', element => { + return element.innerHTML; + }), + 10 + ); +} + +describe("Legacy Drag n' Drop", function () { setupTestBrowserHooks(); it('should throw an exception if not enabled before usage', async () => { @@ -45,12 +57,9 @@ describe('Input.drag', function () { using draggable = (await page.$('#drag'))!; const data = await draggable.drag({x: 1, y: 1}); + assert(data instanceof Object); expect(data.items).toHaveLength(1); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragStart; - }) - ).toBe(true); + expect(await getDragState()).toBe(1); }); it('should emit a dragEnter', async () => { const {page, server} = await getTestState(); @@ -61,19 +70,11 @@ describe('Input.drag', function () { expect(page.isDragInterceptionEnabled()).toBe(true); using draggable = (await page.$('#drag'))!; const data = await draggable.drag({x: 1, y: 1}); + assert(data instanceof Object); using dropzone = (await page.$('#drop'))!; await dropzone.dragEnter(data); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragStart; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragEnter; - }) - ).toBe(true); + expect(await getDragState()).toBe(12); }); it('should emit a dragOver event', async () => { const {page, server} = await getTestState(); @@ -84,25 +85,12 @@ describe('Input.drag', function () { expect(page.isDragInterceptionEnabled()).toBe(true); using draggable = (await page.$('#drag'))!; const data = await draggable.drag({x: 1, y: 1}); + assert(data instanceof Object); using dropzone = (await page.$('#drop'))!; await dropzone.dragEnter(data); await dropzone.dragOver(data); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragStart; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragEnter; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragOver; - }) - ).toBe(true); + expect(await getDragState()).toBe(123); }); it('can be dropped', async () => { const {page, server} = await getTestState(); @@ -114,30 +102,12 @@ describe('Input.drag', function () { using draggable = (await page.$('#drag'))!; using dropzone = (await page.$('#drop'))!; const data = await draggable.drag({x: 1, y: 1}); + assert(data instanceof Object); await dropzone.dragEnter(data); await dropzone.dragOver(data); await dropzone.drop(data); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragStart; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragEnter; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragOver; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDrop; - }) - ).toBe(true); + expect(await getDragState()).toBe(12334); }); it('can be dragged and dropped with a single function', async () => { const {page, server} = await getTestState(); @@ -150,44 +120,59 @@ describe('Input.drag', function () { using dropzone = (await page.$('#drop'))!; await draggable.dragAndDrop(dropzone); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragStart; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragEnter; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDragOver; - }) - ).toBe(true); - expect( - await page.evaluate(() => { - return (globalThis as any).didDrop; - }) - ).toBe(true); + expect(await getDragState()).toBe(12334); }); - it('can be disabled', async () => { +}); + +describe("Drag n' Drop", () => { + setupTestBrowserHooks(); + + it('should drop', async () => { const {page, server} = await getTestState(); await page.goto(server.PREFIX + '/input/drag-and-drop.html'); - expect(page.isDragInterceptionEnabled()).toBe(false); - await page.setDragInterception(true); - expect(page.isDragInterceptionEnabled()).toBe(true); - using draggable = (await page.$('#drag'))!; - await draggable.drag({x: 1, y: 1}); - await page.setDragInterception(false); - try { - await draggable.drag({x: 1, y: 1}); - } catch (error) { - expect((error as Error).message).toContain( - 'Drag Interception is not enabled!' - ); - } + using draggable = await page.$('#drag'); + assert(draggable); + using dropzone = await page.$('#drop'); + assert(dropzone); + + await dropzone.drop(draggable); + + expect(await getDragState()).toBe(1234); + }); + it('should drop using mouse', async () => { + const {page, server} = await getTestState(); + + await page.goto(server.PREFIX + '/input/drag-and-drop.html'); + + using draggable = await page.$('#drag'); + assert(draggable); + using dropzone = await page.$('#drop'); + assert(dropzone); + + await draggable.hover(); + await page.mouse.down(); + await dropzone.hover(); + + expect(await getDragState()).toBe(123); + + await page.mouse.up(); + expect(await getDragState()).toBe(1234); + }); + it('should drag and drop', async () => { + const {page, server} = await getTestState(); + + await page.goto(server.PREFIX + '/input/drag-and-drop.html'); + + using draggable = await page.$('#drag'); + assert(draggable); + using dropzone = await page.$('#drop'); + assert(dropzone); + + await draggable.drag(dropzone); + await dropzone.drop(draggable); + + expect(await getDragState()).toBe(1234); }); });