mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-01 08:34:02 +03:00
api(dispatchEvent): page, frame and handle versions added (#1932)
This commit is contained in:
parent
671cfa0a54
commit
c1c0237d4e
100
docs/api.md
100
docs/api.md
@ -674,6 +674,7 @@ page.removeListener('request', logRequest);
|
||||
- [page.context()](#pagecontext)
|
||||
- [page.coverage](#pagecoverage)
|
||||
- [page.dblclick(selector[, options])](#pagedblclickselector-options)
|
||||
- [page.dispatchEvent(selector, type[, eventInit, options])](#pagedispatcheventselector-type-eventinit-options)
|
||||
- [page.emulateMedia(options)](#pageemulatemediaoptions)
|
||||
- [page.evaluate(pageFunction[, arg])](#pageevaluatepagefunction-arg)
|
||||
- [page.evaluateHandle(pageFunction[, arg])](#pageevaluatehandlepagefunction-arg)
|
||||
@ -1040,6 +1041,40 @@ Bear in mind that if the first click of the `dblclick()` triggers a navigation e
|
||||
|
||||
Shortcut for [page.mainFrame().dblclick(selector[, options])](#framedblclickselector-options).
|
||||
|
||||
|
||||
#### page.dispatchEvent(selector, type[, eventInit, options])
|
||||
- `selector` <[string]> A selector to search for element to use. If there are multiple elements satisfying the selector, the first will be used.
|
||||
- `type` <[string]> DOM event type: `"click"`, `"dragstart"`, etc.
|
||||
- `eventInit` <[Object]> event-specific initialization properties.
|
||||
- `options` <[Object]>
|
||||
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
|
||||
- returns: <[Promise]>
|
||||
|
||||
The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click` is dispatched. This is equivalend to calling [`element.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
||||
|
||||
```js
|
||||
await page.dispatchEvent('button#submit', 'click');
|
||||
```
|
||||
|
||||
Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
|
||||
|
||||
Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
|
||||
- [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
|
||||
- [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
|
||||
- [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
|
||||
- [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
|
||||
- [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
|
||||
- [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
|
||||
- [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
|
||||
|
||||
You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
|
||||
|
||||
```js
|
||||
// Note you can only create DataTransfer in Chromium and Firefox
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
||||
```
|
||||
|
||||
#### page.emulateMedia(options)
|
||||
- `options` <[Object]>
|
||||
- `media` <"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation.
|
||||
@ -1894,6 +1929,7 @@ An example of getting text from an iframe element:
|
||||
- [frame.click(selector[, options])](#frameclickselector-options)
|
||||
- [frame.content()](#framecontent)
|
||||
- [frame.dblclick(selector[, options])](#framedblclickselector-options)
|
||||
- [frame.dispatchEvent(selector, type[, eventInit, options])](#framedispatcheventselector-type-eventinit-options)
|
||||
- [frame.evaluate(pageFunction[, arg])](#frameevaluatepagefunction-arg)
|
||||
- [frame.evaluateHandle(pageFunction[, arg])](#frameevaluatehandlepagefunction-arg)
|
||||
- [frame.fill(selector, value[, options])](#framefillselector-value-options)
|
||||
@ -2052,6 +2088,39 @@ Bear in mind that if the first click of the `dblclick()` triggers a navigation e
|
||||
|
||||
> **NOTE** `frame.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
||||
|
||||
#### frame.dispatchEvent(selector, type[, eventInit, options])
|
||||
- `selector` <[string]> A selector to search for element to double click. If there are multiple elements satisfying the selector, the first will be double clicked.
|
||||
- `type` <[string]> DOM event type: `"click"`, `"dragstart"`, etc.
|
||||
- `eventInit` <[Object]> event-specific initialization properties.
|
||||
- `options` <[Object]>
|
||||
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods.
|
||||
- returns: <[Promise]>
|
||||
|
||||
The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click` is dispatched. This is equivalend to calling [`element.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
||||
|
||||
```js
|
||||
await frame.dispatchEvent('button#submit', 'click');
|
||||
```
|
||||
|
||||
Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
|
||||
|
||||
Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
|
||||
- [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
|
||||
- [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
|
||||
- [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
|
||||
- [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
|
||||
- [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
|
||||
- [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
|
||||
- [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
|
||||
|
||||
You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
|
||||
|
||||
```js
|
||||
// Note you can only create DataTransfer in Chromium and Firefox
|
||||
const dataTransfer = await frame.evaluateHandle(() => new DataTransfer());
|
||||
await frame.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
||||
```
|
||||
|
||||
#### frame.evaluate(pageFunction[, arg])
|
||||
- `pageFunction` <[function]|[string]> Function to be evaluated in browser context
|
||||
- `arg` <[Serializable]|[JSHandle]> Optional argument to pass to `pageFunction`
|
||||
@ -2477,6 +2546,7 @@ ElementHandle instances can be used as an argument in [`page.$eval()`](#pageeval
|
||||
- [elementHandle.click([options])](#elementhandleclickoptions)
|
||||
- [elementHandle.contentFrame()](#elementhandlecontentframe)
|
||||
- [elementHandle.dblclick([options])](#elementhandledblclickoptions)
|
||||
- [elementHandle.dispatchEvent(type[, eventInit])](#elementhandledispatcheventtype-eventinit)
|
||||
- [elementHandle.fill(value[, options])](#elementhandlefillvalue-options)
|
||||
- [elementHandle.focus()](#elementhandlefocus)
|
||||
- [elementHandle.getAttribute(name)](#elementhandlegetattributename)
|
||||
@ -2626,6 +2696,36 @@ Bear in mind that if the first click of the `dblclick()` triggers a navigation e
|
||||
|
||||
> **NOTE** `elementHandle.dblclick()` dispatches two `click` events and a single `dblclick` event.
|
||||
|
||||
#### elementHandle.dispatchEvent(type[, eventInit])
|
||||
- `type` <[string]> DOM event type: `"click"`, `"dragstart"`, etc.
|
||||
- `eventInit` <[Object]> event-specific initialization properties.
|
||||
- returns: <[Promise]>
|
||||
|
||||
The snippet below dispatches the `click` event on the element. Regardless of the visibility state of the elment, `click` is dispatched. This is equivalend to calling [`element.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click).
|
||||
|
||||
```js
|
||||
await elementHandle.dispatchEvent('click');
|
||||
```
|
||||
|
||||
Under the hood, it creates an instance of an event based on the given `type`, initializes it with `eventInit` properties and dispatches it on the element. Events are `composed`, `cancelable` and bubble by default.
|
||||
|
||||
Since `eventInit` is event-specific, please refer to the events documentation for the lists of initial properties:
|
||||
- [DragEvent](https://developer.mozilla.org/en-US/docs/Web/API/DragEvent/DragEvent)
|
||||
- [FocusEvent](https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/FocusEvent)
|
||||
- [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/KeyboardEvent)
|
||||
- [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent)
|
||||
- [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/PointerEvent)
|
||||
- [TouchEvent](https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/TouchEvent)
|
||||
- [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event/Event)
|
||||
|
||||
You can also specify `JSHandle` as the property value if you want live objects to be passed into the event:
|
||||
|
||||
```js
|
||||
// Note you can only create DataTransfer in Chromium and Firefox
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await elementHandle.dispatchEvent('dragstart', { dataTransfer });
|
||||
```
|
||||
|
||||
#### elementHandle.fill(value[, options])
|
||||
- `value` <[string]> Value to set for the `<input>`, `<textarea>` or `[contenteditable]` element.
|
||||
- `options` <[Object]>
|
||||
|
10
src/dom.ts
10
src/dom.ts
@ -94,6 +94,11 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
return this;
|
||||
}
|
||||
|
||||
async _evaluateInMain<R, Arg>(pageFunction: types.FuncOn<{ injected: Injected, node: T }, Arg, R>, arg: Arg): Promise<R> {
|
||||
const main = await this._context.frame._mainContext();
|
||||
return main._doEvaluateInternal(true /* returnByValue */, true /* waitForNavigations */, pageFunction, { injected: await main._injected(), node: this }, arg);
|
||||
}
|
||||
|
||||
async _evaluateInUtility<R, Arg>(pageFunction: types.FuncOn<{ injected: Injected, node: T }, Arg, R>, arg: Arg): Promise<R> {
|
||||
const utility = await this._context.frame._utilityContext();
|
||||
return utility._doEvaluateInternal(true /* returnByValue */, true /* waitForNavigations */, pageFunction, { injected: await utility._injected(), node: this }, arg);
|
||||
@ -152,6 +157,11 @@ export class ElementHandle<T extends Node = Node> extends js.JSHandle<T> {
|
||||
}, {});
|
||||
}
|
||||
|
||||
async dispatchEvent(type: string, eventInit: Object = {}) {
|
||||
await this._evaluateInMain(({ injected, node }, { type, eventInit }) =>
|
||||
injected.dispatchEvent(node, type, eventInit), { type, eventInit });
|
||||
}
|
||||
|
||||
async _scrollRectIntoViewIfNeeded(rect?: types.Rect): Promise<void> {
|
||||
this._page._log(inputLog, 'scrolling into view if needed...');
|
||||
await this._page._delegate.scrollRectIntoViewIfNeeded(this, rect);
|
||||
|
@ -454,6 +454,13 @@ export class Frame {
|
||||
return handle;
|
||||
}
|
||||
|
||||
async dispatchEvent(selector: string, type: string, eventInit?: Object, options?: types.TimeoutOptions): Promise<void> {
|
||||
const deadline = this._page._timeoutSettings.computeDeadline(options);
|
||||
const task = selectors._dispatchEventTask(selector, type, eventInit || {}, deadline);
|
||||
const result = await this._scheduleRerunnableTask(task, 'main', deadline, `selector "${selectorToString(selector, 'attached')}"`);
|
||||
result.dispose();
|
||||
}
|
||||
|
||||
async $eval<R, Arg>(selector: string, pageFunction: types.FuncOn<Element, Arg, R>, arg: Arg): Promise<R>;
|
||||
async $eval<R>(selector: string, pageFunction: types.FuncOn<Element, void, R>, arg?: any): Promise<R>;
|
||||
async $eval<R, Arg>(selector: string, pageFunction: types.FuncOn<Element, Arg, R>, arg: Arg): Promise<R> {
|
||||
|
@ -346,6 +346,21 @@ export class Injected {
|
||||
return { status: result ? 'success' : 'timeout' };
|
||||
}
|
||||
|
||||
dispatchEvent(node: Node, type: string, eventInit: Object) {
|
||||
let event;
|
||||
eventInit = { bubbles: true, cancelable: true, composed: true, ...eventInit };
|
||||
switch (eventType.get(type)) {
|
||||
case 'mouse': event = new MouseEvent(type, eventInit); break;
|
||||
case 'keyboard': event = new KeyboardEvent(type, eventInit); break;
|
||||
case 'touch': event = new TouchEvent(type, eventInit); break;
|
||||
case 'pointer': event = new PointerEvent(type, eventInit); break;
|
||||
case 'focus': event = new FocusEvent(type, eventInit); break;
|
||||
case 'drag': event = new DragEvent(type, eventInit); break;
|
||||
default: event = new Event(type, eventInit); break;
|
||||
}
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
private _parentElementOrShadowHost(element: Element): Element | undefined {
|
||||
if (element.parentElement)
|
||||
return element.parentElement;
|
||||
@ -368,3 +383,51 @@ export class Injected {
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
const eventType = new Map<string, 'mouse'|'keyboard'|'touch'|'pointer'|'focus'|'drag'>([
|
||||
['auxclick', 'mouse'],
|
||||
['click', 'mouse'],
|
||||
['dblclick', 'mouse'],
|
||||
['mousedown','mouse'],
|
||||
['mouseeenter', 'mouse'],
|
||||
['mouseleave', 'mouse'],
|
||||
['mousemove', 'mouse'],
|
||||
['mouseout', 'mouse'],
|
||||
['mouseover', 'mouse'],
|
||||
['mouseup', 'mouse'],
|
||||
['mouseleave', 'mouse'],
|
||||
['mousewheel', 'mouse'],
|
||||
|
||||
['keydown', 'keyboard'],
|
||||
['keyup', 'keyboard'],
|
||||
['keypress', 'keyboard'],
|
||||
['textInput', 'keyboard'],
|
||||
|
||||
['touchstart', 'touch'],
|
||||
['touchmove', 'touch'],
|
||||
['touchend', 'touch'],
|
||||
['touchcancel', 'touch'],
|
||||
|
||||
['pointerover', 'pointer'],
|
||||
['pointerout', 'pointer'],
|
||||
['pointerenter', 'pointer'],
|
||||
['pointerleave', 'pointer'],
|
||||
['pointerdown', 'pointer'],
|
||||
['pointerup', 'pointer'],
|
||||
['pointermove', 'pointer'],
|
||||
['pointercancel', 'pointer'],
|
||||
['gotpointercapture', 'pointer'],
|
||||
['lostpointercapture', 'pointer'],
|
||||
|
||||
['focus', 'focus'],
|
||||
['blur', 'focus'],
|
||||
|
||||
['drag', 'drag'],
|
||||
['dragstart', 'drag'],
|
||||
['dragend', 'drag'],
|
||||
['dragover', 'drag'],
|
||||
['dragenter', 'drag'],
|
||||
['dragleave', 'drag'],
|
||||
['dragexit', 'drag'],
|
||||
['drop', 'drag'],
|
||||
]);
|
||||
|
@ -220,6 +220,10 @@ export class Page extends ExtendedEventEmitter implements InnerLogger {
|
||||
return this.mainFrame().waitForSelector(selector, options);
|
||||
}
|
||||
|
||||
async dispatchEvent(selector: string, type: string, eventInit?: Object, options?: types.TimeoutOptions): Promise<void> {
|
||||
return this.mainFrame().dispatchEvent(selector, type, eventInit, options);
|
||||
}
|
||||
|
||||
async evaluateHandle<R, Arg>(pageFunction: types.Func1<Arg, R>, arg: Arg): Promise<types.SmartHandle<R>>;
|
||||
async evaluateHandle<R>(pageFunction: types.Func1<void, R>, arg?: any): Promise<types.SmartHandle<R>>;
|
||||
async evaluateHandle<R, Arg>(pageFunction: types.Func1<Arg, R>, arg: Arg): Promise<types.SmartHandle<R>> {
|
||||
|
@ -163,6 +163,19 @@ export class Selectors {
|
||||
return { world: this._needsMainContext(parsed) ? 'main' : 'utility', task };
|
||||
}
|
||||
|
||||
_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, () => {
|
||||
const element = evaluator.querySelector(parsed, document);
|
||||
if (element)
|
||||
evaluator.injected.dispatchEvent(element, type, eventInit);
|
||||
return element || false;
|
||||
});
|
||||
}, { evaluator: await this._prepareEvaluator(context), parsed, type, eventInit, timeout: helper.timeUntilDeadline(deadline) });
|
||||
return task;
|
||||
}
|
||||
|
||||
async _createSelector(name: string, handle: dom.ElementHandle<Element>): Promise<string | undefined> {
|
||||
const mainContext = await handle._page.mainFrame()._mainContext();
|
||||
return mainContext.evaluateInternal(({ evaluator, target, name }) => {
|
||||
|
@ -1,51 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang=en>
|
||||
<title>Examples of DataTransfer's setData(), getData() and clearData()</title>
|
||||
<meta content="width=device-width">
|
||||
<style>
|
||||
div:not(.mouse-helper) {
|
||||
margin: 0em;
|
||||
padding: 2em;
|
||||
}
|
||||
#source {
|
||||
color: blue;
|
||||
border: 1px solid black;
|
||||
}
|
||||
#target {
|
||||
border: 1px solid black;
|
||||
}
|
||||
div:not(.mouse-helper) {
|
||||
margin: 0em;
|
||||
padding: 2em;
|
||||
}
|
||||
#source {
|
||||
color: blue;
|
||||
border: 1px solid black;
|
||||
}
|
||||
#target {
|
||||
border: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
function dragstart_handler(ev) {
|
||||
console.log("dragStart");
|
||||
// Change the source element's background color to signify drag has started
|
||||
ev.currentTarget.style.border = "dashed";
|
||||
// Set the drag's format and data. Use the event target's id for the data
|
||||
ev.dataTransfer.setData("text/plain", ev.target.id);
|
||||
ev.currentTarget.style.border = "dashed";
|
||||
ev.dataTransfer.setData("text/plain", ev.target.id);
|
||||
}
|
||||
|
||||
function dragover_handler(ev) {
|
||||
console.log("dragOver");
|
||||
ev.preventDefault();
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
function drop_handler(ev) {
|
||||
console.log("Drop");
|
||||
ev.preventDefault();
|
||||
// Get the data, which is the id of the drop target
|
||||
var data = ev.dataTransfer.getData("text");
|
||||
ev.target.appendChild(document.getElementById(data));
|
||||
// Clear the drag data cache (for all formats/types)
|
||||
ev.dataTransfer.clearData();
|
||||
console.log("Drop");
|
||||
ev.preventDefault();
|
||||
var data = ev.dataTransfer.getData("text");
|
||||
ev.target.appendChild(document.getElementById(data));
|
||||
ev.dataTransfer.clearData();
|
||||
}
|
||||
</script>
|
||||
|
||||
<body>
|
||||
<script src="input/mouse-helper.js"></script>
|
||||
<h1>Examples of <code>DataTransfer</code>: <code>setData()</code>, <code>getData()</code>, <code>clearData()</code></h1>
|
||||
<div>
|
||||
<p id="source" ondragstart="dragstart_handler(event);" draggable="true">
|
||||
Select this element, drag it to the Drop Zone and then release the selection to move the element.</p>
|
||||
</div>
|
||||
<div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div>
|
||||
<div>
|
||||
<p id="source" ondragstart="dragstart_handler(event);" draggable="true">
|
||||
Select this element, drag it to the Drop Zone and then release the selection to move the element.</p>
|
||||
</div>
|
||||
<div id="target" ondrop="drop_handler(event);" ondragover="dragover_handler(event);">Drop Zone</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -15,6 +15,7 @@
|
||||
window.shiftKey = undefined;
|
||||
window.pageX = undefined;
|
||||
window.pageY = undefined;
|
||||
window.bubbles = undefined;
|
||||
document.querySelector('button').addEventListener('click', e => {
|
||||
result = 'Clicked';
|
||||
offsetX = e.offsetX;
|
||||
@ -22,6 +23,9 @@
|
||||
pageX = e.pageX;
|
||||
pageY = e.pageY;
|
||||
shiftKey = e.shiftKey;
|
||||
bubbles = e.bubbles;
|
||||
cancelable = e.cancelable;
|
||||
composed = e.composed;
|
||||
}, false);
|
||||
</script>
|
||||
</body>
|
||||
|
103
test/dispatchevent.spec.js
Normal file
103
test/dispatchevent.spec.js
Normal file
@ -0,0 +1,103 @@
|
||||
/**
|
||||
* Copyright Microsoft Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const utils = require('./utils');
|
||||
const {FFOX, CHROMIUM, WEBKIT, WIN} = utils.testOptions(browserType);
|
||||
|
||||
describe('Page.dispatchEvent(click)', function() {
|
||||
it('should dispatch click event', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
it('should dispatch click event properties', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => bubbles)).toBeTruthy();
|
||||
expect(await page.evaluate(() => cancelable)).toBeTruthy();
|
||||
expect(await page.evaluate(() => composed)).toBeTruthy();
|
||||
});
|
||||
it('should dispatch click svg', async({page, server}) => {
|
||||
await page.setContent(`
|
||||
<svg height="100" width="100">
|
||||
<circle onclick="javascript:window.__CLICKED=42" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
|
||||
</svg>
|
||||
`);
|
||||
await page.dispatchEvent('circle', 'click');
|
||||
expect(await page.evaluate(() => window.__CLICKED)).toBe(42);
|
||||
});
|
||||
it('should dispatch click on a span with an inline element inside', async({page, server}) => {
|
||||
await page.setContent(`
|
||||
<style>
|
||||
span::before {
|
||||
content: 'q';
|
||||
}
|
||||
</style>
|
||||
<span onclick='javascript:window.CLICKED=42'></span>
|
||||
`);
|
||||
await page.dispatchEvent('span', 'click');
|
||||
expect(await page.evaluate(() => window.CLICKED)).toBe(42);
|
||||
});
|
||||
it('should dispatch click after navigation ', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
it('should dispatch click after a cross origin navigation ', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
await page.goto(server.CROSS_PROCESS_PREFIX + '/input/button.html');
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
it('should not fail when element is blocked on hover', async({page, server}) => {
|
||||
await page.setContent(`<style>
|
||||
container { display: block; position: relative; width: 200px; height: 50px; }
|
||||
div, button { position: absolute; left: 0; top: 0; bottom: 0; right: 0; }
|
||||
div { pointer-events: none; }
|
||||
container:hover div { pointer-events: auto; background: red; }
|
||||
</style>
|
||||
<container>
|
||||
<button onclick="window.clicked=true">Click me</button>
|
||||
<div></div>
|
||||
</container>`);
|
||||
await page.dispatchEvent('button', 'click');
|
||||
expect(await page.evaluate(() => window.clicked)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Page.dispatchEvent(drag)', function() {
|
||||
it.fail(WEBKIT)('should dispatch drag drop events', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/drag-n-drop.html');
|
||||
const dataTransfer = await page.evaluateHandle(() => new DataTransfer());
|
||||
await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
|
||||
await page.dispatchEvent('#target', 'drop', { dataTransfer });
|
||||
expect(await page.evaluate(() => {
|
||||
return source.parentElement === target;
|
||||
})).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ElementHandle.dispatchEvent(click)', function() {
|
||||
it('should dispatch click event', async({page, server}) => {
|
||||
await page.goto(server.PREFIX + '/input/button.html');
|
||||
const button = await page.$('button');
|
||||
await button.dispatchEvent('click');
|
||||
expect(await page.evaluate(() => result)).toBe('Clicked');
|
||||
});
|
||||
});
|
@ -158,6 +158,7 @@ module.exports = {
|
||||
'./click.spec.js',
|
||||
'./cookies.spec.js',
|
||||
'./dialog.spec.js',
|
||||
'./dispatchevent.spec.js',
|
||||
'./download.spec.js',
|
||||
'./elementhandle.spec.js',
|
||||
'./emulation.spec.js',
|
||||
|
Loading…
Reference in New Issue
Block a user