askui 0.18.0 → 0.19.0
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/cjs/core/ai-element/ai-element-collection.d.ts +10 -0
- package/dist/cjs/core/ai-element/ai-element-collection.js +78 -0
- package/dist/cjs/core/ai-element/ai-element-error.d.ts +2 -0
- package/dist/cjs/core/ai-element/ai-element-error.js +6 -0
- package/dist/cjs/core/ai-element/ai-element.d.ts +27 -0
- package/dist/cjs/core/ai-element/ai-element.js +31 -0
- package/dist/cjs/core/model/custom-element-json.d.ts +32 -15
- package/dist/cjs/core/model/custom-element.d.ts +3 -2
- package/dist/cjs/core/model/custom-element.js +4 -2
- package/dist/cjs/core/reporting/step-reporter.js +15 -6
- package/dist/cjs/execution/dsl.d.ts +488 -113
- package/dist/cjs/execution/dsl.js +519 -113
- package/dist/cjs/execution/index.d.ts +1 -1
- package/dist/cjs/execution/index.js +11 -3
- package/dist/cjs/execution/inference-client.js +9 -4
- package/dist/cjs/execution/ui-control-client-dependency-builder.d.ts +1 -0
- package/dist/cjs/execution/ui-control-client-dependency-builder.js +6 -3
- package/dist/cjs/execution/ui-control-client.d.ts +101 -16
- package/dist/cjs/execution/ui-control-client.js +142 -52
- package/dist/cjs/execution/ui-controller-client-interface.d.ts +2 -0
- package/dist/cjs/execution/ui-controller-client.d.ts +1 -0
- package/dist/cjs/execution/ui-controller-client.js +11 -1
- package/dist/cjs/execution/ui-controller-not-connected-error.d.ts +4 -0
- package/dist/cjs/execution/ui-controller-not-connected-error.js +12 -0
- package/dist/cjs/main.d.ts +1 -1
- package/dist/cjs/main.js +12 -3
- package/dist/cjs/utils/analytics/analytics.d.ts +3 -1
- package/dist/cjs/utils/analytics/analytics.js +5 -0
- package/dist/cjs/utils/http/custom-errors/index.js +1 -1
- package/dist/cjs/utils/http/http-client-got.js +46 -20
- package/dist/esm/core/ai-element/ai-element-collection.d.ts +10 -0
- package/dist/esm/core/ai-element/ai-element-collection.js +71 -0
- package/dist/esm/core/ai-element/ai-element-error.d.ts +2 -0
- package/dist/esm/core/ai-element/ai-element-error.js +2 -0
- package/dist/esm/core/ai-element/ai-element.d.ts +27 -0
- package/dist/esm/core/ai-element/ai-element.js +28 -0
- package/dist/esm/core/model/custom-element-json.d.ts +32 -15
- package/dist/esm/core/model/custom-element.d.ts +3 -2
- package/dist/esm/core/model/custom-element.js +4 -2
- package/dist/esm/core/reporting/step-reporter.js +15 -6
- package/dist/esm/execution/dsl.d.ts +488 -113
- package/dist/esm/execution/dsl.js +519 -113
- package/dist/esm/execution/index.d.ts +1 -1
- package/dist/esm/execution/index.js +1 -1
- package/dist/esm/execution/inference-client.js +9 -4
- package/dist/esm/execution/ui-control-client-dependency-builder.d.ts +1 -0
- package/dist/esm/execution/ui-control-client-dependency-builder.js +6 -3
- package/dist/esm/execution/ui-control-client.d.ts +101 -16
- package/dist/esm/execution/ui-control-client.js +142 -49
- package/dist/esm/execution/ui-controller-client-interface.d.ts +2 -0
- package/dist/esm/execution/ui-controller-client.d.ts +1 -0
- package/dist/esm/execution/ui-controller-client.js +11 -1
- package/dist/esm/execution/ui-controller-not-connected-error.d.ts +4 -0
- package/dist/esm/execution/ui-controller-not-connected-error.js +8 -0
- package/dist/esm/main.d.ts +1 -1
- package/dist/esm/main.js +1 -1
- package/dist/esm/utils/analytics/analytics.d.ts +3 -1
- package/dist/esm/utils/analytics/analytics.js +5 -0
- package/dist/esm/utils/http/custom-errors/index.js +1 -1
- package/dist/esm/utils/http/http-client-got.js +46 -20
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export * from './ui-control-client';
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports
|
|
4
|
-
var ui_control_client_1 = require("./ui-control-client");
|
|
5
|
-
Object.defineProperty(exports, "UiControlClient", { enumerable: true, get: function () { return ui_control_client_1.UiControlClient; } });
|
|
13
|
+
__exportStar(require("./ui-control-client"), exports);
|
|
@@ -62,12 +62,17 @@ class InferenceClient {
|
|
|
62
62
|
inference(customElements = [], image, instruction) {
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
64
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
65
|
-
const response = yield this.httpClient.post(this.urls.inference, {
|
|
66
|
-
customElements,
|
|
65
|
+
const response = yield this.httpClient.post(this.urls.inference, this.urls.inference.includes('v4-experimental') ? {
|
|
67
66
|
image: resizedImage.base64Image,
|
|
68
67
|
instruction,
|
|
69
|
-
|
|
70
|
-
}
|
|
68
|
+
tasks: ['OCR'],
|
|
69
|
+
}
|
|
70
|
+
: {
|
|
71
|
+
customElements,
|
|
72
|
+
image: resizedImage.base64Image,
|
|
73
|
+
instruction,
|
|
74
|
+
modelComposition: this.modelComposition,
|
|
75
|
+
});
|
|
71
76
|
InferenceClient.logMetaInformation(response);
|
|
72
77
|
return ui_control_commands_1.InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
73
78
|
});
|
|
@@ -8,6 +8,7 @@ export declare class UiControlClientDependencyBuilder {
|
|
|
8
8
|
static build(clientArgs: ClientArgsWithDefaults): Promise<{
|
|
9
9
|
executionRuntime: ExecutionRuntime;
|
|
10
10
|
stepReporter: StepReporter;
|
|
11
|
+
workspaceId: string | undefined;
|
|
11
12
|
}>;
|
|
12
13
|
static getClientArgsWithDefaults(clientArgs: ClientArgs): Promise<ClientArgsWithDefaults>;
|
|
13
14
|
}
|
|
@@ -36,29 +36,32 @@ class UiControlClientDependencyBuilder {
|
|
|
36
36
|
var _a;
|
|
37
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
38
|
const httpClient = yield UiControlClientDependencyBuilder.buildHttpClient(clientArgs);
|
|
39
|
-
return new inference_client_1.InferenceClient(clientArgs.inferenceServerUrl, httpClient, clientArgs.resize, (_a = clientArgs.credentials) === null || _a === void 0 ? void 0 : _a.workspaceId, clientArgs.modelComposition);
|
|
39
|
+
return new inference_client_1.InferenceClient(clientArgs.inferenceServerUrl, httpClient, clientArgs.resize, (_a = clientArgs.credentials) === null || _a === void 0 ? void 0 : _a.workspaceId, clientArgs.modelComposition, clientArgs.inferenceServerApiVersion);
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
static buildUiControllerClient(clientArgs) {
|
|
43
43
|
return new ui_controller_client_1.UiControllerClient(clientArgs.uiControllerUrl);
|
|
44
44
|
}
|
|
45
45
|
static build(clientArgs) {
|
|
46
|
+
var _a;
|
|
46
47
|
return __awaiter(this, void 0, void 0, function* () {
|
|
47
48
|
const uiControllerClient = UiControlClientDependencyBuilder.buildUiControllerClient(clientArgs);
|
|
48
49
|
const inferenceClient = yield UiControlClientDependencyBuilder.buildInferenceClient(clientArgs);
|
|
49
50
|
const stepReporter = new reporting_1.StepReporter(clientArgs.reporter);
|
|
51
|
+
const workspaceId = (_a = clientArgs.credentials) === null || _a === void 0 ? void 0 : _a.workspaceId;
|
|
50
52
|
return {
|
|
51
53
|
executionRuntime: new execution_runtime_1.ExecutionRuntime(uiControllerClient, inferenceClient, stepReporter),
|
|
52
54
|
stepReporter,
|
|
55
|
+
workspaceId,
|
|
53
56
|
};
|
|
54
57
|
});
|
|
55
58
|
}
|
|
56
59
|
static getClientArgsWithDefaults(clientArgs) {
|
|
57
|
-
var _a, _b, _c, _d, _e;
|
|
60
|
+
var _a, _b, _c, _d, _e, _f;
|
|
58
61
|
return __awaiter(this, void 0, void 0, function* () {
|
|
59
62
|
return Object.assign(Object.assign({}, clientArgs), { context: {
|
|
60
63
|
isCi: (_b = (_a = clientArgs.context) === null || _a === void 0 ? void 0 : _a.isCi) !== null && _b !== void 0 ? _b : is_ci_1.default,
|
|
61
|
-
}, credentials: (0, read_credentials_1.readCredentials)(clientArgs),
|
|
64
|
+
}, credentials: (0, read_credentials_1.readCredentials)(clientArgs), inferenceServerApiVersion: (_c = clientArgs.inferenceServerApiVersion) !== null && _c !== void 0 ? _c : 'v3', inferenceServerUrl: (_d = clientArgs.inferenceServerUrl) !== null && _d !== void 0 ? _d : 'https://inference.askui.com', proxyAgents: (_e = clientArgs.proxyAgents) !== null && _e !== void 0 ? _e : (yield (0, proxy_builder_1.envProxyAgents)()), uiControllerUrl: (_f = clientArgs.uiControllerUrl) !== null && _f !== void 0 ? _f : 'http://127.0.0.1:6769' });
|
|
62
65
|
});
|
|
63
66
|
}
|
|
64
67
|
}
|
|
@@ -1,12 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Exec, Executable, FluentFilters, ApiCommands, PC_AND_MODIFIER_KEY } from './dsl';
|
|
1
|
+
import { Exec, Executable, FluentFilters, ApiCommands, PC_AND_MODIFIER_KEY, CommandExecutorContext } from './dsl';
|
|
3
2
|
import { UiControllerClientConnectionState } from './ui-controller-client-connection-state';
|
|
4
3
|
import { Annotation } from '../core/annotation/annotation';
|
|
5
4
|
import { AnnotationRequest } from '../core/model/annotation-result/annotation-interface';
|
|
6
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
7
6
|
import { ClientArgs } from './ui-controller-client-interface';
|
|
8
7
|
export declare type RelationsForConvenienceMethods = 'nearestTo' | 'leftOf' | 'above' | 'rightOf' | 'below' | 'contains';
|
|
8
|
+
export declare type TextMatchingOption = 'similar' | 'exact' | 'regex';
|
|
9
|
+
export declare type ElementExistsQueryType = 'otherElement' | 'switch' | 'element' | 'container' | 'checkbox' | 'element' | 'button' | 'table' | 'text' | 'icon' | 'image' | 'textfield';
|
|
10
|
+
export interface ElementExistsQueryText {
|
|
11
|
+
value: string;
|
|
12
|
+
matching?: TextMatchingOption;
|
|
13
|
+
}
|
|
14
|
+
export interface ElementExistsQueryRelation {
|
|
15
|
+
type: RelationsForConvenienceMethods;
|
|
16
|
+
text: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ElementExistsQuery {
|
|
19
|
+
type: keyof Pick<FluentFilters, ElementExistsQueryType>;
|
|
20
|
+
text?: ElementExistsQueryText;
|
|
21
|
+
relation?: ElementExistsQueryRelation;
|
|
22
|
+
}
|
|
23
|
+
export interface ExpectExistenceElement extends ElementExistsQuery {
|
|
24
|
+
exists: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ExpectAllExistResult {
|
|
27
|
+
allExist: boolean;
|
|
28
|
+
elements: ExpectExistenceElement[];
|
|
29
|
+
}
|
|
9
30
|
export declare class UiControlClient extends ApiCommands {
|
|
31
|
+
private workspaceId;
|
|
10
32
|
private executionRuntime;
|
|
11
33
|
private stepReporter;
|
|
12
34
|
private constructor();
|
|
@@ -34,8 +56,9 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
34
56
|
annotateInteractively(): Promise<void>;
|
|
35
57
|
private escapeSeparatorString;
|
|
36
58
|
private buildInstruction;
|
|
37
|
-
|
|
38
|
-
|
|
59
|
+
private getAIElementsByNames;
|
|
60
|
+
fluentCommandExecutor(instructionString: string, context?: CommandExecutorContext): Promise<void>;
|
|
61
|
+
getterExecutor(instruction: string, context?: CommandExecutorContext): Promise<DetectedElement[]>;
|
|
39
62
|
private secretText;
|
|
40
63
|
private getAndResetSecretText;
|
|
41
64
|
/**
|
|
@@ -190,8 +213,8 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
190
213
|
* @param {Object} params - Object containing required `label` property and
|
|
191
214
|
* optional `relation` property.
|
|
192
215
|
* @property {string} params.label - The label for the checkbox.
|
|
193
|
-
* @property {Object} params.relation - Object describing the relationship between
|
|
194
|
-
*
|
|
216
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
217
|
+
* the clicked checkbox and another element.
|
|
195
218
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
196
219
|
*/
|
|
197
220
|
clickCheckbox(params: {
|
|
@@ -213,7 +236,7 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
213
236
|
* @param {Object} params - Object containing required `label` property and
|
|
214
237
|
* optional `relation` property.
|
|
215
238
|
* @property {string} params.label - The label for the checkbox.
|
|
216
|
-
* @property {Object} params.relation - Object describing the relationship between
|
|
239
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
217
240
|
* the clicked checkbox and another element.
|
|
218
241
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
219
242
|
*/
|
|
@@ -266,41 +289,103 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
266
289
|
}): Promise<void>;
|
|
267
290
|
/**
|
|
268
291
|
* Click on a specific text.
|
|
269
|
-
* You can also use a RegEx or match the text exactly by
|
|
292
|
+
* You can also use a RegEx or match the text exactly by specifying the specific flag.
|
|
270
293
|
* Use a relation to find the text in relation to a specific text.
|
|
271
294
|
*
|
|
272
295
|
* **Examples:**
|
|
273
296
|
* ```typescript
|
|
274
297
|
* // Click text that matches exactly
|
|
275
|
-
* await aui.clickText({text: 'askui',
|
|
298
|
+
* await aui.clickText({text: 'askui', matching: 'similar'})
|
|
276
299
|
*
|
|
277
300
|
* // Click text that contains 'pie' or 'cake' or 'Pie' or 'Cake'
|
|
278
|
-
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*',
|
|
301
|
+
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*', matching: 'regex'})
|
|
279
302
|
*
|
|
280
303
|
* // Click the text 'TERMINAL' that is left of the text 'Ports'
|
|
281
304
|
* await aui.clickText({
|
|
282
305
|
* text: 'TERMINAL',
|
|
283
|
-
*
|
|
306
|
+
* matching: "exact",
|
|
284
307
|
* relation: { type: 'leftOf', text: 'PORTS' }
|
|
285
308
|
* })
|
|
286
309
|
* ```
|
|
310
|
+
*
|
|
287
311
|
* @param {Object} params - Object containing required `text` property and optional properties
|
|
288
312
|
* for regular expression matching and relation.
|
|
289
313
|
* @property {string} params.text - The text to be clicked.
|
|
290
|
-
* @property {string} params.
|
|
291
|
-
*
|
|
292
|
-
* @property {Object} params.relation - Object describing the relationship between the
|
|
293
|
-
*
|
|
314
|
+
* @property {string} params.matching - Whether the text is matched using similarity,
|
|
315
|
+
* exact match or a regular expression.
|
|
316
|
+
* @property {Object} [params.relation] - Object describing the relationship between the
|
|
317
|
+
* clicked text and another element.
|
|
294
318
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
295
319
|
* @property {string} params.relation.text - The label or text associated with the
|
|
296
320
|
* related element or state.
|
|
297
321
|
*/
|
|
298
322
|
clickText(params: {
|
|
299
323
|
text: string;
|
|
300
|
-
|
|
324
|
+
matching: TextMatchingOption;
|
|
301
325
|
relation?: {
|
|
302
326
|
type: RelationsForConvenienceMethods;
|
|
303
327
|
text: string;
|
|
304
328
|
};
|
|
305
329
|
}): Promise<void>;
|
|
330
|
+
private evaluateMatchingProperty;
|
|
331
|
+
/**
|
|
332
|
+
* Check if one or multiple elements are detected.
|
|
333
|
+
*
|
|
334
|
+
* **Examples:**
|
|
335
|
+
* ```typescript
|
|
336
|
+
* await aui.expectAllExist([
|
|
337
|
+
* {
|
|
338
|
+
* type: 'text',
|
|
339
|
+
* text: {
|
|
340
|
+
* value: 'Switch to Dark',
|
|
341
|
+
* matching: 'similar'
|
|
342
|
+
* }
|
|
343
|
+
* },
|
|
344
|
+
* ]);
|
|
345
|
+
*
|
|
346
|
+
* // Check for existence of multiple elements
|
|
347
|
+
* await aui.expectAllExist([
|
|
348
|
+
* {
|
|
349
|
+
* type: 'textfield',
|
|
350
|
+
* relation: {
|
|
351
|
+
* type: 'rightOf',
|
|
352
|
+
* text: 'Email:'
|
|
353
|
+
* }
|
|
354
|
+
* },
|
|
355
|
+
* {
|
|
356
|
+
* type: 'element',
|
|
357
|
+
* text: {
|
|
358
|
+
* value: 'Switch to Dark'
|
|
359
|
+
* }
|
|
360
|
+
* },
|
|
361
|
+
* ]);
|
|
362
|
+
*
|
|
363
|
+
* // Validate existence
|
|
364
|
+
* const exists = await aui.expectAllExist([...]);
|
|
365
|
+
* exists.allExist // true when every element exists
|
|
366
|
+
*
|
|
367
|
+
* // Check which elements do not exist
|
|
368
|
+
* // with the elements property
|
|
369
|
+
* const nonExistentElements = exists.elements.filter((e) => e.exists===false)
|
|
370
|
+
* ```
|
|
371
|
+
*
|
|
372
|
+
* @param {ElementExistsQuery[]} query - Objects containing the required property
|
|
373
|
+
* 'type' and the optional properties
|
|
374
|
+
* 'text' and 'relation'.
|
|
375
|
+
* @property {string} query.type - The type of the element: 'otherElement' | 'switch' |
|
|
376
|
+
* 'element' | 'container' | 'checkbox' | 'element' |
|
|
377
|
+
* 'button' | 'table' | 'text' | 'icon' | 'image' | 'textfield'
|
|
378
|
+
* @property {Object} [query.text] - Object containing value and matching strategy.
|
|
379
|
+
* @property {string} query.text.value - The text to match for.
|
|
380
|
+
* @property {string} [query.text.matching] - Whether the text is matched using similarity,
|
|
381
|
+
* exact match or a regular expression.
|
|
382
|
+
* @property {Object} [query.relation] - Object describing the relationship between the
|
|
383
|
+
* clicked text and another element.
|
|
384
|
+
* @property {RelationsForConvenienceMethods} query.relation.type - The type of relation.
|
|
385
|
+
* @property {string} query.relation.text - The label or text associated with the
|
|
386
|
+
* related element or state.
|
|
387
|
+
* @returns {ExpectAllExistResult.allExist} - If every element exists.
|
|
388
|
+
* @returns {ExpectAllExistResult.elements} - ExpectExistenceElement[].
|
|
389
|
+
*/
|
|
390
|
+
expectAllExist(query: ElementExistsQuery[]): Promise<ExpectAllExistResult>;
|
|
306
391
|
}
|
|
@@ -8,20 +8,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
12
|
exports.UiControlClient = void 0;
|
|
16
|
-
const
|
|
13
|
+
const yup_1 = require("yup");
|
|
17
14
|
const custom_element_1 = require("../core/model/custom-element");
|
|
18
15
|
const dsl_1 = require("./dsl");
|
|
19
16
|
const annotation_writer_1 = require("../core/annotation/annotation-writer");
|
|
20
17
|
const logger_1 = require("../lib/logger");
|
|
21
18
|
const ui_control_client_dependency_builder_1 = require("./ui-control-client-dependency-builder");
|
|
19
|
+
const ai_element_collection_1 = require("../core/ai-element/ai-element-collection");
|
|
22
20
|
class UiControlClient extends dsl_1.ApiCommands {
|
|
23
|
-
constructor(executionRuntime, stepReporter) {
|
|
21
|
+
constructor(workspaceId, executionRuntime, stepReporter) {
|
|
24
22
|
super();
|
|
23
|
+
this.workspaceId = workspaceId;
|
|
25
24
|
this.executionRuntime = executionRuntime;
|
|
26
25
|
this.stepReporter = stepReporter;
|
|
27
26
|
this.secretText = undefined;
|
|
@@ -30,8 +29,8 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
30
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
31
30
|
const builder = ui_control_client_dependency_builder_1.UiControlClientDependencyBuilder;
|
|
32
31
|
const clientArgsWithDefaults = yield builder.getClientArgsWithDefaults(clientArgs);
|
|
33
|
-
const { executionRuntime, stepReporter } = yield builder.build(clientArgsWithDefaults);
|
|
34
|
-
return new UiControlClient(executionRuntime, stepReporter);
|
|
32
|
+
const { workspaceId, executionRuntime, stepReporter, } = yield builder.build(clientArgsWithDefaults);
|
|
33
|
+
return new UiControlClient(workspaceId, executionRuntime, stepReporter);
|
|
35
34
|
});
|
|
36
35
|
}
|
|
37
36
|
/**
|
|
@@ -125,9 +124,20 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
125
124
|
};
|
|
126
125
|
});
|
|
127
126
|
}
|
|
128
|
-
|
|
127
|
+
getAIElementsByNames(names) {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
// eslint-disable-next-line max-len
|
|
130
|
+
const workspaceAIElementCollection = yield ai_element_collection_1.AIElementCollection.collectForWorkspaceId(this.workspaceId);
|
|
131
|
+
return workspaceAIElementCollection.getByNames(names);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
fluentCommandExecutor(instructionString, context = { customElementsJson: [], aiElementNames: [] }) {
|
|
129
135
|
return __awaiter(this, void 0, void 0, function* () {
|
|
130
|
-
const
|
|
136
|
+
const aiElements = yield this.getAIElementsByNames(context.aiElementNames);
|
|
137
|
+
const instruction = yield this.buildInstruction(instructionString, [
|
|
138
|
+
...context.customElementsJson,
|
|
139
|
+
...aiElements,
|
|
140
|
+
]);
|
|
131
141
|
logger_1.logger.debug(instruction);
|
|
132
142
|
try {
|
|
133
143
|
yield this.stepReporter.resetStep(instruction);
|
|
@@ -141,12 +151,16 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
141
151
|
}
|
|
142
152
|
});
|
|
143
153
|
}
|
|
144
|
-
getterExecutor(instruction,
|
|
154
|
+
getterExecutor(instruction, context = { customElementsJson: [], aiElementNames: [] }) {
|
|
145
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
-
const
|
|
156
|
+
const aiElements = yield this.getAIElementsByNames(context.aiElementNames);
|
|
157
|
+
const customElements = yield custom_element_1.CustomElement.fromJsonListWithImagePathOrImage(context.customElementsJson);
|
|
147
158
|
const stringWithoutSeparators = this.escapeSeparatorString(instruction);
|
|
148
159
|
logger_1.logger.debug(stringWithoutSeparators);
|
|
149
|
-
return this.executionRuntime.getDetectedElements(instruction,
|
|
160
|
+
return this.executionRuntime.getDetectedElements(instruction, [
|
|
161
|
+
...customElements,
|
|
162
|
+
...aiElements,
|
|
163
|
+
]);
|
|
150
164
|
});
|
|
151
165
|
}
|
|
152
166
|
getAndResetSecretText() {
|
|
@@ -331,30 +345,22 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
331
345
|
}
|
|
332
346
|
// eslint-disable-next-line class-methods-use-this
|
|
333
347
|
evaluateRelation(command, relation, text) {
|
|
334
|
-
let commando = command;
|
|
335
348
|
switch (relation) {
|
|
336
|
-
case 'nearestTo':
|
|
337
|
-
commando = command.nearestTo().text(text);
|
|
338
|
-
break;
|
|
339
349
|
case 'leftOf':
|
|
340
|
-
|
|
341
|
-
break;
|
|
350
|
+
return command.leftOf().text(text);
|
|
342
351
|
case 'above':
|
|
343
|
-
|
|
344
|
-
break;
|
|
352
|
+
return command.above().text(text);
|
|
345
353
|
case 'rightOf':
|
|
346
|
-
|
|
347
|
-
break;
|
|
354
|
+
return command.rightOf().text(text);
|
|
348
355
|
case 'below':
|
|
349
|
-
|
|
350
|
-
break;
|
|
356
|
+
return command.below().text(text);
|
|
351
357
|
case 'contains':
|
|
352
|
-
|
|
353
|
-
|
|
358
|
+
return command.contains().text(text);
|
|
359
|
+
case 'nearestTo':
|
|
360
|
+
return command.nearestTo().text(text);
|
|
354
361
|
default:
|
|
355
|
-
throw new
|
|
362
|
+
throw new yup_1.ValidationError(`'relation' has to be 'nearestTo', 'leftOf', 'above', 'rightOf', 'below' or 'contains' but was '${relation}'`);
|
|
356
363
|
}
|
|
357
|
-
return commando;
|
|
358
364
|
}
|
|
359
365
|
/**
|
|
360
366
|
* Click a button with a specific label.
|
|
@@ -400,8 +406,8 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
400
406
|
* @param {Object} params - Object containing required `label` property and
|
|
401
407
|
* optional `relation` property.
|
|
402
408
|
* @property {string} params.label - The label for the checkbox.
|
|
403
|
-
* @property {Object} params.relation - Object describing the relationship between
|
|
404
|
-
*
|
|
409
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
410
|
+
* the clicked checkbox and another element.
|
|
405
411
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
406
412
|
*/
|
|
407
413
|
clickCheckbox(params) {
|
|
@@ -429,7 +435,7 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
429
435
|
* @param {Object} params - Object containing required `label` property and
|
|
430
436
|
* optional `relation` property.
|
|
431
437
|
* @property {string} params.label - The label for the checkbox.
|
|
432
|
-
* @property {Object} params.relation - Object describing the relationship between
|
|
438
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
433
439
|
* the clicked checkbox and another element.
|
|
434
440
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
435
441
|
*/
|
|
@@ -493,31 +499,32 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
493
499
|
}
|
|
494
500
|
/**
|
|
495
501
|
* Click on a specific text.
|
|
496
|
-
* You can also use a RegEx or match the text exactly by
|
|
502
|
+
* You can also use a RegEx or match the text exactly by specifying the specific flag.
|
|
497
503
|
* Use a relation to find the text in relation to a specific text.
|
|
498
504
|
*
|
|
499
505
|
* **Examples:**
|
|
500
506
|
* ```typescript
|
|
501
507
|
* // Click text that matches exactly
|
|
502
|
-
* await aui.clickText({text: 'askui',
|
|
508
|
+
* await aui.clickText({text: 'askui', matching: 'similar'})
|
|
503
509
|
*
|
|
504
510
|
* // Click text that contains 'pie' or 'cake' or 'Pie' or 'Cake'
|
|
505
|
-
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*',
|
|
511
|
+
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*', matching: 'regex'})
|
|
506
512
|
*
|
|
507
513
|
* // Click the text 'TERMINAL' that is left of the text 'Ports'
|
|
508
514
|
* await aui.clickText({
|
|
509
515
|
* text: 'TERMINAL',
|
|
510
|
-
*
|
|
516
|
+
* matching: "exact",
|
|
511
517
|
* relation: { type: 'leftOf', text: 'PORTS' }
|
|
512
518
|
* })
|
|
513
519
|
* ```
|
|
520
|
+
*
|
|
514
521
|
* @param {Object} params - Object containing required `text` property and optional properties
|
|
515
522
|
* for regular expression matching and relation.
|
|
516
523
|
* @property {string} params.text - The text to be clicked.
|
|
517
|
-
* @property {string} params.
|
|
518
|
-
*
|
|
519
|
-
* @property {Object} params.relation - Object describing the relationship between the
|
|
520
|
-
*
|
|
524
|
+
* @property {string} params.matching - Whether the text is matched using similarity,
|
|
525
|
+
* exact match or a regular expression.
|
|
526
|
+
* @property {Object} [params.relation] - Object describing the relationship between the
|
|
527
|
+
* clicked text and another element.
|
|
521
528
|
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
522
529
|
* @property {string} params.relation.text - The label or text associated with the
|
|
523
530
|
* related element or state.
|
|
@@ -525,24 +532,107 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
525
532
|
clickText(params) {
|
|
526
533
|
return __awaiter(this, void 0, void 0, function* () {
|
|
527
534
|
let command = this.click().text();
|
|
528
|
-
|
|
529
|
-
case 'similar':
|
|
530
|
-
command = command.withText(params.text);
|
|
531
|
-
break;
|
|
532
|
-
case 'exact':
|
|
533
|
-
command = command.withExactText(params.text);
|
|
534
|
-
break;
|
|
535
|
-
case 'regex':
|
|
536
|
-
command = command.withTextRegex(params.text);
|
|
537
|
-
break;
|
|
538
|
-
default:
|
|
539
|
-
throw new ValidationError_1.default('"type" must be "similar", "exact" or "regex"');
|
|
540
|
-
}
|
|
535
|
+
command = this.evaluateMatchingProperty(command, { value: params.text, matching: params.matching });
|
|
541
536
|
if (params.relation) {
|
|
542
537
|
command = this.evaluateRelation(command, params.relation.type, params.relation.text);
|
|
543
538
|
}
|
|
544
539
|
yield command.exec();
|
|
545
540
|
});
|
|
546
541
|
}
|
|
542
|
+
// eslint-disable-next-line class-methods-use-this
|
|
543
|
+
evaluateMatchingProperty(command, text) {
|
|
544
|
+
var _a;
|
|
545
|
+
switch ((_a = text.matching) !== null && _a !== void 0 ? _a : 'similar') {
|
|
546
|
+
case 'exact':
|
|
547
|
+
return command.withExactText(text.value);
|
|
548
|
+
case 'regex':
|
|
549
|
+
return command.withTextRegex(text.value);
|
|
550
|
+
case 'similar':
|
|
551
|
+
return command.withText(text.value);
|
|
552
|
+
default:
|
|
553
|
+
throw new yup_1.ValidationError(`'text.matching' property has to be 'similar', 'exact' or 'regex' but was '${text.matching}'`);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Check if one or multiple elements are detected.
|
|
558
|
+
*
|
|
559
|
+
* **Examples:**
|
|
560
|
+
* ```typescript
|
|
561
|
+
* await aui.expectAllExist([
|
|
562
|
+
* {
|
|
563
|
+
* type: 'text',
|
|
564
|
+
* text: {
|
|
565
|
+
* value: 'Switch to Dark',
|
|
566
|
+
* matching: 'similar'
|
|
567
|
+
* }
|
|
568
|
+
* },
|
|
569
|
+
* ]);
|
|
570
|
+
*
|
|
571
|
+
* // Check for existence of multiple elements
|
|
572
|
+
* await aui.expectAllExist([
|
|
573
|
+
* {
|
|
574
|
+
* type: 'textfield',
|
|
575
|
+
* relation: {
|
|
576
|
+
* type: 'rightOf',
|
|
577
|
+
* text: 'Email:'
|
|
578
|
+
* }
|
|
579
|
+
* },
|
|
580
|
+
* {
|
|
581
|
+
* type: 'element',
|
|
582
|
+
* text: {
|
|
583
|
+
* value: 'Switch to Dark'
|
|
584
|
+
* }
|
|
585
|
+
* },
|
|
586
|
+
* ]);
|
|
587
|
+
*
|
|
588
|
+
* // Validate existence
|
|
589
|
+
* const exists = await aui.expectAllExist([...]);
|
|
590
|
+
* exists.allExist // true when every element exists
|
|
591
|
+
*
|
|
592
|
+
* // Check which elements do not exist
|
|
593
|
+
* // with the elements property
|
|
594
|
+
* const nonExistentElements = exists.elements.filter((e) => e.exists===false)
|
|
595
|
+
* ```
|
|
596
|
+
*
|
|
597
|
+
* @param {ElementExistsQuery[]} query - Objects containing the required property
|
|
598
|
+
* 'type' and the optional properties
|
|
599
|
+
* 'text' and 'relation'.
|
|
600
|
+
* @property {string} query.type - The type of the element: 'otherElement' | 'switch' |
|
|
601
|
+
* 'element' | 'container' | 'checkbox' | 'element' |
|
|
602
|
+
* 'button' | 'table' | 'text' | 'icon' | 'image' | 'textfield'
|
|
603
|
+
* @property {Object} [query.text] - Object containing value and matching strategy.
|
|
604
|
+
* @property {string} query.text.value - The text to match for.
|
|
605
|
+
* @property {string} [query.text.matching] - Whether the text is matched using similarity,
|
|
606
|
+
* exact match or a regular expression.
|
|
607
|
+
* @property {Object} [query.relation] - Object describing the relationship between the
|
|
608
|
+
* clicked text and another element.
|
|
609
|
+
* @property {RelationsForConvenienceMethods} query.relation.type - The type of relation.
|
|
610
|
+
* @property {string} query.relation.text - The label or text associated with the
|
|
611
|
+
* related element or state.
|
|
612
|
+
* @returns {ExpectAllExistResult.allExist} - If every element exists.
|
|
613
|
+
* @returns {ExpectAllExistResult.elements} - ExpectExistenceElement[].
|
|
614
|
+
*/
|
|
615
|
+
expectAllExist(query) {
|
|
616
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
617
|
+
const elements = yield query.reduce((accumulatorPromise, subquery) => __awaiter(this, void 0, void 0, function* () {
|
|
618
|
+
const acc = yield accumulatorPromise;
|
|
619
|
+
const command = this.get()[subquery.type]();
|
|
620
|
+
let finalCommand = subquery.text !== undefined
|
|
621
|
+
? this.evaluateMatchingProperty(command, subquery.text)
|
|
622
|
+
: command;
|
|
623
|
+
if (subquery.relation) {
|
|
624
|
+
finalCommand = this.evaluateRelation(finalCommand, subquery.relation.type, subquery.relation.text);
|
|
625
|
+
}
|
|
626
|
+
return [
|
|
627
|
+
...acc,
|
|
628
|
+
Object.assign(Object.assign({}, subquery), { exists: (yield finalCommand.exec()).length > 0 }),
|
|
629
|
+
];
|
|
630
|
+
}), Promise.resolve([]));
|
|
631
|
+
return {
|
|
632
|
+
elements,
|
|
633
|
+
allExist: elements.every((el) => el.exists),
|
|
634
|
+
};
|
|
635
|
+
});
|
|
636
|
+
}
|
|
547
637
|
}
|
|
548
638
|
exports.UiControlClient = UiControlClient;
|
|
@@ -53,9 +53,11 @@ export interface ClientArgs {
|
|
|
53
53
|
readonly modelComposition?: ModelCompositionBranch[];
|
|
54
54
|
readonly reporter?: Reporter | Reporter[] | undefined;
|
|
55
55
|
readonly context?: ContextArgs | undefined;
|
|
56
|
+
readonly inferenceServerApiVersion?: string;
|
|
56
57
|
}
|
|
57
58
|
export interface ClientArgsWithDefaults extends ClientArgs {
|
|
58
59
|
readonly uiControllerUrl: string;
|
|
59
60
|
readonly inferenceServerUrl: string;
|
|
60
61
|
readonly context: Context;
|
|
62
|
+
readonly inferenceServerApiVersion: string;
|
|
61
63
|
}
|
|
@@ -18,6 +18,7 @@ export declare class UiControllerClient {
|
|
|
18
18
|
private onMessage;
|
|
19
19
|
connect(): Promise<UiControllerClientConnectionState>;
|
|
20
20
|
disconnect(): void;
|
|
21
|
+
private checkConnection;
|
|
21
22
|
private sendAndReceive;
|
|
22
23
|
private send;
|
|
23
24
|
requestScreenshot(): Promise<CaptureScreenshotResponse>;
|
|
@@ -10,6 +10,7 @@ const logger_1 = require("../lib/logger");
|
|
|
10
10
|
const ui_controller_client_connection_state_1 = require("./ui-controller-client-connection-state");
|
|
11
11
|
const read_recording_response_stream_handler_1 = require("./read-recording-response-stream-handler");
|
|
12
12
|
const ui_controller_client_error_1 = require("./ui-controller-client-error");
|
|
13
|
+
const ui_controller_not_connected_error_1 = require("./ui-controller-not-connected-error");
|
|
13
14
|
class UiControllerClient {
|
|
14
15
|
constructor(url) {
|
|
15
16
|
this.url = url;
|
|
@@ -40,7 +41,9 @@ class UiControllerClient {
|
|
|
40
41
|
return new Promise((resolve, reject) => {
|
|
41
42
|
try {
|
|
42
43
|
this.ws = new ws_1.default(this.url);
|
|
43
|
-
this.ws.on('message', (data) => {
|
|
44
|
+
this.ws.on('message', (data) => {
|
|
45
|
+
this.onMessage(data);
|
|
46
|
+
});
|
|
44
47
|
this.ws.on('open', () => {
|
|
45
48
|
this.connectionState = ui_controller_client_connection_state_1.UiControllerClientConnectionState.CONNECTED;
|
|
46
49
|
resolve(this.connectionState);
|
|
@@ -61,7 +64,13 @@ class UiControllerClient {
|
|
|
61
64
|
var _a;
|
|
62
65
|
(_a = this.ws) === null || _a === void 0 ? void 0 : _a.close();
|
|
63
66
|
}
|
|
67
|
+
checkConnection() {
|
|
68
|
+
if (this.connectionState !== ui_controller_client_connection_state_1.UiControllerClientConnectionState.CONNECTED) {
|
|
69
|
+
throw new ui_controller_not_connected_error_1.UiControllerNotConnectedError();
|
|
70
|
+
}
|
|
71
|
+
}
|
|
64
72
|
sendAndReceive(msg, requestTimeout = UiControllerClient.REQUEST_TIMEOUT_IN_MS) {
|
|
73
|
+
this.checkConnection();
|
|
65
74
|
return new Promise((resolve, reject) => {
|
|
66
75
|
this.currentResolve = resolve;
|
|
67
76
|
this.currentReject = reject;
|
|
@@ -75,6 +84,7 @@ class UiControllerClient {
|
|
|
75
84
|
});
|
|
76
85
|
}
|
|
77
86
|
send(msg, _requestTimeout = UiControllerClient.REQUEST_TIMEOUT_IN_MS) {
|
|
87
|
+
this.checkConnection();
|
|
78
88
|
if (!this.currentReject || !this.currentResolve) {
|
|
79
89
|
throw new ui_controller_client_error_1.UiControllerClientError('Request is not finished! It is not possible to have multiple requests at the same time.');
|
|
80
90
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UiControllerNotConnectedError = void 0;
|
|
4
|
+
const ui_controller_client_error_1 = require("./ui-controller-client-error");
|
|
5
|
+
class UiControllerNotConnectedError extends ui_controller_client_error_1.UiControllerClientError {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('UI Controller is not connected. Did you call `UiControlClient.connect()`'
|
|
8
|
+
+ ' before trying to interact with the UI Controller / OS?');
|
|
9
|
+
this.name = 'UiControllerNotConnectedError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.UiControllerNotConnectedError = UiControllerNotConnectedError;
|