cdp-skill 1.0.16 → 1.0.17

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.
Files changed (103) hide show
  1. package/README.md +4 -4
  2. package/SKILL.md +276 -170
  3. package/package.json +9 -8
  4. package/{src → scripts}/aria/index.js +1 -1
  5. package/scripts/aria/role-query.js +295 -0
  6. package/{src → scripts}/aria.js +11 -5
  7. package/{src → scripts}/capture/console-capture.js +11 -9
  8. package/{src → scripts}/capture/screenshot-capture.js +8 -9
  9. package/{src → scripts}/cdp/connection.js +30 -6
  10. package/{src → scripts}/cdp-skill.js +7 -6
  11. package/{src → scripts}/diff.js +7 -6
  12. package/{src → scripts}/dom/LazyResolver.js +23 -12
  13. package/{src → scripts}/dom/actionability.js +39 -22
  14. package/{src → scripts}/dom/click-executor.js +90 -53
  15. package/{src → scripts}/dom/element-locator.js +4 -4
  16. package/{src → scripts}/dom/fill-executor.js +8 -4
  17. package/{src → scripts}/dom/input-emulator.js +47 -9
  18. package/{src → scripts}/dom/react-filler.js +11 -3
  19. package/{src → scripts}/dom/wait-executor.js +10 -2
  20. package/{src → scripts}/page/dialog-handler.js +7 -3
  21. package/{src → scripts}/page/dom-stability.js +17 -10
  22. package/{src → scripts}/page/page-controller.js +41 -34
  23. package/{src → scripts}/runner/context-helpers.js +7 -0
  24. package/{src → scripts}/runner/execute-browser.js +3 -118
  25. package/{src → scripts}/runner/execute-dynamic.js +46 -11
  26. package/{src → scripts}/runner/execute-form.js +6 -4
  27. package/{src → scripts}/runner/execute-input.js +127 -100
  28. package/{src → scripts}/runner/execute-interaction.js +31 -46
  29. package/{src → scripts}/runner/execute-navigation.js +14 -12
  30. package/{src → scripts}/runner/step-executors.js +28 -9
  31. package/{src → scripts}/runner/step-registry.js +57 -8
  32. package/{src → scripts}/runner/step-validator.js +13 -3
  33. package/{src → scripts}/tests/ExecuteInput.test.js +58 -188
  34. package/src/aria/role-query.js +0 -1229
  35. package/src/aria/snapshot.js +0 -459
  36. /package/{src → scripts}/aria/output-processor.js +0 -0
  37. /package/{src → scripts}/capture/debug-capture.js +0 -0
  38. /package/{src → scripts}/capture/error-aggregator.js +0 -0
  39. /package/{src → scripts}/capture/eval-serializer.js +0 -0
  40. /package/{src → scripts}/capture/index.js +0 -0
  41. /package/{src → scripts}/capture/network-capture.js +0 -0
  42. /package/{src → scripts}/capture/pdf-capture.js +0 -0
  43. /package/{src → scripts}/cdp/browser.js +0 -0
  44. /package/{src → scripts}/cdp/discovery.js +0 -0
  45. /package/{src → scripts}/cdp/index.js +0 -0
  46. /package/{src → scripts}/cdp/target-and-session.js +0 -0
  47. /package/{src → scripts}/constants.js +0 -0
  48. /package/{src → scripts}/dom/element-handle.js +0 -0
  49. /package/{src → scripts}/dom/element-validator.js +0 -0
  50. /package/{src → scripts}/dom/index.js +0 -0
  51. /package/{src → scripts}/dom/keyboard-executor.js +0 -0
  52. /package/{src → scripts}/dom/quad-helpers.js +0 -0
  53. /package/{src → scripts}/index.js +0 -0
  54. /package/{src → scripts}/page/cookie-manager.js +0 -0
  55. /package/{src → scripts}/page/index.js +0 -0
  56. /package/{src → scripts}/page/wait-utilities.js +0 -0
  57. /package/{src → scripts}/page/web-storage-manager.js +0 -0
  58. /package/{src → scripts}/runner/execute-query.js +0 -0
  59. /package/{src → scripts}/runner/index.js +0 -0
  60. /package/{src → scripts}/tests/Actionability.test.js +0 -0
  61. /package/{src → scripts}/tests/Aria.test.js +0 -0
  62. /package/{src → scripts}/tests/BrowserClient.test.js +0 -0
  63. /package/{src → scripts}/tests/CDPConnection.test.js +0 -0
  64. /package/{src → scripts}/tests/ChromeDiscovery.test.js +0 -0
  65. /package/{src → scripts}/tests/ClickExecutor.test.js +0 -0
  66. /package/{src → scripts}/tests/ConsoleCapture.test.js +0 -0
  67. /package/{src → scripts}/tests/ContextHelpers.test.js +0 -0
  68. /package/{src → scripts}/tests/CookieManager.test.js +0 -0
  69. /package/{src → scripts}/tests/DebugCapture.test.js +0 -0
  70. /package/{src → scripts}/tests/ElementHandle.test.js +0 -0
  71. /package/{src → scripts}/tests/ElementLocator.test.js +0 -0
  72. /package/{src → scripts}/tests/ErrorAggregator.test.js +0 -0
  73. /package/{src → scripts}/tests/EvalSerializer.test.js +0 -0
  74. /package/{src → scripts}/tests/ExecuteBrowser.test.js +0 -0
  75. /package/{src → scripts}/tests/ExecuteDynamic.test.js +0 -0
  76. /package/{src → scripts}/tests/ExecuteForm.test.js +0 -0
  77. /package/{src → scripts}/tests/ExecuteInteraction.test.js +0 -0
  78. /package/{src → scripts}/tests/ExecuteQuery.test.js +0 -0
  79. /package/{src → scripts}/tests/FillExecutor.test.js +0 -0
  80. /package/{src → scripts}/tests/InputEmulator.test.js +0 -0
  81. /package/{src → scripts}/tests/KeyboardExecutor.test.js +0 -0
  82. /package/{src → scripts}/tests/LazyResolver.test.js +0 -0
  83. /package/{src → scripts}/tests/NetworkErrorCapture.test.js +0 -0
  84. /package/{src → scripts}/tests/PageController.test.js +0 -0
  85. /package/{src → scripts}/tests/PdfCapture.test.js +0 -0
  86. /package/{src → scripts}/tests/ScreenshotCapture.test.js +0 -0
  87. /package/{src → scripts}/tests/SessionRegistry.test.js +0 -0
  88. /package/{src → scripts}/tests/StepValidator.test.js +0 -0
  89. /package/{src → scripts}/tests/TargetManager.test.js +0 -0
  90. /package/{src → scripts}/tests/TestRunner.test.js +0 -0
  91. /package/{src → scripts}/tests/WaitStrategy.test.js +0 -0
  92. /package/{src → scripts}/tests/WaitUtilities.test.js +0 -0
  93. /package/{src → scripts}/tests/WebStorageManager.test.js +0 -0
  94. /package/{src → scripts}/tests/integration.test.js +0 -0
  95. /package/{src → scripts}/types.js +0 -0
  96. /package/{src → scripts}/utils/backoff.js +0 -0
  97. /package/{src → scripts}/utils/cdp-helpers.js +0 -0
  98. /package/{src → scripts}/utils/devices.js +0 -0
  99. /package/{src → scripts}/utils/errors.js +0 -0
  100. /package/{src → scripts}/utils/index.js +0 -0
  101. /package/{src → scripts}/utils/temp.js +0 -0
  102. /package/{src → scripts}/utils/validators.js +0 -0
  103. /package/{src → scripts}/utils.js +0 -0
@@ -2,7 +2,6 @@ import { describe, it, mock, beforeEach, afterEach } from 'node:test';
2
2
  import assert from 'node:assert';
3
3
 
4
4
  import {
5
- executeFill,
6
5
  executeFillActive,
7
6
  executeSelectOption
8
7
  } from '../runner/execute-input.js';
@@ -103,203 +102,74 @@ function createMockInputEmulator() {
103
102
  }
104
103
 
105
104
  function createMockPageController(opts = {}) {
106
- return {
107
- session: {
108
- send: mock.fn((method, params) => {
109
- if (method === 'Runtime.evaluate') {
110
- if (opts.noFocus) {
111
- return Promise.resolve({
112
- result: {
113
- value: {
114
- error: 'No element is focused'
115
- }
116
- }
117
- });
118
- }
119
- if (opts.notEditable) {
120
- return Promise.resolve({
121
- result: {
122
- value: {
123
- error: 'Focused element is not editable',
124
- tag: 'DIV'
125
- }
126
- }
127
- });
105
+ const evaluateResult = () => {
106
+ if (opts.noFocus) {
107
+ return Promise.resolve({
108
+ result: {
109
+ value: {
110
+ error: 'No element is focused'
128
111
  }
129
- if (opts.disabled) {
130
- return Promise.resolve({
131
- result: {
132
- value: {
133
- error: 'Focused element is disabled',
134
- tag: 'INPUT'
135
- }
136
- }
137
- });
112
+ }
113
+ });
114
+ }
115
+ if (opts.notEditable) {
116
+ return Promise.resolve({
117
+ result: {
118
+ value: {
119
+ error: 'Focused element is not editable',
120
+ tag: 'DIV'
138
121
  }
139
- if (opts.readonly) {
140
- return Promise.resolve({
141
- result: {
142
- value: {
143
- error: 'Focused element is readonly',
144
- tag: 'INPUT'
145
- }
146
- }
147
- });
122
+ }
123
+ });
124
+ }
125
+ if (opts.disabled) {
126
+ return Promise.resolve({
127
+ result: {
128
+ value: {
129
+ error: 'Focused element is disabled',
130
+ tag: 'INPUT'
148
131
  }
149
- if (opts.exception) {
150
- return Promise.resolve({
151
- result: { value: undefined },
152
- exceptionDetails: {
153
- text: opts.exception
154
- }
155
- });
132
+ }
133
+ });
134
+ }
135
+ if (opts.readonly) {
136
+ return Promise.resolve({
137
+ result: {
138
+ value: {
139
+ error: 'Focused element is readonly',
140
+ tag: 'INPUT'
156
141
  }
157
- return Promise.resolve({
158
- result: {
159
- value: {
160
- editable: true,
161
- tag: 'INPUT',
162
- type: 'text',
163
- selector: '#username',
164
- valueBefore: ''
165
- }
166
- }
167
- });
168
142
  }
169
- return Promise.resolve({});
170
- })
143
+ });
171
144
  }
172
- };
173
- }
174
-
175
- // ---------------------------------------------------------------------------
176
- // Tests: executeFill
177
- // ---------------------------------------------------------------------------
178
-
179
- describe('executeFill', () => {
180
- afterEach(() => { mock.reset(); });
181
-
182
- it('should throw if selector is missing', async () => {
183
- const locator = createMockElementLocator();
184
- const emulator = createMockInputEmulator();
185
-
186
- await assert.rejects(
187
- executeFill(locator, emulator, { value: 'test' }),
188
- { message: 'Fill requires selector and value' }
189
- );
190
- });
191
-
192
- it('should throw if value is missing', async () => {
193
- const locator = createMockElementLocator();
194
- const emulator = createMockInputEmulator();
195
-
196
- await assert.rejects(
197
- executeFill(locator, emulator, { selector: '#input' }),
198
- { message: 'Fill requires selector and value' }
199
- );
200
- });
201
-
202
- it('should throw if element not found', async () => {
203
- const locator = createMockElementLocator({ notFound: true });
204
- const emulator = createMockInputEmulator();
205
-
206
- await assert.rejects(
207
- executeFill(locator, emulator, { selector: '#missing', value: 'test' }),
208
- { message: /element not found/i }
209
- );
210
- });
211
-
212
- it('should throw if element is not editable', async () => {
213
- const locator = createMockElementLocator({ notEditable: true });
214
- const emulator = createMockInputEmulator();
215
-
216
- await assert.rejects(
217
- executeFill(locator, emulator, { selector: '#disabled', value: 'test' }),
218
- { message: /not editable/i }
219
- );
220
- });
221
-
222
- it('should throw if element is not actionable after all scroll strategies', async () => {
223
- const locator = createMockElementLocator({ actionable: false, reason: 'Element is covered' });
224
- const emulator = createMockInputEmulator();
225
-
226
- await assert.rejects(
227
- executeFill(locator, emulator, { selector: '#input', value: 'test' }),
228
- { message: /not actionable/i }
229
- );
230
- });
231
-
232
- it('should fill element with standard approach', async () => {
233
- const locator = createMockElementLocator();
234
- const emulator = createMockInputEmulator();
235
-
236
- await executeFill(locator, emulator, { selector: '#input', value: 'hello' });
237
-
238
- assert.strictEqual(locator.findElement.mock.calls.length, 1);
239
- assert.strictEqual(emulator.click.mock.calls.length, 1);
240
- assert.strictEqual(emulator.selectAll.mock.calls.length, 1);
241
- assert.strictEqual(emulator.type.mock.calls.length, 1);
242
- assert.strictEqual(emulator.type.mock.calls[0].arguments[0], 'hello');
243
- });
244
-
245
- it('should skip clear if clear option is false', async () => {
246
- const locator = createMockElementLocator();
247
- const emulator = createMockInputEmulator();
248
-
249
- await executeFill(locator, emulator, { selector: '#input', value: 'hello', clear: false });
250
-
251
- assert.strictEqual(emulator.selectAll.mock.calls.length, 0);
252
- assert.strictEqual(emulator.type.mock.calls.length, 1);
253
- });
254
-
255
- it('should use React filler if react option is true', async () => {
256
- const locator = createMockElementLocator();
257
- const emulator = createMockInputEmulator();
258
-
259
- // Mock createReactInputFiller
260
- await executeFill(locator, emulator, { selector: '#input', value: 'hello', react: true });
261
-
262
- // React mode skips click and type
263
- assert.strictEqual(emulator.click.mock.calls.length, 0);
264
- assert.strictEqual(emulator.type.mock.calls.length, 0);
265
- });
266
-
267
- it('should dispose element handle on success', async () => {
268
- const locator = createMockElementLocator();
269
- const emulator = createMockInputEmulator();
270
-
271
- await executeFill(locator, emulator, { selector: '#input', value: 'test' });
272
-
273
- const element = await locator.findElement('#input');
274
- // Can't directly check if dispose was called, but ensure no errors
275
- assert.ok(element);
276
- });
277
-
278
- it('should try multiple scroll strategies if element not immediately actionable', async () => {
279
- let callCount = 0;
280
- const locator = createMockElementLocator({
281
- actionable: true
282
- });
283
-
284
- // Override isActionable to succeed on second call
285
- const originalHandle = await locator.findElement('#input');
286
- originalHandle._handle.isActionable = mock.fn(() => {
287
- callCount++;
145
+ if (opts.exception) {
288
146
  return Promise.resolve({
289
- actionable: callCount > 1,
290
- reason: callCount > 1 ? null : 'Not visible'
147
+ result: { value: undefined },
148
+ exceptionDetails: {
149
+ text: opts.exception
150
+ }
291
151
  });
152
+ }
153
+ return Promise.resolve({
154
+ result: {
155
+ value: {
156
+ editable: true,
157
+ tag: 'INPUT',
158
+ type: 'text',
159
+ selector: '#username',
160
+ valueBefore: ''
161
+ }
162
+ }
292
163
  });
293
- locator.findElement = mock.fn(() => Promise.resolve(originalHandle));
294
-
295
- const emulator = createMockInputEmulator();
296
-
297
- await executeFill(locator, emulator, { selector: '#input', value: 'test' });
164
+ };
298
165
 
299
- // Should have tried multiple times
300
- assert.ok(originalHandle._handle.isActionable.mock.calls.length >= 2);
301
- });
302
- });
166
+ return {
167
+ session: {
168
+ send: mock.fn(() => Promise.resolve({}))
169
+ },
170
+ evaluateInFrame: mock.fn(() => evaluateResult())
171
+ };
172
+ }
303
173
 
304
174
  // ---------------------------------------------------------------------------
305
175
  // Tests: executeFillActive