testdriverai 6.1.5 → 6.1.6
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/agent/lib/commander.js +14 -2
- package/agent/lib/commands.js +47 -8
- package/docs/commands/assert.mdx +1 -0
- package/docs/commands/hover-text.mdx +6 -6
- package/docs/commands/match-image.mdx +5 -4
- package/docs/commands/press-keys.mdx +6 -8
- package/docs/commands/scroll-until-image.mdx +8 -7
- package/docs/commands/scroll-until-text.mdx +7 -6
- package/docs/commands/wait-for-image.mdx +5 -4
- package/docs/commands/wait-for-text.mdx +6 -5
- package/package.json +1 -1
- package/schema.json +19 -1
- package/testdriver/acceptance/scroll-until-image.yaml +5 -0
package/agent/lib/commander.js
CHANGED
|
@@ -154,7 +154,11 @@ commands:
|
|
|
154
154
|
events.log.narration,
|
|
155
155
|
`${object.action} image ${object.path}`,
|
|
156
156
|
);
|
|
157
|
-
response = await commands["match-image"](
|
|
157
|
+
response = await commands["match-image"](
|
|
158
|
+
object.path,
|
|
159
|
+
object.action,
|
|
160
|
+
object.invert,
|
|
161
|
+
);
|
|
158
162
|
break;
|
|
159
163
|
case "wait-for-image":
|
|
160
164
|
emitter.emit(events.log.log, generator.jsonToManual(object));
|
|
@@ -165,6 +169,7 @@ commands:
|
|
|
165
169
|
response = await commands["wait-for-image"](
|
|
166
170
|
object.description,
|
|
167
171
|
object.timeout,
|
|
172
|
+
object.invert,
|
|
168
173
|
);
|
|
169
174
|
break;
|
|
170
175
|
case "wait-for-text":
|
|
@@ -175,6 +180,7 @@ commands:
|
|
|
175
180
|
object.text,
|
|
176
181
|
object.timeout,
|
|
177
182
|
object.method,
|
|
183
|
+
object.invert,
|
|
178
184
|
);
|
|
179
185
|
break;
|
|
180
186
|
case "scroll-until-text":
|
|
@@ -187,6 +193,7 @@ commands:
|
|
|
187
193
|
object.distance,
|
|
188
194
|
object.textMatchMethod,
|
|
189
195
|
object.method,
|
|
196
|
+
object.invert,
|
|
190
197
|
);
|
|
191
198
|
break;
|
|
192
199
|
case "scroll-until-image": {
|
|
@@ -199,6 +206,7 @@ commands:
|
|
|
199
206
|
object.distance,
|
|
200
207
|
object.method,
|
|
201
208
|
object.path,
|
|
209
|
+
object.invert,
|
|
202
210
|
);
|
|
203
211
|
break;
|
|
204
212
|
}
|
|
@@ -217,7 +225,11 @@ commands:
|
|
|
217
225
|
case "assert":
|
|
218
226
|
emitter.emit(events.log.log, generator.jsonToManual(object));
|
|
219
227
|
emitter.emit(events.log.narration, `asserting ${object.expect}`);
|
|
220
|
-
response = await commands.assert(
|
|
228
|
+
response = await commands.assert(
|
|
229
|
+
object.expect,
|
|
230
|
+
object.async,
|
|
231
|
+
object.invert,
|
|
232
|
+
);
|
|
221
233
|
|
|
222
234
|
break;
|
|
223
235
|
case "exec":
|
package/agent/lib/commands.js
CHANGED
|
@@ -170,7 +170,12 @@ const createCommands = (
|
|
|
170
170
|
return result;
|
|
171
171
|
};
|
|
172
172
|
|
|
173
|
-
const assert = async (
|
|
173
|
+
const assert = async (
|
|
174
|
+
assertion,
|
|
175
|
+
shouldThrow = false,
|
|
176
|
+
async = false,
|
|
177
|
+
invert = false,
|
|
178
|
+
) => {
|
|
174
179
|
if (async) {
|
|
175
180
|
shouldThrow = true;
|
|
176
181
|
}
|
|
@@ -178,12 +183,21 @@ const createCommands = (
|
|
|
178
183
|
const handleAssertResponse = (response) => {
|
|
179
184
|
emitter.emit(events.log.log, response);
|
|
180
185
|
|
|
181
|
-
|
|
186
|
+
let valid = response.indexOf("The task passed") > -1;
|
|
187
|
+
|
|
188
|
+
if (invert) {
|
|
189
|
+
valid = !valid;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (valid) {
|
|
182
193
|
return true;
|
|
183
194
|
} else {
|
|
184
195
|
if (shouldThrow) {
|
|
185
196
|
// Is fatal, othewise it just changes the assertion to be true
|
|
186
|
-
throw new MatchError(
|
|
197
|
+
throw new MatchError(
|
|
198
|
+
`AI Assertion failed ${invert && "(Inverted)"}`,
|
|
199
|
+
true,
|
|
200
|
+
);
|
|
187
201
|
} else {
|
|
188
202
|
return false;
|
|
189
203
|
}
|
|
@@ -399,7 +413,7 @@ const createCommands = (
|
|
|
399
413
|
return response.data;
|
|
400
414
|
}
|
|
401
415
|
},
|
|
402
|
-
"match-image": async (relativePath, action = "click") => {
|
|
416
|
+
"match-image": async (relativePath, action = "click", invert = false) => {
|
|
403
417
|
// Resolve the image path relative to the current file
|
|
404
418
|
const resolvedPath = resolveRelativePath(relativePath);
|
|
405
419
|
|
|
@@ -407,6 +421,10 @@ const createCommands = (
|
|
|
407
421
|
|
|
408
422
|
let result = await findImageOnScreen(resolvedPath, image);
|
|
409
423
|
|
|
424
|
+
if (invert) {
|
|
425
|
+
result = !result;
|
|
426
|
+
}
|
|
427
|
+
|
|
410
428
|
if (!result) {
|
|
411
429
|
throw new CommandError(`Image not found: ${resolvedPath}`);
|
|
412
430
|
} else {
|
|
@@ -445,7 +463,7 @@ const createCommands = (
|
|
|
445
463
|
wait: async (timeout = 3000) => {
|
|
446
464
|
return await delay(timeout);
|
|
447
465
|
},
|
|
448
|
-
"wait-for-image": async (description, timeout = 10000) => {
|
|
466
|
+
"wait-for-image": async (description, timeout = 10000, invert = false) => {
|
|
449
467
|
emitter.emit(
|
|
450
468
|
events.log.narration,
|
|
451
469
|
theme.dim(
|
|
@@ -463,6 +481,7 @@ const createCommands = (
|
|
|
463
481
|
`An image matching the description "${description}" appears on screen.`,
|
|
464
482
|
false,
|
|
465
483
|
false,
|
|
484
|
+
invert,
|
|
466
485
|
);
|
|
467
486
|
|
|
468
487
|
durationPassed = new Date().getTime() - startTime;
|
|
@@ -493,7 +512,12 @@ const createCommands = (
|
|
|
493
512
|
);
|
|
494
513
|
}
|
|
495
514
|
},
|
|
496
|
-
"wait-for-text": async (
|
|
515
|
+
"wait-for-text": async (
|
|
516
|
+
text,
|
|
517
|
+
timeout = 5000,
|
|
518
|
+
method = "turbo",
|
|
519
|
+
invert = false,
|
|
520
|
+
) => {
|
|
497
521
|
await redraw.start();
|
|
498
522
|
|
|
499
523
|
emitter.emit(
|
|
@@ -523,7 +547,12 @@ const createCommands = (
|
|
|
523
547
|
);
|
|
524
548
|
|
|
525
549
|
passed = response.data;
|
|
550
|
+
|
|
551
|
+
if (invert) {
|
|
552
|
+
passed = !passed;
|
|
553
|
+
}
|
|
526
554
|
durationPassed = new Date().getTime() - startTime;
|
|
555
|
+
|
|
527
556
|
if (!passed) {
|
|
528
557
|
emitter.emit(
|
|
529
558
|
events.log.narration,
|
|
@@ -551,6 +580,7 @@ const createCommands = (
|
|
|
551
580
|
maxDistance = 10000,
|
|
552
581
|
textMatchMethod = "turbo",
|
|
553
582
|
method = "keyboard",
|
|
583
|
+
invert = false,
|
|
554
584
|
) => {
|
|
555
585
|
await redraw.start();
|
|
556
586
|
|
|
@@ -594,6 +624,11 @@ const createCommands = (
|
|
|
594
624
|
);
|
|
595
625
|
|
|
596
626
|
passed = response.data;
|
|
627
|
+
|
|
628
|
+
if (invert) {
|
|
629
|
+
passed = !passed;
|
|
630
|
+
}
|
|
631
|
+
|
|
597
632
|
if (!passed) {
|
|
598
633
|
emitter.emit(
|
|
599
634
|
events.log.narration,
|
|
@@ -622,6 +657,7 @@ const createCommands = (
|
|
|
622
657
|
maxDistance = 10000,
|
|
623
658
|
method = "keyboard",
|
|
624
659
|
path,
|
|
660
|
+
invert = false,
|
|
625
661
|
) => {
|
|
626
662
|
const needle = description || path;
|
|
627
663
|
|
|
@@ -651,6 +687,7 @@ const createCommands = (
|
|
|
651
687
|
`An image matching the description "${description}" appears on screen.`,
|
|
652
688
|
false,
|
|
653
689
|
false,
|
|
690
|
+
invert,
|
|
654
691
|
);
|
|
655
692
|
}
|
|
656
693
|
|
|
@@ -703,8 +740,10 @@ const createCommands = (
|
|
|
703
740
|
});
|
|
704
741
|
return result.data;
|
|
705
742
|
},
|
|
706
|
-
assert: async (assertion, async = false) => {
|
|
707
|
-
|
|
743
|
+
assert: async (assertion, async = false, invert = false) => {
|
|
744
|
+
let response = await assert(assertion, true, async, invert);
|
|
745
|
+
|
|
746
|
+
return response;
|
|
708
747
|
},
|
|
709
748
|
exec: async (language, code, timeout, silent = false) => {
|
|
710
749
|
emitter.emit(events.log.narration, theme.dim(`calling exec...`), true);
|
package/docs/commands/assert.mdx
CHANGED
|
@@ -22,6 +22,7 @@ The `assert` command validates that a specific condition is true. It ensures tha
|
|
|
22
22
|
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
23
23
|
| `expect` | `string` | The condition to check. This should describe what you expect to see on the screen. |
|
|
24
24
|
| `async` | `boolean` | (Optional) If set to `true`, the test will continue without waiting for the assertion to pass. Default is `false`. |
|
|
25
|
+
| `invert` | `boolean` | (Optional) If set to `true`, will fail if the assertion passes. |
|
|
25
26
|
|
|
26
27
|
## Example usage
|
|
27
28
|
|
|
@@ -18,13 +18,13 @@ The `hover-text` command is used to locate text on the screen based on a descrip
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type | Description
|
|
22
|
-
| :-----------: | :------: |
|
|
23
|
-
| `text` | `string` | The text to find on the screen. Longer and unique is better.
|
|
24
|
-
| `description` | `string` | A description of the text and what it represents. The actual text itself shouldn't be included here.
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| :-----------: | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `text` | `string` | The text to find on the screen. Longer and unique is better. |
|
|
24
|
+
| `description` | `string` | A description of the text and what it represents. The actual text itself shouldn't be included here. |
|
|
25
25
|
| `action` | `string` | The action to take when the text is found. Available actions are: `click`, `right-click`, `double-click`, `hover`. Also supports `drag-start` and `drag-end` for [dragging text](/commands/hover-image#drag-functionality). |
|
|
26
|
-
| `method` | `enum` | The matching algorithm to use. Possible values are `turbo` (default) and `ai
|
|
27
|
-
|
|
|
26
|
+
| `method` | `enum` | The matching algorithm to use. Possible values are `turbo` (default) and `ai`. |
|
|
27
|
+
| `timeout` | `number` | **(Optional)** The duration in milliseconds to wait for the text to appear. Default is `5000` (5 seconds). |
|
|
28
28
|
|
|
29
29
|
## Example usage
|
|
30
30
|
|
|
@@ -18,10 +18,11 @@ The `match-image` command is used to locate an image on the screen by matching i
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type
|
|
22
|
-
| -------- |
|
|
23
|
-
| `path` | `string`
|
|
24
|
-
| `action` | `string`
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| -------- | --------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `path` | `string` | The path to the image that needs to be matched. The path needs to be relative to the current test file |
|
|
24
|
+
| `action` | `string` | The action to take when the image is found. Available actions are: `click`, `right-click`, `double-click`, `hover`. Also supports `drag-start` and `drag-end` for [dragging images](/commands/hover-image#drag-functionality) |
|
|
25
|
+
| `invert` | `boolean` | (Optional) If set to `true`, the command will pass when the specified image is NOT detected. Default is `false`. |
|
|
25
26
|
|
|
26
27
|
## Example usage
|
|
27
28
|
|
|
@@ -28,8 +28,7 @@ The keys supported are the standard [Windows keys](https://learn.microsoft.com/e
|
|
|
28
28
|
|
|
29
29
|
<Tabs>
|
|
30
30
|
<Tab title="Modifiers">
|
|
31
|
-
- `ctrl`, `shift`, `alt`, `command`, `option`, `win`
|
|
32
|
-
- Left/right variants:
|
|
31
|
+
- `ctrl`, `shift`, `alt`, `command`, `option`, `win` - Left/right variants:
|
|
33
32
|
`ctrlleft`, `ctrlright`, `shiftleft`, `shiftright`, `altleft`, `altright`,
|
|
34
33
|
`optionleft`, `optionright`, `winleft`, `winright`
|
|
35
34
|
</Tab>
|
|
@@ -37,9 +36,7 @@ The keys supported are the standard [Windows keys](https://learn.microsoft.com/e
|
|
|
37
36
|
- All ASCII printable characters: letters `a`–`z`, digits `0`–`9`, common
|
|
38
37
|
punctuation, and `space`.
|
|
39
38
|
</Tab>
|
|
40
|
-
<Tab title="Function keys">
|
|
41
|
-
- `f1`–`f24`
|
|
42
|
-
</Tab>
|
|
39
|
+
<Tab title="Function keys">- `f1`–`f24`</Tab>
|
|
43
40
|
<Tab title="Navigation">
|
|
44
41
|
- `up`, `down`, `left`, `right`, `home`, `end`, `pageup`, `pagedown`,
|
|
45
42
|
`pgup`, `pgdn`
|
|
@@ -57,9 +54,10 @@ The keys supported are the standard [Windows keys](https://learn.microsoft.com/e
|
|
|
57
54
|
`separator`
|
|
58
55
|
</Tab>
|
|
59
56
|
<Tab title="Media & Browser">
|
|
60
|
-
- `playpause`, `stop`, `nexttrack`, `prevtrack`, `volumedown`, `volumeup`,
|
|
61
|
-
- `browserback`, `browserforward`, `browserrefresh`,
|
|
62
|
-
|
|
57
|
+
- `playpause`, `stop`, `nexttrack`, `prevtrack`, `volumedown`, `volumeup`,
|
|
58
|
+
`volumemute` - `browserback`, `browserforward`, `browserrefresh`,
|
|
59
|
+
`browsersearch`, `browserstop`, `browserfavorites`, `browserhome` -
|
|
60
|
+
`launchapp1`, `launchapp2`, `launchmail`, `launchmediaselect`
|
|
63
61
|
</Tab>
|
|
64
62
|
<Tab title="IME / International">
|
|
65
63
|
- `hangul`, `hanguel`, `hanja`, `junja`, `kana`, `kanji`, `modechange`,
|
|
@@ -18,13 +18,14 @@ The `scroll-until-image` command is used to scroll the screen in a specified dir
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type
|
|
22
|
-
| :-----------: |
|
|
23
|
-
| `description` | `string`
|
|
24
|
-
| `direction` | `string`
|
|
25
|
-
| `distance` | `number`
|
|
26
|
-
| `method` | `string`
|
|
27
|
-
| `path` | `string`
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| :-----------: | :-------: | :---------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `description` | `string` | A description of the image and what it represents. |
|
|
24
|
+
| `direction` | `string` | (Optional) The direction to scroll. Available directions are: `up`, `down`, `left`, `right`. Defaults to `down`. |
|
|
25
|
+
| `distance` | `number` | (Optional) The maximum number of pixels to scroll before giving up. Default is `10000`. |
|
|
26
|
+
| `method` | `string` | (Optional) The method to use to scroll the page. Available methods are: `mouse` and `keyboard`. Defaults to `keyboard`. |
|
|
27
|
+
| `path` | `string` | (Optional) The relative path to the image file that needs to be matched on the screen. |
|
|
28
|
+
| `invert` | `boolean` | (Optional) If set to `true`, the command will scroll until the specified image is NOT detected. Default is `false`. |
|
|
28
29
|
|
|
29
30
|
<Note>
|
|
30
31
|
Use either the `description` or `path` argument to match an image on the
|
|
@@ -18,12 +18,13 @@ The `scroll-until-text` command is used to scroll the screen in a specified dire
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type
|
|
22
|
-
| :---------: |
|
|
23
|
-
| `text` | `string`
|
|
24
|
-
| `direction` | `string`
|
|
25
|
-
| `method` | `string`
|
|
26
|
-
| `distance` | `number`
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| :---------: | :-------: | :---------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `text` | `string` | The text to find on the screen. Longer and unique are better. Note this is **case sensitive** |
|
|
24
|
+
| `direction` | `string` | (Optional) The direction to scroll. Available directions are: `up`, `down`, `left`, `right`. Defaults to `down`. |
|
|
25
|
+
| `method` | `string` | (Optional) The method to use to scroll the page. Available methods are: `mouse` and `keyboard`. Defaults to `keyboard`. |
|
|
26
|
+
| `distance` | `number` | (Optional) The maximum number of pixels to scroll before giving up. Default is `10000`. |
|
|
27
|
+
| `invert` | `boolean` | (Optional) If set to `true`, the command will scroll until the specified text is NOT detected. Default is `false`. |
|
|
27
28
|
|
|
28
29
|
<Note>
|
|
29
30
|
If the method is `keyboard` it just searches for the string by doing `ctrl + f`.
|
|
@@ -18,10 +18,11 @@ The `wait-for-image` command waits until the specified image is detected on the
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type
|
|
22
|
-
| :-----------: |
|
|
23
|
-
| `description` | `string`
|
|
24
|
-
| `timeout` | `number`
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| :-----------: | :-------: | :---------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `description` | `string` | A description of the image. |
|
|
24
|
+
| `timeout` | `number` | (Optional) The duration in milliseconds to wait for the image to appear. Default is `10000` (10 seconds). |
|
|
25
|
+
| `invert` | `boolean` | (Optional) If set to `true`, the command will wait until the specified image is NOT detected. Default is `false`. |
|
|
25
26
|
|
|
26
27
|
## Example usage
|
|
27
28
|
|
|
@@ -18,11 +18,12 @@ The `wait-for-text` command waits until the specified text is detected on the sc
|
|
|
18
18
|
|
|
19
19
|
## Arguments
|
|
20
20
|
|
|
21
|
-
| Argument | Type
|
|
22
|
-
| :-------: |
|
|
23
|
-
| `text` | `string`
|
|
24
|
-
| `timeout` | `number`
|
|
25
|
-
| `method` | `enum`
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| :-------: | :-------: | :--------------------------------------------------------------------------------------------------------------- |
|
|
23
|
+
| `text` | `string` | The text to find on the screen. |
|
|
24
|
+
| `timeout` | `number` | (Optional) The duration in milliseconds to wait for the text to appear. Default is `5000` (5 seconds). |
|
|
25
|
+
| `method` | `enum` | (Optional) The matching algorithm to use. Possible values are `ai` and `turbo`. Default is `turbo` |
|
|
26
|
+
| `invert` | `boolean` | (Optional) If set to `true`, the command will wait until the specified text is NOT detected. Default is `false`. |
|
|
26
27
|
|
|
27
28
|
## Example usage
|
|
28
29
|
|
package/package.json
CHANGED
package/schema.json
CHANGED
|
@@ -474,6 +474,9 @@
|
|
|
474
474
|
"drag-start",
|
|
475
475
|
"drag-end"
|
|
476
476
|
]
|
|
477
|
+
},
|
|
478
|
+
"invert": {
|
|
479
|
+
"type": "boolean"
|
|
477
480
|
}
|
|
478
481
|
}
|
|
479
482
|
},
|
|
@@ -493,6 +496,9 @@
|
|
|
493
496
|
},
|
|
494
497
|
"timeout": {
|
|
495
498
|
"type": "integer"
|
|
499
|
+
},
|
|
500
|
+
"invert": {
|
|
501
|
+
"type": "boolean"
|
|
496
502
|
}
|
|
497
503
|
}
|
|
498
504
|
},
|
|
@@ -519,6 +525,9 @@
|
|
|
519
525
|
"ai",
|
|
520
526
|
"turbo"
|
|
521
527
|
]
|
|
528
|
+
},
|
|
529
|
+
"invert": {
|
|
530
|
+
"type": "boolean"
|
|
522
531
|
}
|
|
523
532
|
}
|
|
524
533
|
},
|
|
@@ -555,6 +564,9 @@
|
|
|
555
564
|
"keyboard",
|
|
556
565
|
"mouse"
|
|
557
566
|
]
|
|
567
|
+
},
|
|
568
|
+
"invert": {
|
|
569
|
+
"type": "boolean"
|
|
558
570
|
}
|
|
559
571
|
}
|
|
560
572
|
},
|
|
@@ -593,6 +605,9 @@
|
|
|
593
605
|
"keyboard",
|
|
594
606
|
"mouse"
|
|
595
607
|
]
|
|
608
|
+
},
|
|
609
|
+
"invert": {
|
|
610
|
+
"type": "boolean"
|
|
596
611
|
}
|
|
597
612
|
},
|
|
598
613
|
"anyOf": [
|
|
@@ -660,6 +675,9 @@
|
|
|
660
675
|
},
|
|
661
676
|
"async": {
|
|
662
677
|
"type": "boolean"
|
|
678
|
+
},
|
|
679
|
+
"invert": {
|
|
680
|
+
"type": "boolean"
|
|
663
681
|
}
|
|
664
682
|
}
|
|
665
683
|
},
|
|
@@ -1045,4 +1063,4 @@
|
|
|
1045
1063
|
}
|
|
1046
1064
|
}
|
|
1047
1065
|
}
|
|
1048
|
-
}
|
|
1066
|
+
}
|