Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ulixee
GitHub Repository: ulixee/secret-agent
Path: blob/main/puppet-chrome/lib/Mouse.ts
1028 views
1
/**
2
* Copyright 2018 Google Inc. All rights reserved.
3
* Modifications copyright (c) Data Liberation Foundation Inc.
4
*
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
* you may not use this file except in compliance with the License.
7
* You may obtain a copy of the License at
8
*
9
* http://www.apache.org/licenses/LICENSE-2.0
10
*
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
16
*/
17
import { IMouseButton } from '@secret-agent/interfaces/IInteractions';
18
import { IMouseOptions } from '@secret-agent/interfaces/IPuppetInput';
19
import IPoint from '@secret-agent/interfaces/IPoint';
20
import { DevtoolsSession } from './DevtoolsSession';
21
import { Keyboard } from './Keyboard';
22
23
/**
24
* The Mouse class operates in main-frame CSS pixels
25
* relative to the top-left corner of the viewport.
26
* @remarks
27
* Every `page` object has its own Mouse, accessible with [`page.mouse`](#pagemouse).
28
*
29
* @example
30
* ```js
31
* // Using ‘page.mouse’ to trace a 100x100 square.
32
* await page.mouse.move(0, 0);
33
* await page.mouse.down();
34
* await page.mouse.move(0, 100);
35
* await page.mouse.move(100, 100);
36
* await page.mouse.move(100, 0);
37
* await page.mouse.move(0, 0);
38
* await page.mouse.up();
39
* ```
40
*
41
* **Note**: The mouse events trigger synthetic `MouseEvent`s.
42
* This means that it does not fully replicate the functionality of what a normal user
43
* would be able to do with their mouse.
44
*
45
* For example, dragging and selecting text is not possible using `page.mouse`.
46
* Instead, you can use the {@link https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/getSelection | `DocumentOrShadowRoot.getSelection()`} functionality implemented in the platform.
47
*
48
* @public
49
*/
50
51
export default class Mouse {
52
public position: IPoint = { x: 0, y: 0 };
53
54
private devtoolsSession: DevtoolsSession;
55
private keyboard: Keyboard;
56
private button: IMouseButton | 'none' = 'none';
57
58
constructor(devtoolsSession: DevtoolsSession, keyboard: Keyboard) {
59
this.devtoolsSession = devtoolsSession;
60
this.keyboard = keyboard;
61
}
62
63
async move(x: number, y: number): Promise<void> {
64
const roundedX = Math.round(x ?? 0);
65
const roundedY = Math.round(y ?? 0);
66
if (roundedX === this.position.x && roundedY === this.position.y) return;
67
this.position.x = roundedX;
68
this.position.y = roundedY;
69
70
await this.devtoolsSession.send('Input.dispatchMouseEvent', {
71
type: 'mouseMoved',
72
button: this.button,
73
x: this.position.x,
74
y: this.position.y,
75
modifiers: this.keyboard.modifiers,
76
});
77
}
78
79
async down(options: IMouseOptions = {}): Promise<void> {
80
const { button = 'left', clickCount = 1 } = options;
81
this.button = button;
82
await this.devtoolsSession.send('Input.dispatchMouseEvent', {
83
type: 'mousePressed',
84
button,
85
x: this.position.x,
86
y: this.position.y,
87
modifiers: this.keyboard.modifiers,
88
clickCount,
89
});
90
}
91
92
async up(options: IMouseOptions = {}): Promise<void> {
93
const { button = 'left', clickCount = 1 } = options;
94
this.button = 'none';
95
await this.devtoolsSession.send('Input.dispatchMouseEvent', {
96
type: 'mouseReleased',
97
button,
98
x: this.position.x,
99
y: this.position.y,
100
modifiers: this.keyboard.modifiers,
101
clickCount,
102
});
103
}
104
105
async wheel(options: { deltaX?: number; deltaY?: number } = {}): Promise<void> {
106
const deltaX = Math.round(options.deltaX ?? 0);
107
const deltaY = Math.round(options.deltaY ?? 0);
108
109
if (deltaY === 0 && deltaY === 0) return;
110
111
await this.devtoolsSession.send('Input.dispatchMouseEvent', {
112
type: 'mouseWheel',
113
x: 0,
114
y: 0, // don't scroll relative to points... not included in mouse events and just confusing
115
deltaX,
116
deltaY,
117
modifiers: this.keyboard.modifiers,
118
pointerType: 'mouse',
119
});
120
}
121
}
122
123