askui 0.20.6 → 0.20.8
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/inference-response/inference-response.d.ts +5 -0
- package/dist/cjs/execution/execution-runtime.d.ts +1 -0
- package/dist/cjs/execution/execution-runtime.js +6 -0
- package/dist/cjs/execution/inference-client.d.ts +3 -0
- package/dist/cjs/execution/inference-client.js +25 -0
- package/dist/cjs/execution/ui-control-client.d.ts +89 -0
- package/dist/cjs/execution/ui-control-client.js +94 -0
- package/dist/cjs/lib/interactive_cli/cli.js +0 -32
- package/dist/cjs/lib/interactive_cli/create-example-project.d.ts +0 -1
- package/dist/cjs/lib/interactive_cli/create-example-project.js +4 -31
- package/dist/cjs/lib/ui-controller.d.ts +4 -0
- package/dist/cjs/lib/ui-controller.js +4 -0
- package/dist/esm/core/inference-response/inference-response.d.ts +5 -0
- package/dist/esm/execution/execution-runtime.d.ts +1 -0
- package/dist/esm/execution/execution-runtime.js +6 -0
- package/dist/esm/execution/inference-client.d.ts +3 -0
- package/dist/esm/execution/inference-client.js +25 -0
- package/dist/esm/execution/ui-control-client.d.ts +89 -0
- package/dist/esm/execution/ui-control-client.js +94 -0
- package/dist/esm/lib/interactive_cli/cli.js +0 -32
- package/dist/esm/lib/interactive_cli/create-example-project.d.ts +0 -1
- package/dist/esm/lib/interactive_cli/create-example-project.js +4 -31
- package/dist/esm/lib/ui-controller.d.ts +4 -0
- package/dist/esm/lib/ui-controller.js +4 -0
- package/dist/example_projects_templates/templates/askui-helper.nj +2 -17
- package/package.json +1 -1
- package/dist/example_projects_templates/templates/askui-helper-windows.nj +0 -36
|
@@ -5,6 +5,11 @@ export interface InferenceResponseBody {
|
|
|
5
5
|
type: ModelType;
|
|
6
6
|
data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation;
|
|
7
7
|
}
|
|
8
|
+
export interface VQAInferenceResponseBody {
|
|
9
|
+
data: {
|
|
10
|
+
response: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
8
13
|
export declare class InferenceResponse {
|
|
9
14
|
static fromJson(json: InferenceResponseBody, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
10
15
|
static createModels(type: ModelType, data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
@@ -35,4 +35,5 @@ export declare class ExecutionRuntime {
|
|
|
35
35
|
takeScreenshotIfImageisNotProvided(imagePath?: string): Promise<string>;
|
|
36
36
|
getDetectedElements(instruction: string, customElementJson?: CustomElementJson[]): Promise<DetectedElement[]>;
|
|
37
37
|
annotateImage(imagePath?: string, customElementJson?: CustomElementJson[], elements?: DetectedElement[]): Promise<Annotation>;
|
|
38
|
+
predictVQA(prompt: string, config?: object): Promise<any>;
|
|
38
39
|
}
|
|
@@ -208,5 +208,11 @@ class ExecutionRuntime {
|
|
|
208
208
|
return this.inferenceClient.predictImageAnnotation(base64Image, customElements);
|
|
209
209
|
});
|
|
210
210
|
}
|
|
211
|
+
predictVQA(prompt, config) {
|
|
212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
const base64Image = yield this.takeScreenshotIfImageisNotProvided();
|
|
214
|
+
return this.inferenceClient.predictVQAAnswer(prompt, base64Image, config);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
211
217
|
}
|
|
212
218
|
exports.ExecutionRuntime = ExecutionRuntime;
|
|
@@ -3,6 +3,7 @@ import { ControlCommand } from '../core/ui-control-commands';
|
|
|
3
3
|
import { CustomElement } from '../core/model/custom-element';
|
|
4
4
|
import { Annotation } from '../core/annotation/annotation';
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
|
+
import { VQAInferenceResponseBody } from '../core/inference-response/inference-response';
|
|
6
7
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
8
|
export declare class InferenceClient {
|
|
8
9
|
private readonly baseUrl;
|
|
@@ -16,8 +17,10 @@ export declare class InferenceClient {
|
|
|
16
17
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
18
|
private resizeIfNeeded;
|
|
18
19
|
inference(customElements?: CustomElement[], image?: string, instruction?: string): Promise<ControlCommand | Annotation>;
|
|
20
|
+
vqaInference(image: string, prompt: string, config?: object): Promise<VQAInferenceResponseBody>;
|
|
19
21
|
private static logMetaInformation;
|
|
20
22
|
predictControlCommand(instruction: string, customElements?: CustomElement[], image?: string): Promise<ControlCommand>;
|
|
21
23
|
getDetectedElements(instruction: string, image: string, customElements?: CustomElement[]): Promise<DetectedElement[]>;
|
|
22
24
|
predictImageAnnotation(image: string, customElements?: CustomElement[]): Promise<Annotation>;
|
|
25
|
+
predictVQAAnswer(prompt: string, image: string, config?: object): Promise<any>;
|
|
23
26
|
}
|
|
@@ -35,6 +35,7 @@ class InferenceClient {
|
|
|
35
35
|
this.urls = {
|
|
36
36
|
inference: (0, url_join_1.default)(url, 'inference'),
|
|
37
37
|
isImageRequired: (0, url_join_1.default)(url, 'instruction', 'is-image-required'),
|
|
38
|
+
vqaInference: (0, url_join_1.default)(url, 'vqa', 'inference'),
|
|
38
39
|
};
|
|
39
40
|
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
40
41
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
@@ -77,6 +78,17 @@ class InferenceClient {
|
|
|
77
78
|
return ui_control_commands_1.InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
78
79
|
});
|
|
79
80
|
}
|
|
81
|
+
vqaInference(image, prompt, config) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
const response = yield this.httpClient.post(this.urls.vqaInference, {
|
|
84
|
+
config,
|
|
85
|
+
image,
|
|
86
|
+
prompt,
|
|
87
|
+
});
|
|
88
|
+
InferenceClient.logMetaInformation(response);
|
|
89
|
+
return response.body;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
80
92
|
static logMetaInformation(response) {
|
|
81
93
|
if (response.headers['askui-usage-warnings'] !== undefined) {
|
|
82
94
|
logger_1.logger.warn(response.headers['askui-usage-warnings']);
|
|
@@ -109,5 +121,18 @@ class InferenceClient {
|
|
|
109
121
|
return inferenceResponse;
|
|
110
122
|
});
|
|
111
123
|
}
|
|
124
|
+
predictVQAAnswer(prompt, image, config) {
|
|
125
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
126
|
+
const inferenceResponse = yield this.vqaInference(image, prompt, config);
|
|
127
|
+
const { response } = inferenceResponse.data;
|
|
128
|
+
try {
|
|
129
|
+
return JSON.parse(response);
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
logger_1.logger.warn(`Response is no valid JSON: ${response}`);
|
|
133
|
+
}
|
|
134
|
+
return response;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
112
137
|
}
|
|
113
138
|
exports.InferenceClient = InferenceClient;
|
|
@@ -59,6 +59,95 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
59
59
|
private getAIElementsByNames;
|
|
60
60
|
fluentCommandExecutor(instructionString: string, context?: CommandExecutorContext): Promise<void>;
|
|
61
61
|
getterExecutor(instruction: string, context?: CommandExecutorContext): Promise<DetectedElement[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Takes a prompt that contains a question you want to be answered
|
|
64
|
+
* or the data you want to have extracted from your screen.
|
|
65
|
+
*
|
|
66
|
+
* The optional 'config' can be used to specifiy the JSON schema the
|
|
67
|
+
* returned object shall have (https://json-schema.org).
|
|
68
|
+
*
|
|
69
|
+
* See the following examples on how to use it:
|
|
70
|
+
*
|
|
71
|
+
* let isWidgetsNew =
|
|
72
|
+
* await aui.ask(
|
|
73
|
+
* "Does the sidebar element 'Widgets' have a 'NEW' tag?",
|
|
74
|
+
* {
|
|
75
|
+
* json_schema: {
|
|
76
|
+
* "type": "boolean"
|
|
77
|
+
* }
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* Output of console.log(isWidgetsNew): true
|
|
81
|
+
*
|
|
82
|
+
* let newClients =
|
|
83
|
+
* await aui.ask(
|
|
84
|
+
* "How many new clients?",
|
|
85
|
+
* {
|
|
86
|
+
* json_schema: {
|
|
87
|
+
* "type": "number"
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* Output of console.log(newClients): 9123
|
|
92
|
+
*
|
|
93
|
+
* let userNames =
|
|
94
|
+
* await aui.ask(
|
|
95
|
+
* "Return a list with the users names.",
|
|
96
|
+
* {
|
|
97
|
+
* json_schema: {
|
|
98
|
+
* "type": "array",
|
|
99
|
+
* "items": {
|
|
100
|
+
* "type": "string"
|
|
101
|
+
* }
|
|
102
|
+
* }
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* Output of console.log(userNames):
|
|
106
|
+
* [
|
|
107
|
+
* 'Yiorgos Avraamu',
|
|
108
|
+
* 'Avram Tsarios',
|
|
109
|
+
* 'Quintin Ed',
|
|
110
|
+
* 'Enéas Kwadwo',
|
|
111
|
+
* 'Agapetus Tadeáš'
|
|
112
|
+
* ]
|
|
113
|
+
*
|
|
114
|
+
* let users =
|
|
115
|
+
* await aui.ask(
|
|
116
|
+
* "Extract the users from the table.",
|
|
117
|
+
* {
|
|
118
|
+
* json_schema: {
|
|
119
|
+
* "type": "array",
|
|
120
|
+
* "items": {
|
|
121
|
+
* "type": "object",
|
|
122
|
+
* "properties": {
|
|
123
|
+
* "name": {
|
|
124
|
+
* "type": "string"
|
|
125
|
+
* },
|
|
126
|
+
* "usage": {
|
|
127
|
+
* "type": "number"
|
|
128
|
+
* }
|
|
129
|
+
* },
|
|
130
|
+
* "additionalProperties": false,
|
|
131
|
+
* "required": ["name", "usage"]
|
|
132
|
+
* },
|
|
133
|
+
* },
|
|
134
|
+
* });
|
|
135
|
+
*
|
|
136
|
+
* Output of console.log(users):
|
|
137
|
+
* [
|
|
138
|
+
* { name: 'Yiorgos Avraamu', usage: 50 },
|
|
139
|
+
* { name: 'Avram Tarasios', usage: 10 },
|
|
140
|
+
* { name: 'Quintin Ed', usage: 74 },
|
|
141
|
+
* { name: 'Eneás Kwadwo', usage: 98 },
|
|
142
|
+
* { name: 'Agapetus Tadeáš', usage: 22 }
|
|
143
|
+
* ]
|
|
144
|
+
*
|
|
145
|
+
* @param {string} prompt - The question you want to be answered or
|
|
146
|
+
* the data you want to have extracted.
|
|
147
|
+
* @param {Object} config - object that specifies the return json: {json_schema: {...}}.
|
|
148
|
+
* @returns {any} - The answer as JSON specified in the config object.
|
|
149
|
+
*/
|
|
150
|
+
ask(prompt: string, config?: object): Promise<any>;
|
|
62
151
|
private secretText;
|
|
63
152
|
private getAndResetSecretText;
|
|
64
153
|
/**
|
|
@@ -166,6 +166,100 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
166
166
|
]);
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Takes a prompt that contains a question you want to be answered
|
|
171
|
+
* or the data you want to have extracted from your screen.
|
|
172
|
+
*
|
|
173
|
+
* The optional 'config' can be used to specifiy the JSON schema the
|
|
174
|
+
* returned object shall have (https://json-schema.org).
|
|
175
|
+
*
|
|
176
|
+
* See the following examples on how to use it:
|
|
177
|
+
*
|
|
178
|
+
* let isWidgetsNew =
|
|
179
|
+
* await aui.ask(
|
|
180
|
+
* "Does the sidebar element 'Widgets' have a 'NEW' tag?",
|
|
181
|
+
* {
|
|
182
|
+
* json_schema: {
|
|
183
|
+
* "type": "boolean"
|
|
184
|
+
* }
|
|
185
|
+
* });
|
|
186
|
+
*
|
|
187
|
+
* Output of console.log(isWidgetsNew): true
|
|
188
|
+
*
|
|
189
|
+
* let newClients =
|
|
190
|
+
* await aui.ask(
|
|
191
|
+
* "How many new clients?",
|
|
192
|
+
* {
|
|
193
|
+
* json_schema: {
|
|
194
|
+
* "type": "number"
|
|
195
|
+
* }
|
|
196
|
+
* });
|
|
197
|
+
*
|
|
198
|
+
* Output of console.log(newClients): 9123
|
|
199
|
+
*
|
|
200
|
+
* let userNames =
|
|
201
|
+
* await aui.ask(
|
|
202
|
+
* "Return a list with the users names.",
|
|
203
|
+
* {
|
|
204
|
+
* json_schema: {
|
|
205
|
+
* "type": "array",
|
|
206
|
+
* "items": {
|
|
207
|
+
* "type": "string"
|
|
208
|
+
* }
|
|
209
|
+
* }
|
|
210
|
+
* });
|
|
211
|
+
*
|
|
212
|
+
* Output of console.log(userNames):
|
|
213
|
+
* [
|
|
214
|
+
* 'Yiorgos Avraamu',
|
|
215
|
+
* 'Avram Tsarios',
|
|
216
|
+
* 'Quintin Ed',
|
|
217
|
+
* 'Enéas Kwadwo',
|
|
218
|
+
* 'Agapetus Tadeáš'
|
|
219
|
+
* ]
|
|
220
|
+
*
|
|
221
|
+
* let users =
|
|
222
|
+
* await aui.ask(
|
|
223
|
+
* "Extract the users from the table.",
|
|
224
|
+
* {
|
|
225
|
+
* json_schema: {
|
|
226
|
+
* "type": "array",
|
|
227
|
+
* "items": {
|
|
228
|
+
* "type": "object",
|
|
229
|
+
* "properties": {
|
|
230
|
+
* "name": {
|
|
231
|
+
* "type": "string"
|
|
232
|
+
* },
|
|
233
|
+
* "usage": {
|
|
234
|
+
* "type": "number"
|
|
235
|
+
* }
|
|
236
|
+
* },
|
|
237
|
+
* "additionalProperties": false,
|
|
238
|
+
* "required": ["name", "usage"]
|
|
239
|
+
* },
|
|
240
|
+
* },
|
|
241
|
+
* });
|
|
242
|
+
*
|
|
243
|
+
* Output of console.log(users):
|
|
244
|
+
* [
|
|
245
|
+
* { name: 'Yiorgos Avraamu', usage: 50 },
|
|
246
|
+
* { name: 'Avram Tarasios', usage: 10 },
|
|
247
|
+
* { name: 'Quintin Ed', usage: 74 },
|
|
248
|
+
* { name: 'Eneás Kwadwo', usage: 98 },
|
|
249
|
+
* { name: 'Agapetus Tadeáš', usage: 22 }
|
|
250
|
+
* ]
|
|
251
|
+
*
|
|
252
|
+
* @param {string} prompt - The question you want to be answered or
|
|
253
|
+
* the data you want to have extracted.
|
|
254
|
+
* @param {Object} config - object that specifies the return json: {json_schema: {...}}.
|
|
255
|
+
* @returns {any} - The answer as JSON specified in the config object.
|
|
256
|
+
*/
|
|
257
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
258
|
+
ask(prompt, config) {
|
|
259
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
260
|
+
return this.executionRuntime.predictVQA(prompt, config);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
169
263
|
getAndResetSecretText() {
|
|
170
264
|
const { secretText } = this;
|
|
171
265
|
this.secretText = undefined;
|
|
@@ -17,7 +17,6 @@ const inquirer_1 = __importDefault(require("inquirer"));
|
|
|
17
17
|
const commander_1 = require("commander");
|
|
18
18
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
19
19
|
const create_example_project_1 = require("./create-example-project");
|
|
20
|
-
const nonEmpty = (subject) => (input) => input.trim().length > 0 || `${subject} is required.`;
|
|
21
20
|
/* eslint-disable sort-keys */
|
|
22
21
|
const questions = [
|
|
23
22
|
{
|
|
@@ -26,21 +25,6 @@ const questions = [
|
|
|
26
25
|
message: 'Which framework do you prefer?:',
|
|
27
26
|
choices: ['jest'],
|
|
28
27
|
},
|
|
29
|
-
{
|
|
30
|
-
type: 'input',
|
|
31
|
-
name: 'workspaceId',
|
|
32
|
-
message: 'Your workspace id:',
|
|
33
|
-
validate: nonEmpty('workspace id'),
|
|
34
|
-
when: (answers) => !answers.skipCredentials,
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
type: 'password',
|
|
38
|
-
name: 'accessToken',
|
|
39
|
-
message: 'Your access token:',
|
|
40
|
-
mask: '*',
|
|
41
|
-
validate: nonEmpty('access token'),
|
|
42
|
-
when: (answers) => !answers.skipCredentials,
|
|
43
|
-
},
|
|
44
28
|
{
|
|
45
29
|
type: 'confirm',
|
|
46
30
|
name: 'typescriptConfig',
|
|
@@ -57,22 +41,6 @@ const options = [
|
|
|
57
41
|
description: 'the test framework to use.',
|
|
58
42
|
option: '-f, --test-framework <value>',
|
|
59
43
|
},
|
|
60
|
-
{
|
|
61
|
-
choices: [],
|
|
62
|
-
default: false,
|
|
63
|
-
description: 'skip the credentials setup.',
|
|
64
|
-
option: '-sc, --skip-credentials',
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
choices: [],
|
|
68
|
-
description: 'a workspace id.',
|
|
69
|
-
option: '-w, --workspace-id <value>',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
choices: [],
|
|
73
|
-
description: 'an access token for the workspace with the id.',
|
|
74
|
-
option: '-a, --access-token <value>',
|
|
75
|
-
},
|
|
76
44
|
{
|
|
77
45
|
choices: [],
|
|
78
46
|
default: 'askui_example',
|
|
@@ -18,7 +18,6 @@ export declare class CreateExampleProject {
|
|
|
18
18
|
private createAskUIHelperFromTemplate;
|
|
19
19
|
private setupTestFrameWork;
|
|
20
20
|
private static installTestFrameworkPackages;
|
|
21
|
-
private addUserCredentials;
|
|
22
21
|
private copyESLintConfigFiles;
|
|
23
22
|
private copyGitignore;
|
|
24
23
|
private copyTsConfigFile;
|
|
@@ -30,7 +30,7 @@ class CreateExampleProject {
|
|
|
30
30
|
this.projectRootDirectoryPath = process.cwd();
|
|
31
31
|
this.automationsDirectoryName = this.getAutomationsDirectoryName();
|
|
32
32
|
this.automationsDirectoryPath = path_1.default.join(this.projectRootDirectoryPath, this.automationsDirectoryName);
|
|
33
|
-
this.askUIControllerUrl = 'https://docs.askui.com/docs/
|
|
33
|
+
this.askUIControllerUrl = 'https://docs.askui.com/docs/suite/Components/AskUI-Development-Environment#askui-startcontroller-command';
|
|
34
34
|
this.helperTemplateConfig = {};
|
|
35
35
|
}
|
|
36
36
|
getAutomationsDirectoryName() {
|
|
@@ -131,10 +131,7 @@ class CreateExampleProject {
|
|
|
131
131
|
title: 'Create askui-helper.ts ',
|
|
132
132
|
task: () => __awaiter(this, void 0, void 0, function* () {
|
|
133
133
|
const askuiHelperTemplateFilePath = path_1.default.join((0, path_2.getPathToNodeModulesRoot)(), 'example_projects_templates', 'templates');
|
|
134
|
-
|
|
135
|
-
if (this.cliOptions.operatingSystem === 'windows') {
|
|
136
|
-
templateFileName = 'askui-helper-windows.nj';
|
|
137
|
-
}
|
|
134
|
+
const templateFileName = 'askui-helper.nj';
|
|
138
135
|
nunjucks_1.default.configure(askuiHelperTemplateFilePath, { autoescape: false });
|
|
139
136
|
const result = nunjucks_1.default.render(templateFileName, this.helperTemplateConfig);
|
|
140
137
|
const filePath = path_1.default.join(this.automationsDirectoryPath, 'helpers', 'askui-helper.ts');
|
|
@@ -193,24 +190,6 @@ class CreateExampleProject {
|
|
|
193
190
|
yield runCommand(frameworkDependencies.jest);
|
|
194
191
|
});
|
|
195
192
|
}
|
|
196
|
-
addUserCredentials() {
|
|
197
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
-
return [
|
|
199
|
-
{
|
|
200
|
-
/* eslint-disable sort-keys */
|
|
201
|
-
title: 'Add user credentials',
|
|
202
|
-
enabled: () => !this.cliOptions.skipCredentials,
|
|
203
|
-
task: () => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
-
this.helperTemplateConfig['credentials'] = ` credentials: {
|
|
205
|
-
workspaceId: '${this.cliOptions.workspaceId}',
|
|
206
|
-
token: '${this.cliOptions.accessToken}',
|
|
207
|
-
},`;
|
|
208
|
-
}),
|
|
209
|
-
},
|
|
210
|
-
/* eslint-enable */
|
|
211
|
-
];
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
193
|
copyESLintConfigFiles() {
|
|
215
194
|
return __awaiter(this, void 0, void 0, function* () {
|
|
216
195
|
const esLintRcFilePath = path_1.default.join('example_projects_templates', 'typescript', '.eslintrc.json-template');
|
|
@@ -282,20 +261,14 @@ class CreateExampleProject {
|
|
|
282
261
|
...(yield this.copyESLintConfigFiles()),
|
|
283
262
|
...(yield this.copyGitignore()),
|
|
284
263
|
...(yield this.copyTsConfigFile()),
|
|
285
|
-
...(yield this.addUserCredentials()),
|
|
286
264
|
...(yield this.createAskUIHelperFromTemplate()),
|
|
287
265
|
]);
|
|
288
266
|
yield tasks.run();
|
|
289
267
|
/* eslint-disable no-console */
|
|
290
268
|
console.log(chalk_1.default.greenBright('\nCongratulations!'));
|
|
291
269
|
console.log(`askui example was created under ${chalk_1.default.gray(this.automationsDirectoryPath)}`);
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
console.log(`You can start your automation with this command ${chalk_1.default.green('AskUI-RunProject')}`);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
console.log(`You can start your automation with this command ${chalk_1.default.green('npm run askui')}`);
|
|
298
|
-
}
|
|
270
|
+
console.log(chalk_1.default.redBright(`\nPlease make sure the AskUI Controller is running: ${this.askUIControllerUrl}\n`));
|
|
271
|
+
console.log(`You can start your automation with this command ${chalk_1.default.green('AskUI-RunProject')}`);
|
|
299
272
|
/* eslint-enable no-console */
|
|
300
273
|
});
|
|
301
274
|
}
|
|
@@ -14,6 +14,10 @@ const ui_controller_darwin_1 = require("./ui-controller-darwin");
|
|
|
14
14
|
const ui_controller_linux_1 = require("./ui-controller-linux");
|
|
15
15
|
const ui_controller_win32_1 = require("./ui-controller-win32");
|
|
16
16
|
const download_binaries_1 = require("./download-binaries");
|
|
17
|
+
/**
|
|
18
|
+
* @deprecated Will be removed soon because the AskUI Controller
|
|
19
|
+
* gets started as an operating system service.
|
|
20
|
+
*/
|
|
17
21
|
class UiController {
|
|
18
22
|
constructor(args) {
|
|
19
23
|
this.args = args;
|
|
@@ -5,6 +5,11 @@ export interface InferenceResponseBody {
|
|
|
5
5
|
type: ModelType;
|
|
6
6
|
data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation;
|
|
7
7
|
}
|
|
8
|
+
export interface VQAInferenceResponseBody {
|
|
9
|
+
data: {
|
|
10
|
+
response: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
8
13
|
export declare class InferenceResponse {
|
|
9
14
|
static fromJson(json: InferenceResponseBody, resizeRatio?: number, image?: string): ControlCommand | Annotation;
|
|
10
15
|
static createModels(type: ModelType, data: ModelType extends 'COMMANDS' ? ControlCommand : Annotation, resizeRatio: number, image?: string): ControlCommand | Annotation;
|
|
@@ -35,4 +35,5 @@ export declare class ExecutionRuntime {
|
|
|
35
35
|
takeScreenshotIfImageisNotProvided(imagePath?: string): Promise<string>;
|
|
36
36
|
getDetectedElements(instruction: string, customElementJson?: CustomElementJson[]): Promise<DetectedElement[]>;
|
|
37
37
|
annotateImage(imagePath?: string, customElementJson?: CustomElementJson[], elements?: DetectedElement[]): Promise<Annotation>;
|
|
38
|
+
predictVQA(prompt: string, config?: object): Promise<any>;
|
|
38
39
|
}
|
|
@@ -205,4 +205,10 @@ export class ExecutionRuntime {
|
|
|
205
205
|
return this.inferenceClient.predictImageAnnotation(base64Image, customElements);
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
|
+
predictVQA(prompt, config) {
|
|
209
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
210
|
+
const base64Image = yield this.takeScreenshotIfImageisNotProvided();
|
|
211
|
+
return this.inferenceClient.predictVQAAnswer(prompt, base64Image, config);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
208
214
|
}
|
|
@@ -3,6 +3,7 @@ import { ControlCommand } from '../core/ui-control-commands';
|
|
|
3
3
|
import { CustomElement } from '../core/model/custom-element';
|
|
4
4
|
import { Annotation } from '../core/annotation/annotation';
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
|
+
import { VQAInferenceResponseBody } from '../core/inference-response/inference-response';
|
|
6
7
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
8
|
export declare class InferenceClient {
|
|
8
9
|
private readonly baseUrl;
|
|
@@ -16,8 +17,10 @@ export declare class InferenceClient {
|
|
|
16
17
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
18
|
private resizeIfNeeded;
|
|
18
19
|
inference(customElements?: CustomElement[], image?: string, instruction?: string): Promise<ControlCommand | Annotation>;
|
|
20
|
+
vqaInference(image: string, prompt: string, config?: object): Promise<VQAInferenceResponseBody>;
|
|
19
21
|
private static logMetaInformation;
|
|
20
22
|
predictControlCommand(instruction: string, customElements?: CustomElement[], image?: string): Promise<ControlCommand>;
|
|
21
23
|
getDetectedElements(instruction: string, image: string, customElements?: CustomElement[]): Promise<DetectedElement[]>;
|
|
22
24
|
predictImageAnnotation(image: string, customElements?: CustomElement[]): Promise<Annotation>;
|
|
25
|
+
predictVQAAnswer(prompt: string, image: string, config?: object): Promise<any>;
|
|
23
26
|
}
|
|
@@ -29,6 +29,7 @@ export class InferenceClient {
|
|
|
29
29
|
this.urls = {
|
|
30
30
|
inference: urljoin(url, 'inference'),
|
|
31
31
|
isImageRequired: urljoin(url, 'instruction', 'is-image-required'),
|
|
32
|
+
vqaInference: urljoin(url, 'vqa', 'inference'),
|
|
32
33
|
};
|
|
33
34
|
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
34
35
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
@@ -71,6 +72,17 @@ export class InferenceClient {
|
|
|
71
72
|
return InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
72
73
|
});
|
|
73
74
|
}
|
|
75
|
+
vqaInference(image, prompt, config) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
const response = yield this.httpClient.post(this.urls.vqaInference, {
|
|
78
|
+
config,
|
|
79
|
+
image,
|
|
80
|
+
prompt,
|
|
81
|
+
});
|
|
82
|
+
InferenceClient.logMetaInformation(response);
|
|
83
|
+
return response.body;
|
|
84
|
+
});
|
|
85
|
+
}
|
|
74
86
|
static logMetaInformation(response) {
|
|
75
87
|
if (response.headers['askui-usage-warnings'] !== undefined) {
|
|
76
88
|
logger.warn(response.headers['askui-usage-warnings']);
|
|
@@ -103,4 +115,17 @@ export class InferenceClient {
|
|
|
103
115
|
return inferenceResponse;
|
|
104
116
|
});
|
|
105
117
|
}
|
|
118
|
+
predictVQAAnswer(prompt, image, config) {
|
|
119
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
120
|
+
const inferenceResponse = yield this.vqaInference(image, prompt, config);
|
|
121
|
+
const { response } = inferenceResponse.data;
|
|
122
|
+
try {
|
|
123
|
+
return JSON.parse(response);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
logger.warn(`Response is no valid JSON: ${response}`);
|
|
127
|
+
}
|
|
128
|
+
return response;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
106
131
|
}
|
|
@@ -59,6 +59,95 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
59
59
|
private getAIElementsByNames;
|
|
60
60
|
fluentCommandExecutor(instructionString: string, context?: CommandExecutorContext): Promise<void>;
|
|
61
61
|
getterExecutor(instruction: string, context?: CommandExecutorContext): Promise<DetectedElement[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Takes a prompt that contains a question you want to be answered
|
|
64
|
+
* or the data you want to have extracted from your screen.
|
|
65
|
+
*
|
|
66
|
+
* The optional 'config' can be used to specifiy the JSON schema the
|
|
67
|
+
* returned object shall have (https://json-schema.org).
|
|
68
|
+
*
|
|
69
|
+
* See the following examples on how to use it:
|
|
70
|
+
*
|
|
71
|
+
* let isWidgetsNew =
|
|
72
|
+
* await aui.ask(
|
|
73
|
+
* "Does the sidebar element 'Widgets' have a 'NEW' tag?",
|
|
74
|
+
* {
|
|
75
|
+
* json_schema: {
|
|
76
|
+
* "type": "boolean"
|
|
77
|
+
* }
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* Output of console.log(isWidgetsNew): true
|
|
81
|
+
*
|
|
82
|
+
* let newClients =
|
|
83
|
+
* await aui.ask(
|
|
84
|
+
* "How many new clients?",
|
|
85
|
+
* {
|
|
86
|
+
* json_schema: {
|
|
87
|
+
* "type": "number"
|
|
88
|
+
* }
|
|
89
|
+
* });
|
|
90
|
+
*
|
|
91
|
+
* Output of console.log(newClients): 9123
|
|
92
|
+
*
|
|
93
|
+
* let userNames =
|
|
94
|
+
* await aui.ask(
|
|
95
|
+
* "Return a list with the users names.",
|
|
96
|
+
* {
|
|
97
|
+
* json_schema: {
|
|
98
|
+
* "type": "array",
|
|
99
|
+
* "items": {
|
|
100
|
+
* "type": "string"
|
|
101
|
+
* }
|
|
102
|
+
* }
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* Output of console.log(userNames):
|
|
106
|
+
* [
|
|
107
|
+
* 'Yiorgos Avraamu',
|
|
108
|
+
* 'Avram Tsarios',
|
|
109
|
+
* 'Quintin Ed',
|
|
110
|
+
* 'Enéas Kwadwo',
|
|
111
|
+
* 'Agapetus Tadeáš'
|
|
112
|
+
* ]
|
|
113
|
+
*
|
|
114
|
+
* let users =
|
|
115
|
+
* await aui.ask(
|
|
116
|
+
* "Extract the users from the table.",
|
|
117
|
+
* {
|
|
118
|
+
* json_schema: {
|
|
119
|
+
* "type": "array",
|
|
120
|
+
* "items": {
|
|
121
|
+
* "type": "object",
|
|
122
|
+
* "properties": {
|
|
123
|
+
* "name": {
|
|
124
|
+
* "type": "string"
|
|
125
|
+
* },
|
|
126
|
+
* "usage": {
|
|
127
|
+
* "type": "number"
|
|
128
|
+
* }
|
|
129
|
+
* },
|
|
130
|
+
* "additionalProperties": false,
|
|
131
|
+
* "required": ["name", "usage"]
|
|
132
|
+
* },
|
|
133
|
+
* },
|
|
134
|
+
* });
|
|
135
|
+
*
|
|
136
|
+
* Output of console.log(users):
|
|
137
|
+
* [
|
|
138
|
+
* { name: 'Yiorgos Avraamu', usage: 50 },
|
|
139
|
+
* { name: 'Avram Tarasios', usage: 10 },
|
|
140
|
+
* { name: 'Quintin Ed', usage: 74 },
|
|
141
|
+
* { name: 'Eneás Kwadwo', usage: 98 },
|
|
142
|
+
* { name: 'Agapetus Tadeáš', usage: 22 }
|
|
143
|
+
* ]
|
|
144
|
+
*
|
|
145
|
+
* @param {string} prompt - The question you want to be answered or
|
|
146
|
+
* the data you want to have extracted.
|
|
147
|
+
* @param {Object} config - object that specifies the return json: {json_schema: {...}}.
|
|
148
|
+
* @returns {any} - The answer as JSON specified in the config object.
|
|
149
|
+
*/
|
|
150
|
+
ask(prompt: string, config?: object): Promise<any>;
|
|
62
151
|
private secretText;
|
|
63
152
|
private getAndResetSecretText;
|
|
64
153
|
/**
|
|
@@ -163,6 +163,100 @@ export class UiControlClient extends ApiCommands {
|
|
|
163
163
|
]);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
166
|
+
/**
|
|
167
|
+
* Takes a prompt that contains a question you want to be answered
|
|
168
|
+
* or the data you want to have extracted from your screen.
|
|
169
|
+
*
|
|
170
|
+
* The optional 'config' can be used to specifiy the JSON schema the
|
|
171
|
+
* returned object shall have (https://json-schema.org).
|
|
172
|
+
*
|
|
173
|
+
* See the following examples on how to use it:
|
|
174
|
+
*
|
|
175
|
+
* let isWidgetsNew =
|
|
176
|
+
* await aui.ask(
|
|
177
|
+
* "Does the sidebar element 'Widgets' have a 'NEW' tag?",
|
|
178
|
+
* {
|
|
179
|
+
* json_schema: {
|
|
180
|
+
* "type": "boolean"
|
|
181
|
+
* }
|
|
182
|
+
* });
|
|
183
|
+
*
|
|
184
|
+
* Output of console.log(isWidgetsNew): true
|
|
185
|
+
*
|
|
186
|
+
* let newClients =
|
|
187
|
+
* await aui.ask(
|
|
188
|
+
* "How many new clients?",
|
|
189
|
+
* {
|
|
190
|
+
* json_schema: {
|
|
191
|
+
* "type": "number"
|
|
192
|
+
* }
|
|
193
|
+
* });
|
|
194
|
+
*
|
|
195
|
+
* Output of console.log(newClients): 9123
|
|
196
|
+
*
|
|
197
|
+
* let userNames =
|
|
198
|
+
* await aui.ask(
|
|
199
|
+
* "Return a list with the users names.",
|
|
200
|
+
* {
|
|
201
|
+
* json_schema: {
|
|
202
|
+
* "type": "array",
|
|
203
|
+
* "items": {
|
|
204
|
+
* "type": "string"
|
|
205
|
+
* }
|
|
206
|
+
* }
|
|
207
|
+
* });
|
|
208
|
+
*
|
|
209
|
+
* Output of console.log(userNames):
|
|
210
|
+
* [
|
|
211
|
+
* 'Yiorgos Avraamu',
|
|
212
|
+
* 'Avram Tsarios',
|
|
213
|
+
* 'Quintin Ed',
|
|
214
|
+
* 'Enéas Kwadwo',
|
|
215
|
+
* 'Agapetus Tadeáš'
|
|
216
|
+
* ]
|
|
217
|
+
*
|
|
218
|
+
* let users =
|
|
219
|
+
* await aui.ask(
|
|
220
|
+
* "Extract the users from the table.",
|
|
221
|
+
* {
|
|
222
|
+
* json_schema: {
|
|
223
|
+
* "type": "array",
|
|
224
|
+
* "items": {
|
|
225
|
+
* "type": "object",
|
|
226
|
+
* "properties": {
|
|
227
|
+
* "name": {
|
|
228
|
+
* "type": "string"
|
|
229
|
+
* },
|
|
230
|
+
* "usage": {
|
|
231
|
+
* "type": "number"
|
|
232
|
+
* }
|
|
233
|
+
* },
|
|
234
|
+
* "additionalProperties": false,
|
|
235
|
+
* "required": ["name", "usage"]
|
|
236
|
+
* },
|
|
237
|
+
* },
|
|
238
|
+
* });
|
|
239
|
+
*
|
|
240
|
+
* Output of console.log(users):
|
|
241
|
+
* [
|
|
242
|
+
* { name: 'Yiorgos Avraamu', usage: 50 },
|
|
243
|
+
* { name: 'Avram Tarasios', usage: 10 },
|
|
244
|
+
* { name: 'Quintin Ed', usage: 74 },
|
|
245
|
+
* { name: 'Eneás Kwadwo', usage: 98 },
|
|
246
|
+
* { name: 'Agapetus Tadeáš', usage: 22 }
|
|
247
|
+
* ]
|
|
248
|
+
*
|
|
249
|
+
* @param {string} prompt - The question you want to be answered or
|
|
250
|
+
* the data you want to have extracted.
|
|
251
|
+
* @param {Object} config - object that specifies the return json: {json_schema: {...}}.
|
|
252
|
+
* @returns {any} - The answer as JSON specified in the config object.
|
|
253
|
+
*/
|
|
254
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
255
|
+
ask(prompt, config) {
|
|
256
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
257
|
+
return this.executionRuntime.predictVQA(prompt, config);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
166
260
|
getAndResetSecretText() {
|
|
167
261
|
const { secretText } = this;
|
|
168
262
|
this.secretText = undefined;
|
|
@@ -11,7 +11,6 @@ import inquirer from 'inquirer';
|
|
|
11
11
|
import { Command, Option } from 'commander';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
13
|
import { CreateExampleProject } from './create-example-project';
|
|
14
|
-
const nonEmpty = (subject) => (input) => input.trim().length > 0 || `${subject} is required.`;
|
|
15
14
|
/* eslint-disable sort-keys */
|
|
16
15
|
const questions = [
|
|
17
16
|
{
|
|
@@ -20,21 +19,6 @@ const questions = [
|
|
|
20
19
|
message: 'Which framework do you prefer?:',
|
|
21
20
|
choices: ['jest'],
|
|
22
21
|
},
|
|
23
|
-
{
|
|
24
|
-
type: 'input',
|
|
25
|
-
name: 'workspaceId',
|
|
26
|
-
message: 'Your workspace id:',
|
|
27
|
-
validate: nonEmpty('workspace id'),
|
|
28
|
-
when: (answers) => !answers.skipCredentials,
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
type: 'password',
|
|
32
|
-
name: 'accessToken',
|
|
33
|
-
message: 'Your access token:',
|
|
34
|
-
mask: '*',
|
|
35
|
-
validate: nonEmpty('access token'),
|
|
36
|
-
when: (answers) => !answers.skipCredentials,
|
|
37
|
-
},
|
|
38
22
|
{
|
|
39
23
|
type: 'confirm',
|
|
40
24
|
name: 'typescriptConfig',
|
|
@@ -51,22 +35,6 @@ const options = [
|
|
|
51
35
|
description: 'the test framework to use.',
|
|
52
36
|
option: '-f, --test-framework <value>',
|
|
53
37
|
},
|
|
54
|
-
{
|
|
55
|
-
choices: [],
|
|
56
|
-
default: false,
|
|
57
|
-
description: 'skip the credentials setup.',
|
|
58
|
-
option: '-sc, --skip-credentials',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
choices: [],
|
|
62
|
-
description: 'a workspace id.',
|
|
63
|
-
option: '-w, --workspace-id <value>',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
choices: [],
|
|
67
|
-
description: 'an access token for the workspace with the id.',
|
|
68
|
-
option: '-a, --access-token <value>',
|
|
69
|
-
},
|
|
70
38
|
{
|
|
71
39
|
choices: [],
|
|
72
40
|
default: 'askui_example',
|
|
@@ -18,7 +18,6 @@ export declare class CreateExampleProject {
|
|
|
18
18
|
private createAskUIHelperFromTemplate;
|
|
19
19
|
private setupTestFrameWork;
|
|
20
20
|
private static installTestFrameworkPackages;
|
|
21
|
-
private addUserCredentials;
|
|
22
21
|
private copyESLintConfigFiles;
|
|
23
22
|
private copyGitignore;
|
|
24
23
|
private copyTsConfigFile;
|
|
@@ -24,7 +24,7 @@ export class CreateExampleProject {
|
|
|
24
24
|
this.projectRootDirectoryPath = process.cwd();
|
|
25
25
|
this.automationsDirectoryName = this.getAutomationsDirectoryName();
|
|
26
26
|
this.automationsDirectoryPath = path.join(this.projectRootDirectoryPath, this.automationsDirectoryName);
|
|
27
|
-
this.askUIControllerUrl = 'https://docs.askui.com/docs/
|
|
27
|
+
this.askUIControllerUrl = 'https://docs.askui.com/docs/suite/Components/AskUI-Development-Environment#askui-startcontroller-command';
|
|
28
28
|
this.helperTemplateConfig = {};
|
|
29
29
|
}
|
|
30
30
|
getAutomationsDirectoryName() {
|
|
@@ -125,10 +125,7 @@ export class CreateExampleProject {
|
|
|
125
125
|
title: 'Create askui-helper.ts ',
|
|
126
126
|
task: () => __awaiter(this, void 0, void 0, function* () {
|
|
127
127
|
const askuiHelperTemplateFilePath = path.join(getPathToNodeModulesRoot(), 'example_projects_templates', 'templates');
|
|
128
|
-
|
|
129
|
-
if (this.cliOptions.operatingSystem === 'windows') {
|
|
130
|
-
templateFileName = 'askui-helper-windows.nj';
|
|
131
|
-
}
|
|
128
|
+
const templateFileName = 'askui-helper.nj';
|
|
132
129
|
nunjucks.configure(askuiHelperTemplateFilePath, { autoescape: false });
|
|
133
130
|
const result = nunjucks.render(templateFileName, this.helperTemplateConfig);
|
|
134
131
|
const filePath = path.join(this.automationsDirectoryPath, 'helpers', 'askui-helper.ts');
|
|
@@ -187,24 +184,6 @@ export class CreateExampleProject {
|
|
|
187
184
|
yield runCommand(frameworkDependencies.jest);
|
|
188
185
|
});
|
|
189
186
|
}
|
|
190
|
-
addUserCredentials() {
|
|
191
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
192
|
-
return [
|
|
193
|
-
{
|
|
194
|
-
/* eslint-disable sort-keys */
|
|
195
|
-
title: 'Add user credentials',
|
|
196
|
-
enabled: () => !this.cliOptions.skipCredentials,
|
|
197
|
-
task: () => __awaiter(this, void 0, void 0, function* () {
|
|
198
|
-
this.helperTemplateConfig['credentials'] = ` credentials: {
|
|
199
|
-
workspaceId: '${this.cliOptions.workspaceId}',
|
|
200
|
-
token: '${this.cliOptions.accessToken}',
|
|
201
|
-
},`;
|
|
202
|
-
}),
|
|
203
|
-
},
|
|
204
|
-
/* eslint-enable */
|
|
205
|
-
];
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
187
|
copyESLintConfigFiles() {
|
|
209
188
|
return __awaiter(this, void 0, void 0, function* () {
|
|
210
189
|
const esLintRcFilePath = path.join('example_projects_templates', 'typescript', '.eslintrc.json-template');
|
|
@@ -276,20 +255,14 @@ export class CreateExampleProject {
|
|
|
276
255
|
...(yield this.copyESLintConfigFiles()),
|
|
277
256
|
...(yield this.copyGitignore()),
|
|
278
257
|
...(yield this.copyTsConfigFile()),
|
|
279
|
-
...(yield this.addUserCredentials()),
|
|
280
258
|
...(yield this.createAskUIHelperFromTemplate()),
|
|
281
259
|
]);
|
|
282
260
|
yield tasks.run();
|
|
283
261
|
/* eslint-disable no-console */
|
|
284
262
|
console.log(chalk.greenBright('\nCongratulations!'));
|
|
285
263
|
console.log(`askui example was created under ${chalk.gray(this.automationsDirectoryPath)}`);
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
console.log(`You can start your automation with this command ${chalk.green('AskUI-RunProject')}`);
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
console.log(`You can start your automation with this command ${chalk.green('npm run askui')}`);
|
|
292
|
-
}
|
|
264
|
+
console.log(chalk.redBright(`\nPlease make sure the AskUI Controller is running: ${this.askUIControllerUrl}\n`));
|
|
265
|
+
console.log(`You can start your automation with this command ${chalk.green('AskUI-RunProject')}`);
|
|
293
266
|
/* eslint-enable no-console */
|
|
294
267
|
});
|
|
295
268
|
}
|
|
@@ -11,6 +11,10 @@ import { UiControllerDarwin } from './ui-controller-darwin';
|
|
|
11
11
|
import { UiControllerLinux } from './ui-controller-linux';
|
|
12
12
|
import { UiControllerWin32 } from './ui-controller-win32';
|
|
13
13
|
import { platform } from './download-binaries';
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated Will be removed soon because the AskUI Controller
|
|
16
|
+
* gets started as an operating system service.
|
|
17
|
+
*/
|
|
14
18
|
export class UiController {
|
|
15
19
|
constructor(args) {
|
|
16
20
|
this.args = args;
|
|
@@ -1,27 +1,14 @@
|
|
|
1
|
-
import { UiControlClient
|
|
1
|
+
import { UiControlClient } from 'askui';
|
|
2
2
|
{{ allure_stepreporter_import }}
|
|
3
3
|
|
|
4
|
-
// Server for controlling the operating system
|
|
5
|
-
let uiController: UiController;
|
|
6
|
-
|
|
7
4
|
// Client is necessary to use the askui API
|
|
5
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
8
6
|
let aui: UiControlClient;
|
|
9
7
|
|
|
10
8
|
{{ timeout_placeholder }}
|
|
11
9
|
|
|
12
10
|
beforeAll(async () => {
|
|
13
|
-
uiController = new UiController({
|
|
14
|
-
/**
|
|
15
|
-
* Select the display you want to run your tests on, display 0 is your main display;
|
|
16
|
-
* ignore if you have only one display
|
|
17
|
-
*/
|
|
18
|
-
display: 0,
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
await uiController.start();
|
|
22
|
-
|
|
23
11
|
aui = await UiControlClient.build({
|
|
24
|
-
{{ credentials }}
|
|
25
12
|
{{ reporter_placeholder }}
|
|
26
13
|
});
|
|
27
14
|
|
|
@@ -43,8 +30,6 @@ afterEach(async () => {
|
|
|
43
30
|
|
|
44
31
|
afterAll(async () => {
|
|
45
32
|
aui.disconnect();
|
|
46
|
-
|
|
47
|
-
await uiController.stop();
|
|
48
33
|
});
|
|
49
34
|
|
|
50
35
|
export { aui };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "askui",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.8",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "askui GmbH <info@askui.com> (http://www.askui.com/)",
|
|
6
6
|
"description": "Reliable, automated end-to-end-testing that depends on what is shown on your screen instead of the technology you are running on",
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { UiControlClient } from 'askui';
|
|
2
|
-
{{ allure_stepreporter_import }}
|
|
3
|
-
|
|
4
|
-
// Client is necessary to use the askui API
|
|
5
|
-
// eslint-disable-next-line import/no-mutable-exports
|
|
6
|
-
let aui: UiControlClient;
|
|
7
|
-
|
|
8
|
-
{{ timeout_placeholder }}
|
|
9
|
-
|
|
10
|
-
beforeAll(async () => {
|
|
11
|
-
aui = await UiControlClient.build({
|
|
12
|
-
{{ credentials }}
|
|
13
|
-
{{ reporter_placeholder }}
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
await aui.connect();
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
beforeEach(async () => {
|
|
20
|
-
/* Uncomment to enable video recording
|
|
21
|
-
await aui.startVideoRecording();
|
|
22
|
-
*/
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
afterEach(async () => {
|
|
26
|
-
/* Uncomment to enable video recording
|
|
27
|
-
await aui.stopVideoRecording();
|
|
28
|
-
{{ allure_stepreporter_attach_video }}
|
|
29
|
-
*/
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
afterAll(async () => {
|
|
33
|
-
aui.disconnect();
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
export { aui };
|