donobu 2.17.0 → 2.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/generated/parameter-schemas.json +33 -33
- package/dist/assets/generated/version +1 -1
- package/dist/esm/assets/generated/parameter-schemas.json +33 -33
- package/dist/esm/assets/generated/version +1 -1
- package/dist/esm/managers/InteractionVisualizer.d.ts +8 -30
- package/dist/esm/managers/InteractionVisualizer.d.ts.map +1 -1
- package/dist/esm/managers/InteractionVisualizer.js +132 -204
- package/dist/esm/managers/InteractionVisualizer.js.map +1 -1
- package/dist/esm/managers/PageInspector.d.ts.map +1 -1
- package/dist/esm/managers/PageInspector.js +30 -32
- package/dist/esm/managers/PageInspector.js.map +1 -1
- package/dist/esm/tools/SolveMfaChallenge.d.ts +32 -0
- package/dist/esm/tools/SolveMfaChallenge.d.ts.map +1 -0
- package/dist/esm/tools/SolveMfaChallenge.js +185 -0
- package/dist/esm/tools/SolveMfaChallenge.js.map +1 -0
- package/dist/managers/InteractionVisualizer.d.ts +8 -30
- package/dist/managers/InteractionVisualizer.d.ts.map +1 -1
- package/dist/managers/InteractionVisualizer.js +132 -204
- package/dist/managers/InteractionVisualizer.js.map +1 -1
- package/dist/managers/PageInspector.d.ts.map +1 -1
- package/dist/managers/PageInspector.js +30 -32
- package/dist/managers/PageInspector.js.map +1 -1
- package/dist/tools/SolveMfaChallenge.d.ts +32 -0
- package/dist/tools/SolveMfaChallenge.d.ts.map +1 -0
- package/dist/tools/SolveMfaChallenge.js +185 -0
- package/dist/tools/SolveMfaChallenge.js.map +1 -0
- package/package.json +1 -1
|
@@ -14,35 +14,6 @@
|
|
|
14
14
|
"additionalProperties": false,
|
|
15
15
|
"required": ["targetId", "bindingName"]
|
|
16
16
|
},
|
|
17
|
-
"BaseToolGptParameters": {
|
|
18
|
-
"description": "This interface is intended to be the base for all tool parameters that are generated by a GPT.",
|
|
19
|
-
"type": "object",
|
|
20
|
-
"properties": {
|
|
21
|
-
"rationale": {
|
|
22
|
-
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
23
|
-
"type": "string"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"additionalProperties": false,
|
|
27
|
-
"required": ["rationale"]
|
|
28
|
-
},
|
|
29
|
-
"RunAccessibilityTestToolCoreParameters": {
|
|
30
|
-
"type": "object",
|
|
31
|
-
"additionalProperties": false,
|
|
32
|
-
"required": [],
|
|
33
|
-
"properties": {}
|
|
34
|
-
},
|
|
35
|
-
"RunAccessibilityTestToolGptParameters": {
|
|
36
|
-
"type": "object",
|
|
37
|
-
"properties": {
|
|
38
|
-
"rationale": {
|
|
39
|
-
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
40
|
-
"type": "string"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"additionalProperties": false,
|
|
44
|
-
"required": ["rationale"]
|
|
45
|
-
},
|
|
46
17
|
"ToolParameters": {
|
|
47
18
|
"anyOf": [
|
|
48
19
|
{
|
|
@@ -117,7 +88,7 @@
|
|
|
117
88
|
"type": "object",
|
|
118
89
|
"additionalProperties": false
|
|
119
90
|
},
|
|
120
|
-
"__@validatorSymbol@
|
|
91
|
+
"__@validatorSymbol@6486": {
|
|
121
92
|
"description": "Used to mark validator functions so we can support both Zod and custom schemas.",
|
|
122
93
|
"type": "boolean",
|
|
123
94
|
"const": true
|
|
@@ -129,21 +100,50 @@
|
|
|
129
100
|
"$ref": "#/definitions/JSONSchema7",
|
|
130
101
|
"description": "The JSON Schema for the schema. It is passed to the providers."
|
|
131
102
|
},
|
|
132
|
-
"__@schemaSymbol@
|
|
103
|
+
"__@schemaSymbol@6491": {
|
|
133
104
|
"description": "Used to mark schemas so we can support both Zod and custom schemas.",
|
|
134
105
|
"type": "boolean",
|
|
135
106
|
"const": true
|
|
136
107
|
}
|
|
137
108
|
},
|
|
138
109
|
"required": [
|
|
139
|
-
"__@schemaSymbol@
|
|
140
|
-
"__@validatorSymbol@
|
|
110
|
+
"__@schemaSymbol@6491",
|
|
111
|
+
"__@validatorSymbol@6486",
|
|
141
112
|
"_type",
|
|
142
113
|
"jsonSchema"
|
|
143
114
|
]
|
|
144
115
|
}
|
|
145
116
|
]
|
|
146
117
|
},
|
|
118
|
+
"BaseToolGptParameters": {
|
|
119
|
+
"description": "This interface is intended to be the base for all tool parameters that are generated by a GPT.",
|
|
120
|
+
"type": "object",
|
|
121
|
+
"properties": {
|
|
122
|
+
"rationale": {
|
|
123
|
+
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
124
|
+
"type": "string"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"additionalProperties": false,
|
|
128
|
+
"required": ["rationale"]
|
|
129
|
+
},
|
|
130
|
+
"RunAccessibilityTestToolCoreParameters": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"additionalProperties": false,
|
|
133
|
+
"required": [],
|
|
134
|
+
"properties": {}
|
|
135
|
+
},
|
|
136
|
+
"RunAccessibilityTestToolGptParameters": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"properties": {
|
|
139
|
+
"rationale": {
|
|
140
|
+
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
141
|
+
"type": "string"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"additionalProperties": false,
|
|
145
|
+
"required": ["rationale"]
|
|
146
|
+
},
|
|
147
147
|
"ChooseSelectOptionToolCoreParameters": {
|
|
148
148
|
"type": "object",
|
|
149
149
|
"properties": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1153
|
|
@@ -14,35 +14,6 @@
|
|
|
14
14
|
"additionalProperties": false,
|
|
15
15
|
"required": ["targetId", "bindingName"]
|
|
16
16
|
},
|
|
17
|
-
"BaseToolGptParameters": {
|
|
18
|
-
"description": "This interface is intended to be the base for all tool parameters that are generated by a GPT.",
|
|
19
|
-
"type": "object",
|
|
20
|
-
"properties": {
|
|
21
|
-
"rationale": {
|
|
22
|
-
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
23
|
-
"type": "string"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"additionalProperties": false,
|
|
27
|
-
"required": ["rationale"]
|
|
28
|
-
},
|
|
29
|
-
"RunAccessibilityTestToolCoreParameters": {
|
|
30
|
-
"type": "object",
|
|
31
|
-
"additionalProperties": false,
|
|
32
|
-
"required": [],
|
|
33
|
-
"properties": {}
|
|
34
|
-
},
|
|
35
|
-
"RunAccessibilityTestToolGptParameters": {
|
|
36
|
-
"type": "object",
|
|
37
|
-
"properties": {
|
|
38
|
-
"rationale": {
|
|
39
|
-
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
40
|
-
"type": "string"
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
"additionalProperties": false,
|
|
44
|
-
"required": ["rationale"]
|
|
45
|
-
},
|
|
46
17
|
"ToolParameters": {
|
|
47
18
|
"anyOf": [
|
|
48
19
|
{
|
|
@@ -117,7 +88,7 @@
|
|
|
117
88
|
"type": "object",
|
|
118
89
|
"additionalProperties": false
|
|
119
90
|
},
|
|
120
|
-
"__@validatorSymbol@
|
|
91
|
+
"__@validatorSymbol@6486": {
|
|
121
92
|
"description": "Used to mark validator functions so we can support both Zod and custom schemas.",
|
|
122
93
|
"type": "boolean",
|
|
123
94
|
"const": true
|
|
@@ -129,21 +100,50 @@
|
|
|
129
100
|
"$ref": "#/definitions/JSONSchema7",
|
|
130
101
|
"description": "The JSON Schema for the schema. It is passed to the providers."
|
|
131
102
|
},
|
|
132
|
-
"__@schemaSymbol@
|
|
103
|
+
"__@schemaSymbol@6491": {
|
|
133
104
|
"description": "Used to mark schemas so we can support both Zod and custom schemas.",
|
|
134
105
|
"type": "boolean",
|
|
135
106
|
"const": true
|
|
136
107
|
}
|
|
137
108
|
},
|
|
138
109
|
"required": [
|
|
139
|
-
"__@schemaSymbol@
|
|
140
|
-
"__@validatorSymbol@
|
|
110
|
+
"__@schemaSymbol@6491",
|
|
111
|
+
"__@validatorSymbol@6486",
|
|
141
112
|
"_type",
|
|
142
113
|
"jsonSchema"
|
|
143
114
|
]
|
|
144
115
|
}
|
|
145
116
|
]
|
|
146
117
|
},
|
|
118
|
+
"BaseToolGptParameters": {
|
|
119
|
+
"description": "This interface is intended to be the base for all tool parameters that are generated by a GPT.",
|
|
120
|
+
"type": "object",
|
|
121
|
+
"properties": {
|
|
122
|
+
"rationale": {
|
|
123
|
+
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
124
|
+
"type": "string"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"additionalProperties": false,
|
|
128
|
+
"required": ["rationale"]
|
|
129
|
+
},
|
|
130
|
+
"RunAccessibilityTestToolCoreParameters": {
|
|
131
|
+
"type": "object",
|
|
132
|
+
"additionalProperties": false,
|
|
133
|
+
"required": [],
|
|
134
|
+
"properties": {}
|
|
135
|
+
},
|
|
136
|
+
"RunAccessibilityTestToolGptParameters": {
|
|
137
|
+
"type": "object",
|
|
138
|
+
"properties": {
|
|
139
|
+
"rationale": {
|
|
140
|
+
"description": "The reason why this particular action is being taken. It MUST relate to the overall objective.",
|
|
141
|
+
"type": "string"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"additionalProperties": false,
|
|
145
|
+
"required": ["rationale"]
|
|
146
|
+
},
|
|
147
147
|
"ChooseSelectOptionToolCoreParameters": {
|
|
148
148
|
"type": "object",
|
|
149
149
|
"properties": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
1153
|
|
@@ -1,37 +1,15 @@
|
|
|
1
1
|
import { Page, Locator } from 'playwright';
|
|
2
|
-
/**
|
|
3
|
-
* Class for visualizing interactions in a webpage with a virtual mouse and messages.
|
|
4
|
-
*/
|
|
5
2
|
export declare class InteractionVisualizer {
|
|
6
3
|
readonly defaultMessageDurationMillis: number;
|
|
7
|
-
private static readonly
|
|
4
|
+
private static readonly SVG_MOUSE;
|
|
8
5
|
private static readonly CSS;
|
|
9
|
-
private static readonly
|
|
10
|
-
private
|
|
11
|
-
private static readonly registeredContexts;
|
|
12
|
-
private currentMousePosition;
|
|
13
|
-
/**
|
|
14
|
-
* Creates an instance of InteractionVisualizer.
|
|
15
|
-
* @param defaultMessageDurationMillis - Default duration for displaying messages in milliseconds.
|
|
16
|
-
*/
|
|
6
|
+
private static readonly CONTAINER_ID;
|
|
7
|
+
private cursorPos;
|
|
17
8
|
constructor(defaultMessageDurationMillis: number);
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Moves the virtual mouse to the target position with a smooth animation.
|
|
25
|
-
*/
|
|
26
|
-
private moveVirtualMouse;
|
|
27
|
-
/**
|
|
28
|
-
* Creates a message adjacent to the element, inside a shadow root to avoid CSS collisions.
|
|
29
|
-
*/
|
|
30
|
-
private displayMessageNearElement;
|
|
31
|
-
/**
|
|
32
|
-
* Ensures routes are registered for the given browser context.
|
|
33
|
-
* @param browserContext - The browser context to register routes on.
|
|
34
|
-
*/
|
|
35
|
-
private static ensureRoutesRegistered;
|
|
9
|
+
/** Move the virtual cursor to the centre of the locator and optionally show a message. */
|
|
10
|
+
pointAt(page: Page, locator: Locator, message?: string, duration?: number): Promise<void>;
|
|
11
|
+
private ensureContainer;
|
|
12
|
+
private moveCursor;
|
|
13
|
+
private showMessage;
|
|
36
14
|
}
|
|
37
15
|
//# sourceMappingURL=InteractionVisualizer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InteractionVisualizer.d.ts","sourceRoot":"","sources":["../../../src/managers/InteractionVisualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"InteractionVisualizer.d.ts","sourceRoot":"","sources":["../../../src/managers/InteractionVisualizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE3C,qBAAa,qBAAqB;aA6BG,4BAA4B,EAAE,MAAM;IAxBvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAW3B;IAEN,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAM3B;IAEA,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAuB;IAC3D,OAAO,CAAC,SAAS,CAA4C;gBAE1B,4BAA4B,EAAE,MAAM;IAMvE,0FAA0F;IAC7E,OAAO,CAClB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,MAAM,EAChB,QAAQ,SAAoC,GAC3C,OAAO,CAAC,IAAI,CAAC;YAsBF,eAAe;YA8Bf,UAAU;YAkDV,WAAW;CA8C1B"}
|
|
@@ -1,223 +1,151 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InteractionVisualizer = void 0;
|
|
4
|
-
const Logger_1 = require("../utils/Logger");
|
|
5
|
-
const PlaywrightUtils_1 = require("../utils/PlaywrightUtils");
|
|
6
|
-
const MiscUtils_1 = require("../utils/MiscUtils");
|
|
7
|
-
/**
|
|
8
|
-
* Class for visualizing interactions in a webpage with a virtual mouse and messages.
|
|
9
|
-
*/
|
|
10
4
|
class InteractionVisualizer {
|
|
11
|
-
/**
|
|
12
|
-
* Creates an instance of InteractionVisualizer.
|
|
13
|
-
* @param defaultMessageDurationMillis - Default duration for displaying messages in milliseconds.
|
|
14
|
-
*/
|
|
15
5
|
constructor(defaultMessageDurationMillis) {
|
|
16
6
|
this.defaultMessageDurationMillis = defaultMessageDurationMillis;
|
|
17
|
-
this.
|
|
7
|
+
this.cursorPos = { x: 0, y: 0 };
|
|
18
8
|
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
async pointAt(page,
|
|
24
|
-
if (!
|
|
9
|
+
/* ------------------------------------------------------------------ */
|
|
10
|
+
/* Public API */
|
|
11
|
+
/* ------------------------------------------------------------------ */
|
|
12
|
+
/** Move the virtual cursor to the centre of the locator and optionally show a message. */
|
|
13
|
+
async pointAt(page, locator, message, duration = this.defaultMessageDurationMillis) {
|
|
14
|
+
if (!duration || duration <= 0)
|
|
25
15
|
return;
|
|
26
|
-
|
|
27
|
-
await
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
16
|
+
await locator.scrollIntoViewIfNeeded();
|
|
17
|
+
const box = await locator.boundingBox();
|
|
18
|
+
if (!box)
|
|
19
|
+
throw new Error('Element bounding box unavailable');
|
|
20
|
+
const target = { x: box.x + box.width / 2, y: box.y + box.height / 2 };
|
|
21
|
+
await this.ensureContainer(page);
|
|
22
|
+
await Promise.all([
|
|
23
|
+
this.moveCursor(page, target, duration / 2),
|
|
24
|
+
message && message.trim()
|
|
25
|
+
? this.showMessage(page, target, message.trim(), duration)
|
|
26
|
+
: Promise.resolve(),
|
|
27
|
+
]);
|
|
28
|
+
}
|
|
29
|
+
/* ------------------------------------------------------------------ */
|
|
30
|
+
/* Private helpers */
|
|
31
|
+
/* ------------------------------------------------------------------ */
|
|
32
|
+
async ensureContainer(page) {
|
|
33
|
+
const id = InteractionVisualizer.CONTAINER_ID;
|
|
34
|
+
await page.evaluate(([containerId, css]) => {
|
|
35
|
+
if (document.getElementById(containerId))
|
|
33
36
|
return;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (container) {
|
|
53
|
-
const shadow = container.shadowRoot;
|
|
54
|
-
if (shadow) {
|
|
55
|
-
// Remove only message elements but keep the mouse
|
|
56
|
-
const messages = Array.from(shadow.querySelectorAll('.donobu-message'));
|
|
57
|
-
messages.forEach((msg) => msg.remove());
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}, [InteractionVisualizer.MESSAGE_CONTAINER_ID]);
|
|
61
|
-
}
|
|
62
|
-
catch (e) {
|
|
63
|
-
if (PlaywrightUtils_1.PlaywrightUtils.isPageClosedError(e)) {
|
|
64
|
-
throw e;
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
Logger_1.appLogger.error(`Failed to display message at element`, e);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
37
|
+
const el = document.createElement('div');
|
|
38
|
+
el.id = containerId;
|
|
39
|
+
Object.assign(el.style, {
|
|
40
|
+
position: 'fixed',
|
|
41
|
+
top: '0',
|
|
42
|
+
left: '0',
|
|
43
|
+
width: '100vw',
|
|
44
|
+
height: '100vh',
|
|
45
|
+
pointerEvents: 'none',
|
|
46
|
+
zIndex: '2147483646', // just below the message itself
|
|
47
|
+
});
|
|
48
|
+
const shadow = el.attachShadow({ mode: 'open' });
|
|
49
|
+
const style = document.createElement('style');
|
|
50
|
+
style.textContent = css;
|
|
51
|
+
shadow.appendChild(style);
|
|
52
|
+
// Append to <html> so it is not clipped by overflow/transform on <body>
|
|
53
|
+
(document.documentElement || document.body).appendChild(el);
|
|
54
|
+
}, [id, InteractionVisualizer.CSS]);
|
|
70
55
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
// Find or create mouse
|
|
103
|
-
let mouse = shadow.getElementById(mouseId);
|
|
104
|
-
if (!mouse) {
|
|
105
|
-
mouse = document.createElement('div');
|
|
106
|
-
mouse.id = mouseId;
|
|
107
|
-
mouse.className = 'donobu-virtual-mouse';
|
|
108
|
-
// Initial position if first time
|
|
109
|
-
mouse.style.left = `${startX}px`;
|
|
110
|
-
mouse.style.top = `${startY}px`;
|
|
111
|
-
mouse.style.transitionDuration = '0s'; // No animation initially
|
|
112
|
-
shadow.appendChild(mouse);
|
|
113
|
-
// Force reflow to ensure initial position is applied before animation
|
|
114
|
-
void mouse.offsetWidth;
|
|
115
|
-
}
|
|
116
|
-
// Animate the mouse
|
|
117
|
-
mouse.style.transitionDuration = `${duration}ms`;
|
|
118
|
-
mouse.style.left = `${endX - 16}px`; // Half of 40px
|
|
119
|
-
mouse.style.top = `${endY - 8}px`; // Tip adjustment
|
|
120
|
-
// Resolve when transition completes or timeout as fallback
|
|
121
|
-
const transitionEndHandler = () => {
|
|
122
|
-
mouse?.removeEventListener('transitionend', transitionEndHandler);
|
|
123
|
-
if (mouse) {
|
|
124
|
-
mouse.classList.remove('rippling'); // Reset ripple
|
|
125
|
-
void mouse.offsetWidth; // Force reflow
|
|
126
|
-
setTimeout(() => {
|
|
127
|
-
mouse?.classList.add('rippling'); // Trigger new ripple
|
|
128
|
-
}, 10);
|
|
129
|
-
}
|
|
56
|
+
async moveCursor(page, target, duration) {
|
|
57
|
+
const id = InteractionVisualizer.CONTAINER_ID;
|
|
58
|
+
await page.evaluate(([containerId, start, end, duration, svg]) => {
|
|
59
|
+
containerId = containerId;
|
|
60
|
+
start = start;
|
|
61
|
+
end = end;
|
|
62
|
+
duration = duration;
|
|
63
|
+
svg = svg;
|
|
64
|
+
const root = document.getElementById(containerId)
|
|
65
|
+
.shadowRoot;
|
|
66
|
+
let cursor = root.querySelector('.donobu-virtual-mouse');
|
|
67
|
+
if (!cursor) {
|
|
68
|
+
cursor = document.createElement('div');
|
|
69
|
+
cursor.className = 'donobu-virtual-mouse';
|
|
70
|
+
cursor.innerHTML = svg;
|
|
71
|
+
cursor.style.left = `${start.x}px`;
|
|
72
|
+
cursor.style.top = `${start.y}px`;
|
|
73
|
+
cursor.style.transitionDuration = '0s';
|
|
74
|
+
root.appendChild(cursor);
|
|
75
|
+
cursor.getBoundingClientRect(); // force reflow
|
|
76
|
+
}
|
|
77
|
+
cursor.style.transitionDuration = `${duration}ms`;
|
|
78
|
+
cursor.style.left = `${end.x - 12}px`; // half width offset
|
|
79
|
+
cursor.style.top = `${end.y - 12}px`; // half height offset
|
|
80
|
+
cursor.classList.add('rippling');
|
|
81
|
+
const done = new Promise((resolve) => {
|
|
82
|
+
const finish = () => {
|
|
83
|
+
cursor.removeEventListener('transitionend', finish);
|
|
84
|
+
cursor.classList.remove('rippling');
|
|
130
85
|
resolve();
|
|
131
86
|
};
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
setTimeout(resolve, duration + 50);
|
|
87
|
+
cursor.addEventListener('transitionend', finish);
|
|
88
|
+
setTimeout(finish, duration + 50);
|
|
135
89
|
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.currentMousePosition.x,
|
|
140
|
-
this.currentMousePosition.y,
|
|
141
|
-
targetX,
|
|
142
|
-
targetY,
|
|
143
|
-
durationMillis,
|
|
144
|
-
]);
|
|
145
|
-
// Update current mouse position
|
|
146
|
-
this.currentMousePosition = { x: targetX, y: targetY };
|
|
90
|
+
return done;
|
|
91
|
+
}, [id, this.cursorPos, target, duration, InteractionVisualizer.SVG_MOUSE]);
|
|
92
|
+
this.cursorPos = target;
|
|
147
93
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
let y = rect.bottom + window.scrollY + 10;
|
|
171
|
-
messageElement.style.left = `${x}px`;
|
|
172
|
-
messageElement.style.top = `${y}px`;
|
|
173
|
-
// Adjust if it goes off-screen to the right
|
|
174
|
-
const msgRect = messageElement.getBoundingClientRect();
|
|
175
|
-
const overflowRight = msgRect.right - window.innerWidth;
|
|
176
|
-
if (overflowRight > 0) {
|
|
177
|
-
messageElement.style.left = `${x - overflowRight - 10}px`;
|
|
178
|
-
}
|
|
179
|
-
// Adjust if it goes off-screen to the left
|
|
180
|
-
if (msgRect.left < 0) {
|
|
181
|
-
messageElement.style.left = `${window.scrollX + 10}px`;
|
|
94
|
+
async showMessage(page, target, text, duration) {
|
|
95
|
+
const id = InteractionVisualizer.CONTAINER_ID;
|
|
96
|
+
await page.evaluate(([containerId, target, text, duration]) => {
|
|
97
|
+
containerId = containerId;
|
|
98
|
+
target = target;
|
|
99
|
+
text = text;
|
|
100
|
+
duration = duration;
|
|
101
|
+
const root = document.getElementById(containerId)
|
|
102
|
+
.shadowRoot;
|
|
103
|
+
const msg = document.createElement('div');
|
|
104
|
+
msg.className = 'donobu-message';
|
|
105
|
+
msg.textContent = text;
|
|
106
|
+
root.appendChild(msg);
|
|
107
|
+
/* ── compute final coordinates ────────────────────────────────── */
|
|
108
|
+
const { width, height } = msg.getBoundingClientRect();
|
|
109
|
+
let x = target.x - width / 2;
|
|
110
|
+
let y = target.y + 24; // default - below cursor
|
|
111
|
+
/* clamp horizontally inside viewport */
|
|
112
|
+
x = Math.max(8, Math.min(window.innerWidth - width - 8, x));
|
|
113
|
+
/* if it overflows bottom, flip above the element */
|
|
114
|
+
if (y + height + 8 > window.innerHeight) {
|
|
115
|
+
y = target.y - height - 24;
|
|
182
116
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
try {
|
|
194
|
-
await browserContext.route('**/donobu-virtual-mouse.svg', async (route) => {
|
|
195
|
-
await route.fulfill({
|
|
196
|
-
status: 200,
|
|
197
|
-
contentType: 'image/svg+xml',
|
|
198
|
-
body: InteractionVisualizer.VIRTUAL_MOUSE_SVG,
|
|
199
|
-
});
|
|
200
|
-
});
|
|
201
|
-
await browserContext.route('**/donobu.css', async (route) => {
|
|
202
|
-
await route.fulfill({
|
|
203
|
-
status: 200,
|
|
204
|
-
contentType: 'text/css',
|
|
205
|
-
body: InteractionVisualizer.CSS,
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
this.registeredContexts.add(browserContext);
|
|
209
|
-
Logger_1.appLogger.debug('Routes registered for InteractionVisualizer');
|
|
210
|
-
}
|
|
211
|
-
catch (e) {
|
|
212
|
-
Logger_1.appLogger.error('Failed to register routes for InteractionVisualizer', e);
|
|
213
|
-
throw e;
|
|
214
|
-
}
|
|
117
|
+
/* if still off-screen at the top, clamp to 8 px margin */
|
|
118
|
+
if (y < 8)
|
|
119
|
+
y = 8;
|
|
120
|
+
msg.style.left = `${x}px`;
|
|
121
|
+
msg.style.top = `${y}px`;
|
|
122
|
+
/* auto-remove after the requested duration */
|
|
123
|
+
setTimeout(() => msg.remove(), duration);
|
|
124
|
+
}, [id, target, text, duration]);
|
|
215
125
|
}
|
|
216
126
|
}
|
|
217
127
|
exports.InteractionVisualizer = InteractionVisualizer;
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
InteractionVisualizer.
|
|
222
|
-
|
|
128
|
+
/* ------------------------------------------------------------------ */
|
|
129
|
+
/* Constants */
|
|
130
|
+
/* ------------------------------------------------------------------ */
|
|
131
|
+
InteractionVisualizer.SVG_MOUSE = `
|
|
132
|
+
<svg xmlns="http://www.w3.org/2000/svg"
|
|
133
|
+
width="32"
|
|
134
|
+
height="32"
|
|
135
|
+
viewBox="0 0 24 24"
|
|
136
|
+
fill="oklch(13.09% 0.005 165.18)"
|
|
137
|
+
stroke="oklch(83.04% 0.1698 83.99)"
|
|
138
|
+
stroke-width="2"
|
|
139
|
+
stroke-linecap="round"
|
|
140
|
+
stroke-linejoin="round">
|
|
141
|
+
<path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z" />
|
|
142
|
+
</svg>`;
|
|
143
|
+
InteractionVisualizer.CSS = `
|
|
144
|
+
.donobu-message{position:absolute;z-index:2147483647;background:#000;color:#fff;padding:8px 10px;border-radius:5px;font:12px/1 'Source Sans Pro','Helvetica Neue',Helvetica,Arial,sans-serif;max-width:300px;white-space:pre-wrap;box-shadow:2px 2px 10px rgba(0,0,0,.2);pointer-events:none}
|
|
145
|
+
.donobu-virtual-mouse{width:24px;height:24px;position:absolute;z-index:2147483646;filter:drop-shadow(1px 1px 1px rgba(0,0,0,.5));transition:left .15s ease-in-out,top .15s ease-in-out,transform .15s ease-in-out}
|
|
146
|
+
.donobu-virtual-mouse svg{width:100%;height:100%;display:block}
|
|
147
|
+
.donobu-virtual-mouse.rippling::after{content:"";position:absolute;left:50%;top:50%;width:24px;height:24px;border-radius:50%;background:oklch(83.04% 0.1698 83.99);transform:translate(-50%,-50%) scale(.5);opacity:.4;animation:ripple-pop .6s ease-out forwards}
|
|
148
|
+
@keyframes ripple-pop{40%{transform:translate(-50%,-50%) scale(1);opacity:.5}100%{transform:translate(-50%,-50%) scale(2);opacity:0}}
|
|
149
|
+
`;
|
|
150
|
+
InteractionVisualizer.CONTAINER_ID = 'donobu-iv-overlay';
|
|
223
151
|
//# sourceMappingURL=InteractionVisualizer.js.map
|