askui 0.17.0 → 0.18.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/execution/context.d.ts +12 -0
- package/dist/cjs/execution/context.js +2 -0
- package/dist/cjs/execution/index.d.ts +1 -1
- package/dist/cjs/execution/ui-control-client-dependency-builder.js +9 -3
- package/dist/cjs/execution/ui-control-client.d.ts +154 -13
- package/dist/cjs/execution/ui-control-client.js +219 -21
- package/dist/cjs/execution/ui-controller-client-interface.d.ts +41 -19
- package/dist/cjs/lib/interactive_cli/create-example-project.js +1 -1
- package/dist/cjs/main.d.ts +1 -1
- package/dist/cjs/utils/analytics/analytics-interface.d.ts +2 -1
- package/dist/cjs/utils/analytics/analytics.d.ts +2 -1
- package/dist/cjs/utils/analytics/analytics.js +3 -2
- package/dist/esm/execution/context.d.ts +12 -0
- package/dist/esm/execution/context.js +1 -0
- package/dist/esm/execution/index.d.ts +1 -1
- package/dist/esm/execution/ui-control-client-dependency-builder.js +6 -3
- package/dist/esm/execution/ui-control-client.d.ts +154 -13
- package/dist/esm/execution/ui-control-client.js +216 -21
- package/dist/esm/execution/ui-controller-client-interface.d.ts +41 -19
- package/dist/esm/lib/interactive_cli/create-example-project.js +1 -1
- package/dist/esm/main.d.ts +1 -1
- package/dist/esm/utils/analytics/analytics-interface.d.ts +2 -1
- package/dist/esm/utils/analytics/analytics.d.ts +2 -1
- package/dist/esm/utils/analytics/analytics.js +3 -2
- package/dist/example_projects_templates/typescript/.eslintrc.json-template +3 -2
- package/package.json +7 -5
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { UiControlClient } from './ui-control-client';
|
|
1
|
+
export { UiControlClient, RelationsForConvenienceMethods } from './ui-control-client';
|
|
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import isCI from 'is-ci';
|
|
10
11
|
import { HttpClientGot } from '../utils/http/http-client-got';
|
|
11
12
|
import { UiControllerClient } from './ui-controller-client';
|
|
12
13
|
import { InferenceClient } from './inference-client';
|
|
@@ -20,7 +21,7 @@ export class UiControlClientDependencyBuilder {
|
|
|
20
21
|
var _a;
|
|
21
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
22
23
|
const analytics = new Analytics();
|
|
23
|
-
const analyticsHeaders = yield analytics.getAnalyticsHeaders();
|
|
24
|
+
const analyticsHeaders = yield analytics.getAnalyticsHeaders(clientArgs.context);
|
|
24
25
|
const analyticsCookies = yield analytics.getAnalyticsCookies();
|
|
25
26
|
return new HttpClientGot((_a = clientArgs.credentials) === null || _a === void 0 ? void 0 : _a.token, analyticsHeaders, analyticsCookies, clientArgs.proxyAgents);
|
|
26
27
|
});
|
|
@@ -47,9 +48,11 @@ export class UiControlClientDependencyBuilder {
|
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
static getClientArgsWithDefaults(clientArgs) {
|
|
50
|
-
var _a, _b, _c;
|
|
51
|
+
var _a, _b, _c, _d, _e;
|
|
51
52
|
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
-
return Object.assign(Object.assign({}, clientArgs), {
|
|
53
|
+
return Object.assign(Object.assign({}, clientArgs), { context: {
|
|
54
|
+
isCi: (_b = (_a = clientArgs.context) === null || _a === void 0 ? void 0 : _a.isCi) !== null && _b !== void 0 ? _b : isCI,
|
|
55
|
+
}, credentials: readCredentials(clientArgs), inferenceServerUrl: (_c = clientArgs.inferenceServerUrl) !== null && _c !== void 0 ? _c : 'https://inference.askui.com', proxyAgents: (_d = clientArgs.proxyAgents) !== null && _d !== void 0 ? _d : (yield envProxyAgents()), uiControllerUrl: (_e = clientArgs.uiControllerUrl) !== null && _e !== void 0 ? _e : 'http://127.0.0.1:6769' });
|
|
53
56
|
});
|
|
54
57
|
}
|
|
55
58
|
}
|
|
@@ -5,6 +5,7 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
5
5
|
import { AnnotationRequest } from '../core/model/annotation-result/annotation-interface';
|
|
6
6
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
7
7
|
import { ClientArgs } from './ui-controller-client-interface';
|
|
8
|
+
export declare type RelationsForConvenienceMethods = 'nearestTo' | 'leftOf' | 'above' | 'rightOf' | 'below' | 'contains';
|
|
8
9
|
export declare class UiControlClient extends ApiCommands {
|
|
9
10
|
private executionRuntime;
|
|
10
11
|
private stepReporter;
|
|
@@ -108,12 +109,6 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
108
109
|
* @param {PC_AND_MODIFIER_KEY[]} keys
|
|
109
110
|
*/
|
|
110
111
|
pressKeys(keys: PC_AND_MODIFIER_KEY[]): Promise<void>;
|
|
111
|
-
/**
|
|
112
|
-
* Searches for a text element and clicks it when found.
|
|
113
|
-
*
|
|
114
|
-
* @param {string} text - A text to be searched.
|
|
115
|
-
*/
|
|
116
|
-
clickText(text: string): Promise<void>;
|
|
117
112
|
/**
|
|
118
113
|
* Searches for text elements and clicks them
|
|
119
114
|
* one after another when found.
|
|
@@ -121,13 +116,6 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
121
116
|
* @param {string[]} texts - An array of texts to be searched.
|
|
122
117
|
*/
|
|
123
118
|
clickTexts(texts: string[]): Promise<void>;
|
|
124
|
-
/**
|
|
125
|
-
* Searches for an element of type button
|
|
126
|
-
* with a label and clicks it when found.
|
|
127
|
-
*
|
|
128
|
-
* @param {string} label - The buttons label.
|
|
129
|
-
*/
|
|
130
|
-
clickButton(label: string): Promise<void>;
|
|
131
119
|
/**
|
|
132
120
|
* Searches for an element of type textfield with a specific placeholder text.
|
|
133
121
|
* If found, clicks it.
|
|
@@ -162,4 +150,157 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
162
150
|
* @param {number} waitTime - Time in milliseconds
|
|
163
151
|
*/
|
|
164
152
|
waitUntil(AskUICommand: Executable, maxTry?: number, waitTime?: number): Promise<void>;
|
|
153
|
+
private evaluateRelation;
|
|
154
|
+
/**
|
|
155
|
+
* Click a button with a specific label.
|
|
156
|
+
* Optional relation identifies the button in relation to another element.
|
|
157
|
+
*
|
|
158
|
+
* **Examples:**
|
|
159
|
+
* ```typescript
|
|
160
|
+
* await aui.clickButton({})
|
|
161
|
+
* await aui.clickButton({label: 'Checkout here'})
|
|
162
|
+
* await aui.clickButton({relation: {type: 'leftOf', text: 'Choose a ticket'}})
|
|
163
|
+
* await aui.clickButton({label: 'Click', {relation: {type: 'leftOf', text: 'Choose a ticket'}})
|
|
164
|
+
* ```
|
|
165
|
+
*
|
|
166
|
+
* @param {Object} params - Object containing properties.
|
|
167
|
+
* @property {string} [params.label] - The text label of the button. Defaults to an empty string.
|
|
168
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
169
|
+
* the clicked button and another element.
|
|
170
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
171
|
+
* @property {string} params.relation.text - The text element the relation is based on.
|
|
172
|
+
*/
|
|
173
|
+
clickButton(params: {
|
|
174
|
+
label?: string;
|
|
175
|
+
relation?: {
|
|
176
|
+
type: RelationsForConvenienceMethods;
|
|
177
|
+
text: string;
|
|
178
|
+
};
|
|
179
|
+
}): Promise<void>;
|
|
180
|
+
/**
|
|
181
|
+
* Click a checkbox with a specific label.
|
|
182
|
+
* You can also specify where the label is placed relationally.
|
|
183
|
+
*
|
|
184
|
+
* **Examples:**
|
|
185
|
+
* ```typescript
|
|
186
|
+
* await aui.clickCheckbox({label: 'Toggle'})
|
|
187
|
+
* await aui.clickCheckbox({label: 'Toggle', relation: {type: 'leftOf'}})
|
|
188
|
+
* ```
|
|
189
|
+
*
|
|
190
|
+
* @param {Object} params - Object containing required `label` property and
|
|
191
|
+
* optional `relation` property.
|
|
192
|
+
* @property {string} params.label - The label for the checkbox.
|
|
193
|
+
* @property {Object} params.relation - Object describing the relationship between
|
|
194
|
+
* the clicked checkbox and another element.
|
|
195
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
196
|
+
*/
|
|
197
|
+
clickCheckbox(params: {
|
|
198
|
+
label: string;
|
|
199
|
+
relation?: {
|
|
200
|
+
type: RelationsForConvenienceMethods;
|
|
201
|
+
};
|
|
202
|
+
}): Promise<void>;
|
|
203
|
+
/**
|
|
204
|
+
* Click a switch with a specific label.
|
|
205
|
+
* You can also specify where the label is placed relationally.
|
|
206
|
+
*
|
|
207
|
+
* **Examples:**
|
|
208
|
+
* ```typescript
|
|
209
|
+
* await aui.clickSwitch({label: 'Toggle'})
|
|
210
|
+
* await aui.clickSwitch({label: 'Toggle', relation: {type: 'leftOf'}})
|
|
211
|
+
* ```
|
|
212
|
+
*
|
|
213
|
+
* @param {Object} params - Object containing required `label` property and
|
|
214
|
+
* optional `relation` property.
|
|
215
|
+
* @property {string} params.label - The label for the checkbox.
|
|
216
|
+
* @property {Object} params.relation - Object describing the relationship between
|
|
217
|
+
* the clicked checkbox and another element.
|
|
218
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
219
|
+
*/
|
|
220
|
+
clickSwitch(params: {
|
|
221
|
+
label: string;
|
|
222
|
+
relation?: {
|
|
223
|
+
type: RelationsForConvenienceMethods;
|
|
224
|
+
};
|
|
225
|
+
}): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* Types a given text into a textfield.
|
|
228
|
+
* Use a relation to specify how to find
|
|
229
|
+
* the textfield in relation to a specific label.
|
|
230
|
+
*
|
|
231
|
+
* **Examples:**
|
|
232
|
+
* ```typescript
|
|
233
|
+
* // Finds the textfield nearest to the label 'Email'
|
|
234
|
+
* await aui.typeIntoTextfield({textToWrite: 'Hello World', relation: {label: 'Email'}});
|
|
235
|
+
*
|
|
236
|
+
* // Finds the textfield above/below a label 'Password'
|
|
237
|
+
* await aui.typeIntoTextfield(
|
|
238
|
+
* {textToWrite: 'Hello World', relation: {type: 'above', label: 'Password'}}
|
|
239
|
+
* );
|
|
240
|
+
* await aui.typeIntoTextfield(
|
|
241
|
+
* {textToWrite: 'Hello World', relation: {type: 'below', label: 'Password'}}
|
|
242
|
+
* );
|
|
243
|
+
*
|
|
244
|
+
* // If there is no label but a placeholder, the label is contained in the textfield
|
|
245
|
+
* await aui.typeIntoTextfield(
|
|
246
|
+
* {textToWrite: 'Hello World', relation: {type: 'contains', label: 'Enter email'}}
|
|
247
|
+
* );
|
|
248
|
+
* ```
|
|
249
|
+
*
|
|
250
|
+
* @param {Object} params - Object containing required `textToWrite` property and
|
|
251
|
+
* optional `relation` property.
|
|
252
|
+
* @property {string} params.textToWrite - The text to be typed into the textfield.
|
|
253
|
+
* @property {Object} params.relation - Object describing the relationship between the
|
|
254
|
+
* textfield being interacted with and another element.
|
|
255
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of
|
|
256
|
+
* relation, optional.
|
|
257
|
+
* @property {string} params.relation.label - The label associated with the related
|
|
258
|
+
* element, optional.
|
|
259
|
+
*/
|
|
260
|
+
typeIntoTextfield(params: {
|
|
261
|
+
textToWrite: string;
|
|
262
|
+
relation: {
|
|
263
|
+
type?: RelationsForConvenienceMethods;
|
|
264
|
+
label: string;
|
|
265
|
+
};
|
|
266
|
+
}): Promise<void>;
|
|
267
|
+
/**
|
|
268
|
+
* Click on a specific text.
|
|
269
|
+
* You can also use a RegEx or match the text exactly by specifyicing the specific flag.
|
|
270
|
+
* Use a relation to find the text in relation to a specific text.
|
|
271
|
+
*
|
|
272
|
+
* **Examples:**
|
|
273
|
+
* ```typescript
|
|
274
|
+
* // Click text that matches exactly
|
|
275
|
+
* await aui.clickText({text: 'askui', type: 'similar'})
|
|
276
|
+
*
|
|
277
|
+
* // Click text that contains 'pie' or 'cake' or 'Pie' or 'Cake'
|
|
278
|
+
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*', type: 'regex'})
|
|
279
|
+
*
|
|
280
|
+
* // Click the text 'TERMINAL' that is left of the text 'Ports'
|
|
281
|
+
* await aui.clickText({
|
|
282
|
+
* text: 'TERMINAL',
|
|
283
|
+
* type: "exact",
|
|
284
|
+
* relation: { type: 'leftOf', text: 'PORTS' }
|
|
285
|
+
* })
|
|
286
|
+
* ```
|
|
287
|
+
* @param {Object} params - Object containing required `text` property and optional properties
|
|
288
|
+
* for regular expression matching and relation.
|
|
289
|
+
* @property {string} params.text - The text to be clicked.
|
|
290
|
+
* @property {string} params.type - Whether the text is matched using similarity,
|
|
291
|
+
* exact match or a regular expression.
|
|
292
|
+
* @property {Object} params.relation - Object describing the relationship between the
|
|
293
|
+
* clicked text and another element.
|
|
294
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
295
|
+
* @property {string} params.relation.text - The label or text associated with the
|
|
296
|
+
* related element or state.
|
|
297
|
+
*/
|
|
298
|
+
clickText(params: {
|
|
299
|
+
text: string;
|
|
300
|
+
type: 'similar' | 'exact' | 'regex';
|
|
301
|
+
relation?: {
|
|
302
|
+
type: RelationsForConvenienceMethods;
|
|
303
|
+
text: string;
|
|
304
|
+
};
|
|
305
|
+
}): Promise<void>;
|
|
165
306
|
}
|
|
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
+
import ValidationError from 'yup/lib/ValidationError';
|
|
10
11
|
import { CustomElement } from '../core/model/custom-element';
|
|
11
12
|
import { ApiCommands, Separators, } from './dsl';
|
|
12
13
|
import { AnnotationWriter } from '../core/annotation/annotation-writer';
|
|
@@ -246,16 +247,6 @@ export class UiControlClient extends ApiCommands {
|
|
|
246
247
|
}
|
|
247
248
|
});
|
|
248
249
|
}
|
|
249
|
-
/**
|
|
250
|
-
* Searches for a text element and clicks it when found.
|
|
251
|
-
*
|
|
252
|
-
* @param {string} text - A text to be searched.
|
|
253
|
-
*/
|
|
254
|
-
clickText(text) {
|
|
255
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
-
yield this.click().text(text).exec();
|
|
257
|
-
});
|
|
258
|
-
}
|
|
259
250
|
/**
|
|
260
251
|
* Searches for text elements and clicks them
|
|
261
252
|
* one after another when found.
|
|
@@ -270,17 +261,6 @@ export class UiControlClient extends ApiCommands {
|
|
|
270
261
|
}
|
|
271
262
|
});
|
|
272
263
|
}
|
|
273
|
-
/**
|
|
274
|
-
* Searches for an element of type button
|
|
275
|
-
* with a label and clicks it when found.
|
|
276
|
-
*
|
|
277
|
-
* @param {string} label - The buttons label.
|
|
278
|
-
*/
|
|
279
|
-
clickButton(label) {
|
|
280
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
281
|
-
yield this.click().button().withText(label).exec();
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
264
|
/**
|
|
285
265
|
* Searches for an element of type textfield with a specific placeholder text.
|
|
286
266
|
* If found, clicks it.
|
|
@@ -343,4 +323,219 @@ export class UiControlClient extends ApiCommands {
|
|
|
343
323
|
}
|
|
344
324
|
});
|
|
345
325
|
}
|
|
326
|
+
// eslint-disable-next-line class-methods-use-this
|
|
327
|
+
evaluateRelation(command, relation, text) {
|
|
328
|
+
let commando = command;
|
|
329
|
+
switch (relation) {
|
|
330
|
+
case 'nearestTo':
|
|
331
|
+
commando = command.nearestTo().text(text);
|
|
332
|
+
break;
|
|
333
|
+
case 'leftOf':
|
|
334
|
+
commando = command.leftOf().text(text);
|
|
335
|
+
break;
|
|
336
|
+
case 'above':
|
|
337
|
+
commando = command.above().text(text);
|
|
338
|
+
break;
|
|
339
|
+
case 'rightOf':
|
|
340
|
+
commando = command.rightOf().text(text);
|
|
341
|
+
break;
|
|
342
|
+
case 'below':
|
|
343
|
+
commando = command.below().text(text);
|
|
344
|
+
break;
|
|
345
|
+
case 'contains':
|
|
346
|
+
commando = command.contains().text(text);
|
|
347
|
+
break;
|
|
348
|
+
default:
|
|
349
|
+
throw new ValidationError('No valid Relation.Type was passed.');
|
|
350
|
+
}
|
|
351
|
+
return commando;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Click a button with a specific label.
|
|
355
|
+
* Optional relation identifies the button in relation to another element.
|
|
356
|
+
*
|
|
357
|
+
* **Examples:**
|
|
358
|
+
* ```typescript
|
|
359
|
+
* await aui.clickButton({})
|
|
360
|
+
* await aui.clickButton({label: 'Checkout here'})
|
|
361
|
+
* await aui.clickButton({relation: {type: 'leftOf', text: 'Choose a ticket'}})
|
|
362
|
+
* await aui.clickButton({label: 'Click', {relation: {type: 'leftOf', text: 'Choose a ticket'}})
|
|
363
|
+
* ```
|
|
364
|
+
*
|
|
365
|
+
* @param {Object} params - Object containing properties.
|
|
366
|
+
* @property {string} [params.label] - The text label of the button. Defaults to an empty string.
|
|
367
|
+
* @property {Object} [params.relation] - Object describing the relationship between
|
|
368
|
+
* the clicked button and another element.
|
|
369
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
370
|
+
* @property {string} params.relation.text - The text element the relation is based on.
|
|
371
|
+
*/
|
|
372
|
+
clickButton(params) {
|
|
373
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
374
|
+
let command = this.click().button();
|
|
375
|
+
if (params.label) {
|
|
376
|
+
command = command.withText(params.label);
|
|
377
|
+
}
|
|
378
|
+
if (params.relation) {
|
|
379
|
+
command = this.evaluateRelation(command, params.relation.type, params.relation.text);
|
|
380
|
+
}
|
|
381
|
+
yield command.exec();
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Click a checkbox with a specific label.
|
|
386
|
+
* You can also specify where the label is placed relationally.
|
|
387
|
+
*
|
|
388
|
+
* **Examples:**
|
|
389
|
+
* ```typescript
|
|
390
|
+
* await aui.clickCheckbox({label: 'Toggle'})
|
|
391
|
+
* await aui.clickCheckbox({label: 'Toggle', relation: {type: 'leftOf'}})
|
|
392
|
+
* ```
|
|
393
|
+
*
|
|
394
|
+
* @param {Object} params - Object containing required `label` property and
|
|
395
|
+
* optional `relation` property.
|
|
396
|
+
* @property {string} params.label - The label for the checkbox.
|
|
397
|
+
* @property {Object} params.relation - Object describing the relationship between
|
|
398
|
+
* the clicked checkbox and another element.
|
|
399
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
400
|
+
*/
|
|
401
|
+
clickCheckbox(params) {
|
|
402
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
403
|
+
let command = this.click().checkbox();
|
|
404
|
+
if (!params.relation) {
|
|
405
|
+
command = command.nearestTo().text(params.label);
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
command = this.evaluateRelation(command, params.relation.type, params.label);
|
|
409
|
+
}
|
|
410
|
+
yield command.exec();
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Click a switch with a specific label.
|
|
415
|
+
* You can also specify where the label is placed relationally.
|
|
416
|
+
*
|
|
417
|
+
* **Examples:**
|
|
418
|
+
* ```typescript
|
|
419
|
+
* await aui.clickSwitch({label: 'Toggle'})
|
|
420
|
+
* await aui.clickSwitch({label: 'Toggle', relation: {type: 'leftOf'}})
|
|
421
|
+
* ```
|
|
422
|
+
*
|
|
423
|
+
* @param {Object} params - Object containing required `label` property and
|
|
424
|
+
* optional `relation` property.
|
|
425
|
+
* @property {string} params.label - The label for the checkbox.
|
|
426
|
+
* @property {Object} params.relation - Object describing the relationship between
|
|
427
|
+
* the clicked checkbox and another element.
|
|
428
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
429
|
+
*/
|
|
430
|
+
clickSwitch(params) {
|
|
431
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
432
|
+
let command = this.click().switch();
|
|
433
|
+
if (!params.relation) {
|
|
434
|
+
command = command.nearestTo().text(params.label);
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
command = this.evaluateRelation(command, params.relation.type, params.label);
|
|
438
|
+
}
|
|
439
|
+
yield command.exec();
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
/**
|
|
443
|
+
* Types a given text into a textfield.
|
|
444
|
+
* Use a relation to specify how to find
|
|
445
|
+
* the textfield in relation to a specific label.
|
|
446
|
+
*
|
|
447
|
+
* **Examples:**
|
|
448
|
+
* ```typescript
|
|
449
|
+
* // Finds the textfield nearest to the label 'Email'
|
|
450
|
+
* await aui.typeIntoTextfield({textToWrite: 'Hello World', relation: {label: 'Email'}});
|
|
451
|
+
*
|
|
452
|
+
* // Finds the textfield above/below a label 'Password'
|
|
453
|
+
* await aui.typeIntoTextfield(
|
|
454
|
+
* {textToWrite: 'Hello World', relation: {type: 'above', label: 'Password'}}
|
|
455
|
+
* );
|
|
456
|
+
* await aui.typeIntoTextfield(
|
|
457
|
+
* {textToWrite: 'Hello World', relation: {type: 'below', label: 'Password'}}
|
|
458
|
+
* );
|
|
459
|
+
*
|
|
460
|
+
* // If there is no label but a placeholder, the label is contained in the textfield
|
|
461
|
+
* await aui.typeIntoTextfield(
|
|
462
|
+
* {textToWrite: 'Hello World', relation: {type: 'contains', label: 'Enter email'}}
|
|
463
|
+
* );
|
|
464
|
+
* ```
|
|
465
|
+
*
|
|
466
|
+
* @param {Object} params - Object containing required `textToWrite` property and
|
|
467
|
+
* optional `relation` property.
|
|
468
|
+
* @property {string} params.textToWrite - The text to be typed into the textfield.
|
|
469
|
+
* @property {Object} params.relation - Object describing the relationship between the
|
|
470
|
+
* textfield being interacted with and another element.
|
|
471
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of
|
|
472
|
+
* relation, optional.
|
|
473
|
+
* @property {string} params.relation.label - The label associated with the related
|
|
474
|
+
* element, optional.
|
|
475
|
+
*/
|
|
476
|
+
typeIntoTextfield(params) {
|
|
477
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
478
|
+
let command = this.typeIn(params.textToWrite).textfield();
|
|
479
|
+
if (!params.relation.type) {
|
|
480
|
+
command = command.nearestTo().text(params.relation.label);
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
command = this.evaluateRelation(command, params.relation.type, params.relation.label);
|
|
484
|
+
}
|
|
485
|
+
yield command.exec();
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Click on a specific text.
|
|
490
|
+
* You can also use a RegEx or match the text exactly by specifyicing the specific flag.
|
|
491
|
+
* Use a relation to find the text in relation to a specific text.
|
|
492
|
+
*
|
|
493
|
+
* **Examples:**
|
|
494
|
+
* ```typescript
|
|
495
|
+
* // Click text that matches exactly
|
|
496
|
+
* await aui.clickText({text: 'askui', type: 'similar'})
|
|
497
|
+
*
|
|
498
|
+
* // Click text that contains 'pie' or 'cake' or 'Pie' or 'Cake'
|
|
499
|
+
* await aui.clickText({text: '.*([Pp]ie|[Cc]ake).*', type: 'regex'})
|
|
500
|
+
*
|
|
501
|
+
* // Click the text 'TERMINAL' that is left of the text 'Ports'
|
|
502
|
+
* await aui.clickText({
|
|
503
|
+
* text: 'TERMINAL',
|
|
504
|
+
* type: "exact",
|
|
505
|
+
* relation: { type: 'leftOf', text: 'PORTS' }
|
|
506
|
+
* })
|
|
507
|
+
* ```
|
|
508
|
+
* @param {Object} params - Object containing required `text` property and optional properties
|
|
509
|
+
* for regular expression matching and relation.
|
|
510
|
+
* @property {string} params.text - The text to be clicked.
|
|
511
|
+
* @property {string} params.type - Whether the text is matched using similarity,
|
|
512
|
+
* exact match or a regular expression.
|
|
513
|
+
* @property {Object} params.relation - Object describing the relationship between the
|
|
514
|
+
* clicked text and another element.
|
|
515
|
+
* @property {RelationsForConvenienceMethods} params.relation.type - The type of relation.
|
|
516
|
+
* @property {string} params.relation.text - The label or text associated with the
|
|
517
|
+
* related element or state.
|
|
518
|
+
*/
|
|
519
|
+
clickText(params) {
|
|
520
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
521
|
+
let command = this.click().text();
|
|
522
|
+
switch (params.type) {
|
|
523
|
+
case 'similar':
|
|
524
|
+
command = command.withText(params.text);
|
|
525
|
+
break;
|
|
526
|
+
case 'exact':
|
|
527
|
+
command = command.withExactText(params.text);
|
|
528
|
+
break;
|
|
529
|
+
case 'regex':
|
|
530
|
+
command = command.withTextRegex(params.text);
|
|
531
|
+
break;
|
|
532
|
+
default:
|
|
533
|
+
throw new ValidationError('"type" must be "similar", "exact" or "regex"');
|
|
534
|
+
}
|
|
535
|
+
if (params.relation) {
|
|
536
|
+
command = this.evaluateRelation(command, params.relation.type, params.relation.text);
|
|
537
|
+
}
|
|
538
|
+
yield command.exec();
|
|
539
|
+
});
|
|
540
|
+
}
|
|
346
541
|
}
|
|
@@ -2,27 +2,47 @@ import { CredentialArgs } from './credentials-args';
|
|
|
2
2
|
import { ProxyAgentArgs } from '../shared/proxy-agent-args';
|
|
3
3
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
4
4
|
import { Reporter } from '../core/reporting';
|
|
5
|
+
import { Context } from './context';
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
+
* Context object to provide additional information about the context of (test) automation.
|
|
7
8
|
*
|
|
8
|
-
* @
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* @
|
|
24
|
-
*
|
|
25
|
-
*
|
|
9
|
+
* @property {(boolean | undefined)} [isCi] - Default: Determined automatically by
|
|
10
|
+
* https://github.com/watson/is-ci; see https://github.com/watson/ci-info#supported-ci-tools for
|
|
11
|
+
* all supported CI tools. Can be used for overriding the automatic detection of CI tools, e.g.,
|
|
12
|
+
* if not supported by `is-ci`, so that AskUI can be optimized for the corresponding
|
|
13
|
+
* environment, e.g., adjusting caching behavior.
|
|
14
|
+
*/
|
|
15
|
+
export interface ContextArgs {
|
|
16
|
+
readonly isCi?: boolean | undefined;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Configuration options for AskUI's UiControlClient.
|
|
20
|
+
*
|
|
21
|
+
* @property {string} [uiControllerUrl] - Default: `'http://127.0.0.1:6769'`. The address of
|
|
22
|
+
* AskUI's UiController that interacts with the operating system, e.g., simulating input
|
|
23
|
+
* events and capturing screenshots.
|
|
24
|
+
* @property {string} [inferenceServerUrl] - Default: `'https://inference.askui.com'`.
|
|
25
|
+
* Address of the AskUI's inference server which is responsible for understanding the
|
|
26
|
+
* screenshots and extracting data from them and returning commands for the UiController.
|
|
27
|
+
* @property {(CredentialArgs | undefined)} [credentials] - Optional. Credentials for
|
|
28
|
+
* the authenticating and authorizing with the inference server.
|
|
29
|
+
* @property {(ProxyAgentArgs | undefined)} [proxyAgents] - Optional. Proxy agents for http(s)
|
|
30
|
+
* requests against the inference server if running behind a proxy.
|
|
31
|
+
* @property {number} [resize] - Optional. Length in px to resize the screenshot image to before
|
|
32
|
+
* sending it to the inference server so that the screenshot image's longer side is equal to or
|
|
33
|
+
* less than it. Aspect ratio (of width and height) is preserved. This can be used to reduce the
|
|
34
|
+
* inference time by reducing the request size, e.g., if network bandwidth is limited. But it
|
|
35
|
+
* can cause a decrease in the prediction quality. If undefined, the screenshot image is not
|
|
36
|
+
* resized but sent as is.
|
|
37
|
+
* @property {(Reporter | Reporter[] | undefined)} [reporter] - Default: `[]`. To configure the
|
|
38
|
+
* reporter(s) to report on steps (see
|
|
39
|
+
* https://docs.askui.com/docs/next/general/Components/askui-ui-control-client#reporter).
|
|
40
|
+
* @property {ModelCompositionBranch[]} [modelComposition] - Default: `[]`. To configure the model
|
|
41
|
+
* composition for the inference server, i.e., which models are used for the inference, e.g.,
|
|
42
|
+
* test recognition or object detection.
|
|
43
|
+
* @property {(Context | undefined)} [context] - Optional. Context object to provide additional
|
|
44
|
+
* information about the context of (test) automation, e.g., to allow for optimizations based on
|
|
45
|
+
* the environment, e.g., CI/CD.
|
|
26
46
|
*/
|
|
27
47
|
export interface ClientArgs {
|
|
28
48
|
readonly uiControllerUrl?: string;
|
|
@@ -32,8 +52,10 @@ export interface ClientArgs {
|
|
|
32
52
|
readonly resize?: number;
|
|
33
53
|
readonly modelComposition?: ModelCompositionBranch[];
|
|
34
54
|
readonly reporter?: Reporter | Reporter[] | undefined;
|
|
55
|
+
readonly context?: ContextArgs | undefined;
|
|
35
56
|
}
|
|
36
57
|
export interface ClientArgsWithDefaults extends ClientArgs {
|
|
37
58
|
readonly uiControllerUrl: string;
|
|
38
59
|
readonly inferenceServerUrl: string;
|
|
60
|
+
readonly context: Context;
|
|
39
61
|
}
|
|
@@ -182,7 +182,7 @@ export class CreateExampleProject {
|
|
|
182
182
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
183
|
const runCommand = promisify(exec);
|
|
184
184
|
const frameworkDependencies = {
|
|
185
|
-
jest: 'npm i -D @askui/askui-reporters typescript ts-node @types/jest ts-jest jest @askui/jest-allure-circus eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-import eslint-plugin-askui hpagent',
|
|
185
|
+
jest: 'npm i -D @askui/askui-reporters typescript ts-node @types/jest ts-jest jest @askui/jest-allure-circus eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint-plugin-import @askui/eslint-plugin-askui hpagent',
|
|
186
186
|
};
|
|
187
187
|
yield runCommand(frameworkDependencies.jest);
|
|
188
188
|
});
|
package/dist/esm/main.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { UiController } from './lib';
|
|
2
|
-
export { UiControlClient } from './execution';
|
|
2
|
+
export { UiControlClient, RelationsForConvenienceMethods } from './execution';
|
|
3
3
|
export { Instruction, Reporter, ReporterConfig, Snapshot, SnapshotDetailLevel, Step, StepStatus, StepStatusEnd, } from './core/reporting';
|
|
4
4
|
export { Annotation } from './core/annotation/annotation';
|
|
5
5
|
export { DetectedElement } from './core/model/annotation-result/detected-element';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AnalyticsInterface } from './analytics-interface';
|
|
2
|
+
import { Context } from '@/execution/context';
|
|
2
3
|
export declare class Analytics implements AnalyticsInterface {
|
|
3
4
|
private userIdentifier;
|
|
4
|
-
getAnalyticsHeaders(): Promise<Record<string, string>>;
|
|
5
|
+
getAnalyticsHeaders(context: Context): Promise<Record<string, string>>;
|
|
5
6
|
getAnalyticsCookies(): Promise<Record<string, string>>;
|
|
6
7
|
}
|
|
@@ -14,12 +14,13 @@ export class Analytics {
|
|
|
14
14
|
constructor() {
|
|
15
15
|
this.userIdentifier = new UserIdentifier();
|
|
16
16
|
}
|
|
17
|
-
getAnalyticsHeaders() {
|
|
17
|
+
getAnalyticsHeaders(context) {
|
|
18
18
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
19
|
const userID = yield this.userIdentifier.userId();
|
|
20
20
|
const headers = {
|
|
21
|
-
'askui-
|
|
21
|
+
'askui-is-ci': String(context.isCi),
|
|
22
22
|
'askui-user-agent': `os:${os.platform()};arch:${os.arch()}`,
|
|
23
|
+
'askui-user-id': userID,
|
|
23
24
|
};
|
|
24
25
|
const askuiInstalledAt = yield InstallationTimestamp.get();
|
|
25
26
|
if (askuiInstalledAt) {
|