mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
feat: implement improved Drag n' Drop APIs (#10651)
This commit is contained in:
parent
67f72de274
commit
9342bac263
@ -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<Element>,
|
||||
target: Point
|
||||
): Promise<Protocol.Input.DragData>;
|
||||
target: Point | ElementHandle<Element>
|
||||
): Promise<Protocol.Input.DragData | void>;
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------------------------------------------------------------ | ----------- |
|
||||
| --------- | --------------------------------------------------------------------------------------------- | ----------- |
|
||||
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||
| target | [Point](./puppeteer.point.md) | |
|
||||
| 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.
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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,7 +12,7 @@ This method triggers a drop on the element.
|
||||
class ElementHandle {
|
||||
drop(
|
||||
this: ElementHandle<Element>,
|
||||
data?: Protocol.Input.DragData
|
||||
element: ElementHandle<Element>
|
||||
): Promise<void>;
|
||||
}
|
||||
```
|
||||
@ -20,9 +20,9 @@ class ElementHandle {
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------------------------------------------------------------ | ------------ |
|
||||
| --------- | ------------------------------------------------------------ | ----------- |
|
||||
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||
| data | Protocol.Input.DragData | _(Optional)_ |
|
||||
| element | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||
|
||||
**Returns:**
|
||||
|
||||
|
31
docs/api/puppeteer.elementhandle.drop_1.md
Normal file
31
docs/api/puppeteer.elementhandle.drop_1.md
Normal file
@ -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<Element>,
|
||||
data?: Protocol.Input.DragData
|
||||
): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ------------------------------------------------------------ | ------------ |
|
||||
| this | [ElementHandle](./puppeteer.elementhandle.md)<Element> | |
|
||||
| data | Protocol.Input.DragData | _(Optional)_ |
|
||||
|
||||
**Returns:**
|
||||
|
||||
Promise<void>
|
@ -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 <code>dragenter</code> event on the element. |
|
||||
| [dragOver(this, data)](./puppeteer.elementhandle.dragover.md) | | This method creates a <code>dragover</code> 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). |
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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<Element>,
|
||||
target: Point
|
||||
): Promise<Protocol.Input.DragData>;
|
||||
async drag(this: ElementHandle<Element>): Promise<Protocol.Input.DragData> {
|
||||
throw new Error('Not implemented');
|
||||
target: Point | ElementHandle<Element>
|
||||
): Promise<Protocol.Input.DragData | void> {
|
||||
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<Element>,
|
||||
data?: Protocol.Input.DragData
|
||||
): Promise<void>;
|
||||
async dragEnter(this: ElementHandle<Element>): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
|
||||
): Promise<void> {
|
||||
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<Element>,
|
||||
data?: Protocol.Input.DragData
|
||||
): Promise<void>;
|
||||
async dragOver(this: ElementHandle<Element>): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
|
||||
): Promise<void> {
|
||||
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>,
|
||||
element: ElementHandle<Element>
|
||||
): Promise<void>;
|
||||
|
||||
/**
|
||||
* @deprecated No longer supported.
|
||||
*/
|
||||
async drop(
|
||||
this: ElementHandle<Element>,
|
||||
data?: Protocol.Input.DragData
|
||||
): Promise<void>;
|
||||
async drop(this: ElementHandle<Element>): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
@throwIfDisposed()
|
||||
@ElementHandle.bindIsolatedHandle
|
||||
async drop(
|
||||
this: ElementHandle<Element>,
|
||||
dataOrElement: ElementHandle<Element> | Protocol.Input.DragData = {
|
||||
items: [],
|
||||
dragOperationsMask: 1,
|
||||
}
|
||||
): Promise<void> {
|
||||
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<Element>,
|
||||
target: ElementHandle<Node>,
|
||||
options?: {delay: number}
|
||||
): Promise<void>;
|
||||
async dragAndDrop(this: ElementHandle<Element>): Promise<void> {
|
||||
throw new Error('Not implemented');
|
||||
): Promise<void> {
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -509,6 +509,11 @@ export abstract class Page
|
||||
extends EventEmitter<PageEvents>
|
||||
implements AsyncDisposable, Disposable
|
||||
{
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_isDragging = false;
|
||||
|
||||
#requestHandlers = new WeakMap<Handler<HTTPRequest>, Handler<HTTPRequest>>();
|
||||
|
||||
/**
|
||||
@ -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<void>;
|
||||
async setDragInterception(): Promise<void> {
|
||||
|
@ -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<Element>,
|
||||
target: Point
|
||||
): Promise<Protocol.Input.DragData> {
|
||||
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<Element>,
|
||||
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
|
||||
): Promise<void> {
|
||||
await this.scrollIntoViewIfNeeded();
|
||||
const target = await this.clickablePoint();
|
||||
await this.#page.mouse.dragEnter(target, data);
|
||||
}
|
||||
|
||||
@throwIfDisposed()
|
||||
@ElementHandle.bindIsolatedHandle
|
||||
override async dragOver(
|
||||
this: CdpElementHandle<Element>,
|
||||
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
|
||||
): Promise<void> {
|
||||
await this.scrollIntoViewIfNeeded();
|
||||
const target = await this.clickablePoint();
|
||||
await this.#page.mouse.dragOver(target, data);
|
||||
}
|
||||
|
||||
@throwIfDisposed()
|
||||
@ElementHandle.bindIsolatedHandle
|
||||
override async drop(
|
||||
this: CdpElementHandle<Element>,
|
||||
data: Protocol.Input.DragData = {items: [], dragOperationsMask: 1}
|
||||
): Promise<void> {
|
||||
await this.scrollIntoViewIfNeeded();
|
||||
const destination = await this.clickablePoint();
|
||||
await this.#page.mouse.drop(destination, data);
|
||||
}
|
||||
|
||||
@throwIfDisposed()
|
||||
@ElementHandle.bindIsolatedHandle
|
||||
override async dragAndDrop(
|
||||
this: CdpElementHandle<Element>,
|
||||
target: CdpElementHandle<Node>,
|
||||
options?: {delay: number}
|
||||
): Promise<void> {
|
||||
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(
|
||||
|
@ -702,6 +702,10 @@ export class BidiPage extends Page {
|
||||
'default' in pptrFunction ? pptrFunction.default : pptrFunction
|
||||
);
|
||||
}
|
||||
|
||||
override isDragInterceptionEnabled(): boolean {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function isConsoleLogEntry(
|
||||
|
@ -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"],
|
||||
|
@ -13,24 +13,21 @@
|
||||
<body>
|
||||
<div id="drag" draggable="true">drag me</div>
|
||||
<div id="drop"></div>
|
||||
<div id="drag-state">0</div>
|
||||
<script>
|
||||
window.didDragStart = false;
|
||||
window.didDragEnter = false;
|
||||
window.didDragOver = false;
|
||||
window.didDrop = false;
|
||||
const drag = document.getElementById('drag');
|
||||
const drop = document.getElementById('drop');
|
||||
drag.addEventListener('dragstart', function(event) {
|
||||
event.dataTransfer.setData('id', event.target.id);
|
||||
window.didDragStart = true;
|
||||
document.getElementById('drag-state').textContent += '1';
|
||||
});
|
||||
drop.addEventListener('dragenter', function(event) {
|
||||
event.preventDefault();
|
||||
window.didDragEnter = true;
|
||||
document.getElementById('drag-state').textContent += '2';
|
||||
});
|
||||
drop.addEventListener('dragover', function(event) {
|
||||
event.preventDefault();
|
||||
window.didDragOver = true;
|
||||
document.getElementById('drag-state').textContent += '3';
|
||||
});
|
||||
drop.addEventListener('drop', function(event) {
|
||||
event.preventDefault();
|
||||
@ -38,7 +35,7 @@
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
event.target.appendChild(el);
|
||||
window.didDrop = true;
|
||||
document.getElementById('drag-state').textContent += '4';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user