askui 0.10.4 → 0.11.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/reporting/default-step.js +5 -1
- package/dist/cjs/core/reporting/instruction.d.ts +1 -1
- package/dist/cjs/execution/index.d.ts +0 -1
- package/dist/cjs/execution/index.js +1 -3
- package/dist/cjs/execution/inference-client.d.ts +5 -5
- package/dist/cjs/execution/inference-client.js +10 -9
- package/dist/cjs/execution/ui-control-client-dependency-builder.js +2 -3
- package/dist/cjs/execution/ui-control-client.d.ts +0 -2
- package/dist/cjs/execution/ui-control-client.js +4 -18
- package/dist/cjs/execution/ui-controller-client-error.d.ts +3 -0
- package/dist/cjs/execution/ui-controller-client-error.js +10 -0
- package/dist/cjs/execution/ui-controller-client-interface.d.ts +1 -11
- package/dist/cjs/execution/ui-controller-client.js +7 -8
- package/dist/cjs/main.d.ts +3 -1
- package/dist/cjs/main.js +5 -2
- package/dist/cjs/utils/http/http-client-got.d.ts +4 -0
- package/dist/cjs/utils/http/http-client-got.js +48 -1
- package/dist/esm/core/reporting/default-step.js +5 -1
- package/dist/esm/core/reporting/instruction.d.ts +1 -1
- package/dist/esm/execution/index.d.ts +0 -1
- package/dist/esm/execution/index.js +0 -1
- package/dist/esm/execution/inference-client.d.ts +5 -5
- package/dist/esm/execution/inference-client.js +10 -9
- package/dist/esm/execution/ui-control-client-dependency-builder.js +2 -3
- package/dist/esm/execution/ui-control-client-error.d.ts +1 -0
- package/dist/esm/execution/ui-control-client-error.js +4 -0
- package/dist/esm/execution/ui-control-client.d.ts +0 -2
- package/dist/esm/execution/ui-control-client.js +4 -18
- package/dist/esm/execution/ui-controller-client-error.d.ts +3 -0
- package/dist/esm/execution/ui-controller-client-error.js +6 -0
- package/dist/esm/execution/ui-controller-client-interface.d.ts +1 -11
- package/dist/esm/execution/ui-controller-client.js +7 -8
- package/dist/esm/main.d.ts +3 -1
- package/dist/esm/main.js +3 -1
- package/dist/esm/utils/http/http-client-got.d.ts +4 -0
- package/dist/esm/utils/http/http-client-got.js +48 -1
- package/package.json +2 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DefaultStep = void 0;
|
|
4
|
+
const control_command_error_1 = require("../../execution/control-command-error");
|
|
4
5
|
class DefaultStep {
|
|
5
6
|
constructor(instruction) {
|
|
6
7
|
this.instruction = instruction;
|
|
@@ -66,9 +67,12 @@ class DefaultStep {
|
|
|
66
67
|
return this;
|
|
67
68
|
}
|
|
68
69
|
static determineLastRunStatus(error) {
|
|
69
|
-
if (error
|
|
70
|
+
if (error instanceof control_command_error_1.ControlCommandError) {
|
|
70
71
|
return 'failed';
|
|
71
72
|
}
|
|
73
|
+
if (error !== undefined) {
|
|
74
|
+
return 'erroneous';
|
|
75
|
+
}
|
|
72
76
|
return 'passed';
|
|
73
77
|
}
|
|
74
78
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.UiControlClient =
|
|
4
|
-
var annotation_level_1 = require("./annotation-level");
|
|
5
|
-
Object.defineProperty(exports, "AnnotationLevel", { enumerable: true, get: function () { return annotation_level_1.AnnotationLevel; } });
|
|
3
|
+
exports.UiControlClient = void 0;
|
|
6
4
|
var ui_control_client_1 = require("./ui-control-client");
|
|
7
5
|
Object.defineProperty(exports, "UiControlClient", { enumerable: true, get: function () { return ui_control_client_1.UiControlClient; } });
|
|
@@ -5,13 +5,13 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
6
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
7
|
export declare class InferenceClient {
|
|
8
|
-
baseUrl
|
|
9
|
-
httpClient
|
|
10
|
-
|
|
8
|
+
private readonly baseUrl;
|
|
9
|
+
private readonly httpClient;
|
|
10
|
+
private readonly resize?;
|
|
11
11
|
readonly workspaceId?: string | undefined;
|
|
12
12
|
readonly modelComposition?: ModelCompositionBranch[] | undefined;
|
|
13
|
-
apiVersion
|
|
14
|
-
|
|
13
|
+
private readonly apiVersion;
|
|
14
|
+
private urls;
|
|
15
15
|
constructor(baseUrl: string, httpClient: HttpClientGot, resize?: number | undefined, workspaceId?: string | undefined, modelComposition?: ModelCompositionBranch[] | undefined, apiVersion?: string);
|
|
16
16
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
17
|
private resizeIfNeeded;
|
|
@@ -29,9 +29,14 @@ class InferenceClient {
|
|
|
29
29
|
this.modelComposition = modelComposition;
|
|
30
30
|
this.apiVersion = apiVersion;
|
|
31
31
|
const versionedBaseUrl = (0, url_join_1.default)(this.baseUrl, 'api', this.apiVersion);
|
|
32
|
-
|
|
32
|
+
const url = workspaceId
|
|
33
33
|
? (0, url_join_1.default)(versionedBaseUrl, 'workspaces', workspaceId)
|
|
34
34
|
: versionedBaseUrl;
|
|
35
|
+
this.urls = {
|
|
36
|
+
inference: (0, url_join_1.default)(url, 'inference'),
|
|
37
|
+
isImageRequired: (0, url_join_1.default)(url, 'instruction', 'is-image-required'),
|
|
38
|
+
};
|
|
39
|
+
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
35
40
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
36
41
|
throw new config_error_1.ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
37
42
|
}
|
|
@@ -39,11 +44,9 @@ class InferenceClient {
|
|
|
39
44
|
}
|
|
40
45
|
isImageRequired(instruction) {
|
|
41
46
|
return __awaiter(this, void 0, void 0, function* () {
|
|
42
|
-
const
|
|
43
|
-
const requestBody = {
|
|
47
|
+
const response = yield this.httpClient.post(this.urls.isImageRequired, {
|
|
44
48
|
instruction,
|
|
45
|
-
};
|
|
46
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
49
|
+
});
|
|
47
50
|
return response.body.isImageRequired;
|
|
48
51
|
});
|
|
49
52
|
}
|
|
@@ -59,14 +62,12 @@ class InferenceClient {
|
|
|
59
62
|
inference(customElements = [], image, instruction) {
|
|
60
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
64
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
62
|
-
const
|
|
65
|
+
const response = yield this.httpClient.post(this.urls.inference, {
|
|
63
66
|
image: resizedImage.base64Image,
|
|
64
67
|
instruction,
|
|
65
68
|
customElements,
|
|
66
69
|
modelComposition: this.modelComposition,
|
|
67
|
-
};
|
|
68
|
-
const url = (0, url_join_1.default)(this.url, 'inference');
|
|
69
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
70
|
+
});
|
|
70
71
|
InferenceClient.logMetaInformation(response);
|
|
71
72
|
return ui_control_commands_1.InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
72
73
|
});
|
|
@@ -16,7 +16,6 @@ const inference_client_1 = require("./inference-client");
|
|
|
16
16
|
const read_environment_credentials_1 = require("./read-environment-credentials");
|
|
17
17
|
const analytics_1 = require("../utils/analytics");
|
|
18
18
|
const proxy_builder_1 = require("../utils/proxy/proxy-builder");
|
|
19
|
-
const annotation_level_1 = require("./annotation-level");
|
|
20
19
|
const execution_runtime_1 = require("./execution-runtime");
|
|
21
20
|
const reporting_1 = require("../core/reporting");
|
|
22
21
|
class UiControlClientDependencyBuilder {
|
|
@@ -63,9 +62,9 @@ class UiControlClientDependencyBuilder {
|
|
|
63
62
|
};
|
|
64
63
|
}
|
|
65
64
|
static getClientArgsWithDefaults(clientArgs) {
|
|
66
|
-
var _a, _b, _c, _d
|
|
65
|
+
var _a, _b, _c, _d;
|
|
67
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
68
|
-
return Object.assign(Object.assign({}, clientArgs), { uiControllerUrl: (_a = clientArgs.uiControllerUrl) !== null && _a !== void 0 ? _a : 'http://127.0.0.1:6769', inferenceServerUrl: (_b = clientArgs.inferenceServerUrl) !== null && _b !== void 0 ? _b : 'https://inference.askui.com',
|
|
67
|
+
return Object.assign(Object.assign({}, clientArgs), { uiControllerUrl: (_a = clientArgs.uiControllerUrl) !== null && _a !== void 0 ? _a : 'http://127.0.0.1:6769', inferenceServerUrl: (_b = clientArgs.inferenceServerUrl) !== null && _b !== void 0 ? _b : 'https://inference.askui.com', credentials: (_c = clientArgs.credentials) !== null && _c !== void 0 ? _c : (0, read_environment_credentials_1.envCredentials)(), proxyAgents: (_d = clientArgs.proxyAgents) !== null && _d !== void 0 ? _d : yield (0, proxy_builder_1.envProxyAgents)(), reporter: UiControlClientDependencyBuilder.buildReporter(clientArgs.reporter) });
|
|
69
68
|
});
|
|
70
69
|
}
|
|
71
70
|
}
|
|
@@ -6,7 +6,6 @@ import { AnnotationRequest } from '../core/model/annotation-result/annotation-in
|
|
|
6
6
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
7
7
|
import { ClientArgs } from './ui-controller-client-interface';
|
|
8
8
|
export declare class UiControlClient extends ApiCommands {
|
|
9
|
-
private config;
|
|
10
9
|
private executionRuntime;
|
|
11
10
|
private stepReporter;
|
|
12
11
|
private constructor();
|
|
@@ -28,7 +27,6 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
28
27
|
startVideoRecording(): Promise<void>;
|
|
29
28
|
stopVideoRecording(): Promise<void>;
|
|
30
29
|
readVideoRecording(): Promise<string>;
|
|
31
|
-
private shouldWriteAnntotationAfterCommandExecution;
|
|
32
30
|
private shouldAnnotateAfterCommandExecution;
|
|
33
31
|
private afterCommandExecution;
|
|
34
32
|
annotate(annotationRequest?: AnnotationRequest): Promise<Annotation>;
|
|
@@ -14,13 +14,10 @@ const custom_element_1 = require("../core/model/custom-element");
|
|
|
14
14
|
const dsl_1 = require("./dsl");
|
|
15
15
|
const annotation_writer_1 = require("../core/annotation/annotation-writer");
|
|
16
16
|
const logger_1 = require("../lib/logger");
|
|
17
|
-
const annotation_level_1 = require("./annotation-level");
|
|
18
|
-
const ui_control_client_error_1 = require("./ui-control-client-error");
|
|
19
17
|
const ui_control_client_dependency_builder_1 = require("./ui-control-client-dependency-builder");
|
|
20
18
|
class UiControlClient extends dsl_1.ApiCommands {
|
|
21
|
-
constructor(
|
|
19
|
+
constructor(executionRuntime, stepReporter) {
|
|
22
20
|
super();
|
|
23
|
-
this.config = config;
|
|
24
21
|
this.executionRuntime = executionRuntime;
|
|
25
22
|
this.stepReporter = stepReporter;
|
|
26
23
|
this.secretText = undefined;
|
|
@@ -30,9 +27,7 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
30
27
|
const builder = ui_control_client_dependency_builder_1.UiControlClientDependencyBuilder;
|
|
31
28
|
const clientArgsWithDefaults = yield builder.getClientArgsWithDefaults(clientArgs);
|
|
32
29
|
const { executionRuntime, stepReporter } = yield builder.build(clientArgsWithDefaults);
|
|
33
|
-
return new UiControlClient(
|
|
34
|
-
annotationLevel: clientArgsWithDefaults.annotationLevel,
|
|
35
|
-
}, executionRuntime, stepReporter);
|
|
30
|
+
return new UiControlClient(executionRuntime, stepReporter);
|
|
36
31
|
});
|
|
37
32
|
}
|
|
38
33
|
/**
|
|
@@ -72,14 +67,8 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
72
67
|
return this.executionRuntime.readVideoRecording();
|
|
73
68
|
});
|
|
74
69
|
}
|
|
75
|
-
shouldWriteAnntotationAfterCommandExecution(error) {
|
|
76
|
-
const { annotationLevel } = this.config;
|
|
77
|
-
return annotationLevel === annotation_level_1.AnnotationLevel.ALL
|
|
78
|
-
|| (annotationLevel === annotation_level_1.AnnotationLevel.ON_FAILURE && error !== undefined);
|
|
79
|
-
}
|
|
80
70
|
shouldAnnotateAfterCommandExecution(error) {
|
|
81
|
-
return this.
|
|
82
|
-
|| (this.stepReporter.config.withDetectedElements === 'onFailure' && error !== undefined)
|
|
71
|
+
return (this.stepReporter.config.withDetectedElements === 'onFailure' && error !== undefined)
|
|
83
72
|
|| (this.stepReporter.config.withDetectedElements === 'always');
|
|
84
73
|
}
|
|
85
74
|
afterCommandExecution(instruction, error) {
|
|
@@ -91,9 +80,6 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
91
80
|
if (this.shouldAnnotateAfterCommandExecution(error)) {
|
|
92
81
|
annotation = yield this.executionRuntime.annotateImage(undefined, instruction.customElements);
|
|
93
82
|
}
|
|
94
|
-
if (annotation !== undefined && this.shouldWriteAnntotationAfterCommandExecution(error)) {
|
|
95
|
-
annotation_writer_1.AnnotationWriter.write(annotation.toHtml(), undefined, `${error !== undefined ? 'failed' : 'passed'}_testStep_annotation`);
|
|
96
|
-
}
|
|
97
83
|
if (annotation !== undefined || this.stepReporter.config.withScreenshots === 'always') {
|
|
98
84
|
screenshot = (_a = annotation === null || annotation === void 0 ? void 0 : annotation.image) !== null && _a !== void 0 ? _a : yield this.executionRuntime.getScreenshot();
|
|
99
85
|
}
|
|
@@ -147,7 +133,7 @@ class UiControlClient extends dsl_1.ApiCommands {
|
|
|
147
133
|
}
|
|
148
134
|
catch (error) {
|
|
149
135
|
yield this.afterCommandExecution(instruction, error instanceof Error ? error : new Error(String(error)));
|
|
150
|
-
return Promise.reject(
|
|
136
|
+
return Promise.reject(error);
|
|
151
137
|
}
|
|
152
138
|
});
|
|
153
139
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UiControllerClientError = void 0;
|
|
4
|
+
class UiControllerClientError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'UiControllerClientError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.UiControllerClientError = UiControllerClientError;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { AnnotationLevel } from './annotation-level';
|
|
2
1
|
import { CredentialArgs } from './credentials-args';
|
|
3
2
|
import { ProxyAgentArgs } from '../shared/proxy-agent-args';
|
|
4
3
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
5
|
-
import { Reporter, ReporterConfig } from '
|
|
4
|
+
import { Reporter, ReporterConfig } from '../core/reporting';
|
|
6
5
|
/**
|
|
7
6
|
* Configuration options for the askui UI Control Client
|
|
8
7
|
*
|
|
@@ -18,10 +17,6 @@ import { Reporter, ReporterConfig } from '@/core/reporting';
|
|
|
18
17
|
* But it can cause a decrease in the prediction quality.
|
|
19
18
|
* @param {string} inferenceServerUrl - Default: https://inference.askui.com`
|
|
20
19
|
* Address of the askui Inference server.
|
|
21
|
-
* @param {AnnotationLevel} annotationLevel - Default: AnnotationLevel.DISABLED
|
|
22
|
-
* Usage of annotate command
|
|
23
|
-
* after execution of test steps.
|
|
24
|
-
* You have three options: `DISABLED`, `ON_FAILURE`, `ALL`.
|
|
25
20
|
* @param {CredentialArgs} credentials - We need to provide credentials for
|
|
26
21
|
* the authentication of the askui Inference Server.
|
|
27
22
|
* You have three options: `DISABLED`, `ON_FAILURE`, `ALL`.
|
|
@@ -31,7 +26,6 @@ import { Reporter, ReporterConfig } from '@/core/reporting';
|
|
|
31
26
|
export interface ClientArgs {
|
|
32
27
|
readonly uiControllerUrl?: string;
|
|
33
28
|
readonly inferenceServerUrl?: string;
|
|
34
|
-
readonly annotationLevel?: AnnotationLevel;
|
|
35
29
|
readonly credentials?: CredentialArgs | undefined;
|
|
36
30
|
readonly proxyAgents?: ProxyAgentArgs | undefined;
|
|
37
31
|
readonly resize?: number;
|
|
@@ -41,11 +35,7 @@ export interface ClientArgs {
|
|
|
41
35
|
export interface ClientArgsWithDefaults extends ClientArgs {
|
|
42
36
|
readonly uiControllerUrl: string;
|
|
43
37
|
readonly inferenceServerUrl: string;
|
|
44
|
-
readonly annotationLevel: AnnotationLevel;
|
|
45
38
|
readonly reporter: Required<Reporter> & {
|
|
46
39
|
config: Required<ReporterConfig>;
|
|
47
40
|
};
|
|
48
41
|
}
|
|
49
|
-
export interface UiControlClientConfig {
|
|
50
|
-
annotationLevel: AnnotationLevel;
|
|
51
|
-
}
|
|
@@ -9,7 +9,7 @@ const runner_protocol_1 = require("../core/runner-protocol");
|
|
|
9
9
|
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
|
-
const
|
|
12
|
+
const ui_controller_client_error_1 = require("./ui-controller-client-error");
|
|
13
13
|
class UiControllerClient {
|
|
14
14
|
constructor(url) {
|
|
15
15
|
this.url = url;
|
|
@@ -47,13 +47,13 @@ class UiControllerClient {
|
|
|
47
47
|
});
|
|
48
48
|
this.ws.on('error', (error) => {
|
|
49
49
|
this.connectionState = ui_controller_client_connection_state_1.UiControllerClientConnectionState.ERROR;
|
|
50
|
-
reject(new
|
|
50
|
+
reject(new ui_controller_client_error_1.UiControllerClientError(`Connection to UI Controller cannot be established,
|
|
51
51
|
Probably it was not started. Make sure you started UI Controller with this
|
|
52
|
-
Url ${this.url}.
|
|
52
|
+
Url ${this.url}. Cause: ${error}`));
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
56
|
-
reject(new
|
|
56
|
+
reject(new ui_controller_client_error_1.UiControllerClientError(`Connection to UI Controller cannot be established. Cause: ${error}`));
|
|
57
57
|
}
|
|
58
58
|
});
|
|
59
59
|
}
|
|
@@ -67,17 +67,16 @@ class UiControllerClient {
|
|
|
67
67
|
this.currentReject = reject;
|
|
68
68
|
try {
|
|
69
69
|
this.send(msg, requestTimeout);
|
|
70
|
-
this.timeout = setTimeout(() => this.currentReject(
|
|
71
|
-
It seems that the UI Controller is not running. Please, make sure that it is running when executing tests.`), UiControllerClient.REQUEST_TIMEOUT_IN_MS);
|
|
70
|
+
this.timeout = setTimeout(() => this.currentReject(new ui_controller_client_error_1.UiControllerClientError('Request to UI Controller timed out. It seems that the UI Controller is not running. Please, make sure that it is running when executing tests.')), UiControllerClient.REQUEST_TIMEOUT_IN_MS);
|
|
72
71
|
}
|
|
73
72
|
catch (error) {
|
|
74
|
-
this.currentReject(`The communication to the UI Controller is broken.
|
|
73
|
+
this.currentReject(new ui_controller_client_error_1.UiControllerClientError(`The communication to the UI Controller is broken. Cause: ${error}`));
|
|
75
74
|
}
|
|
76
75
|
});
|
|
77
76
|
}
|
|
78
77
|
send(msg, _requestTimeout = UiControllerClient.REQUEST_TIMEOUT_IN_MS) {
|
|
79
78
|
if (!this.currentReject || !this.currentResolve) {
|
|
80
|
-
throw
|
|
79
|
+
throw new ui_controller_client_error_1.UiControllerClientError('Request is not finished! It is not possible to have multiple requests at the same time.');
|
|
81
80
|
}
|
|
82
81
|
logger_1.logger.debug(`Send: ${JSON.stringify(msg.msgName)}`);
|
|
83
82
|
this.ws.send(JSON.stringify(msg));
|
package/dist/cjs/main.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { UiController } from './lib';
|
|
2
|
-
export {
|
|
2
|
+
export { UiControlClient } from './execution';
|
|
3
3
|
export { Instruction, Reporter, ReporterConfig, Snapshot, SnapshotDetailLevel, Step, StepStatus, StepStatusEnd, } from './core/reporting';
|
|
4
|
+
export { Annotation } from './core/annotation/annotation';
|
|
5
|
+
export { DetectedElement } from './core/model/annotation-result/detected-element';
|
|
4
6
|
export { LogLevels } from './shared';
|
package/dist/cjs/main.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogLevels = exports.
|
|
3
|
+
exports.LogLevels = exports.DetectedElement = exports.Annotation = exports.UiControlClient = exports.UiController = void 0;
|
|
4
4
|
var lib_1 = require("./lib");
|
|
5
5
|
Object.defineProperty(exports, "UiController", { enumerable: true, get: function () { return lib_1.UiController; } });
|
|
6
6
|
var execution_1 = require("./execution");
|
|
7
|
-
Object.defineProperty(exports, "AnnotationLevel", { enumerable: true, get: function () { return execution_1.AnnotationLevel; } });
|
|
8
7
|
Object.defineProperty(exports, "UiControlClient", { enumerable: true, get: function () { return execution_1.UiControlClient; } });
|
|
8
|
+
var annotation_1 = require("./core/annotation/annotation");
|
|
9
|
+
Object.defineProperty(exports, "Annotation", { enumerable: true, get: function () { return annotation_1.Annotation; } });
|
|
10
|
+
var detected_element_1 = require("./core/model/annotation-result/detected-element");
|
|
11
|
+
Object.defineProperty(exports, "DetectedElement", { enumerable: true, get: function () { return detected_element_1.DetectedElement; } });
|
|
9
12
|
var shared_1 = require("./shared");
|
|
10
13
|
Object.defineProperty(exports, "LogLevels", { enumerable: true, get: function () { return shared_1.LogLevels; } });
|
|
@@ -12,10 +12,14 @@ export declare class HttpClientGot {
|
|
|
12
12
|
} | undefined;
|
|
13
13
|
private headers;
|
|
14
14
|
private askuiGot;
|
|
15
|
+
urlsToRetry: string[];
|
|
15
16
|
constructor(token?: string | undefined, customHeaders?: Record<string, string> | undefined, cookies?: Record<string, string>, proxyAgents?: {
|
|
16
17
|
http: http.Agent;
|
|
17
18
|
https: https.Agent;
|
|
18
19
|
} | undefined);
|
|
20
|
+
private buildGotExtendOptions;
|
|
21
|
+
private shouldRetryOnError;
|
|
22
|
+
private shouldRetryPostRequest;
|
|
19
23
|
private initHeaders;
|
|
20
24
|
private injectHeadersAndCookies;
|
|
21
25
|
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
@@ -25,8 +25,55 @@ class HttpClientGot {
|
|
|
25
25
|
this.cookies = cookies;
|
|
26
26
|
this.proxyAgents = proxyAgents;
|
|
27
27
|
this.headers = {};
|
|
28
|
+
this.urlsToRetry = [];
|
|
28
29
|
this.initHeaders(token, customHeaders);
|
|
29
|
-
|
|
30
|
+
const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
|
|
31
|
+
this.askuiGot = got_1.default.extend(gotExtendOptions);
|
|
32
|
+
}
|
|
33
|
+
buildGotExtendOptions(proxyAgents) {
|
|
34
|
+
const gotExtendOptions = {
|
|
35
|
+
retry: {
|
|
36
|
+
limit: 5,
|
|
37
|
+
methods: ['POST', 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'],
|
|
38
|
+
statusCodes: [408, 413, 429, 500, 502, 503, 504, 521, 522, 524],
|
|
39
|
+
errorCodes: [
|
|
40
|
+
'ETIMEDOUT',
|
|
41
|
+
'ECONNRESET',
|
|
42
|
+
'EADDRINUSE',
|
|
43
|
+
'ECONNREFUSED',
|
|
44
|
+
'EPIPE',
|
|
45
|
+
'ENOTFOUND',
|
|
46
|
+
'ENETUNREACH',
|
|
47
|
+
'EAI_AGAIN',
|
|
48
|
+
],
|
|
49
|
+
calculateDelay: ({ attemptCount, retryOptions, error, computedValue, }) => {
|
|
50
|
+
var _a, _b, _c;
|
|
51
|
+
if (attemptCount > retryOptions.limit
|
|
52
|
+
|| !this.shouldRetryOnError(error)) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
if (error.response !== undefined
|
|
56
|
+
&& error.response.headers['retry-after'] === undefined) {
|
|
57
|
+
lib_1.logger.debug(`Request to ${(_a = error.request) === null || _a === void 0 ? void 0 : _a.requestUrl} failed with status code ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode}.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
58
|
+
return Math.min(1000 * Math.pow(2, (attemptCount - 1)) + Math.random() * 100, Number.MAX_SAFE_INTEGER);
|
|
59
|
+
}
|
|
60
|
+
lib_1.logger.debug(`Request to ${(_c = error.request) === null || _c === void 0 ? void 0 : _c.requestUrl} failed.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
61
|
+
return computedValue;
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
if (proxyAgents) {
|
|
66
|
+
gotExtendOptions.agent = proxyAgents;
|
|
67
|
+
}
|
|
68
|
+
return gotExtendOptions;
|
|
69
|
+
}
|
|
70
|
+
shouldRetryOnError(error) {
|
|
71
|
+
var _a;
|
|
72
|
+
return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
|
|
73
|
+
|| this.shouldRetryPostRequest(error.request));
|
|
74
|
+
}
|
|
75
|
+
shouldRetryPostRequest(request) {
|
|
76
|
+
return (request !== undefined && this.urlsToRetry.includes(request.requestUrl));
|
|
30
77
|
}
|
|
31
78
|
initHeaders(token, customHeaders = {}) {
|
|
32
79
|
const credentials = token ? new credentials_1.Credentials(token) : undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ControlCommandError } from '../../execution/control-command-error';
|
|
1
2
|
export class DefaultStep {
|
|
2
3
|
constructor(instruction) {
|
|
3
4
|
this.instruction = instruction;
|
|
@@ -63,9 +64,12 @@ export class DefaultStep {
|
|
|
63
64
|
return this;
|
|
64
65
|
}
|
|
65
66
|
static determineLastRunStatus(error) {
|
|
66
|
-
if (error
|
|
67
|
+
if (error instanceof ControlCommandError) {
|
|
67
68
|
return 'failed';
|
|
68
69
|
}
|
|
70
|
+
if (error !== undefined) {
|
|
71
|
+
return 'erroneous';
|
|
72
|
+
}
|
|
69
73
|
return 'passed';
|
|
70
74
|
}
|
|
71
75
|
}
|
|
@@ -5,13 +5,13 @@ import { Annotation } from '../core/annotation/annotation';
|
|
|
5
5
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
6
6
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
7
7
|
export declare class InferenceClient {
|
|
8
|
-
baseUrl
|
|
9
|
-
httpClient
|
|
10
|
-
|
|
8
|
+
private readonly baseUrl;
|
|
9
|
+
private readonly httpClient;
|
|
10
|
+
private readonly resize?;
|
|
11
11
|
readonly workspaceId?: string | undefined;
|
|
12
12
|
readonly modelComposition?: ModelCompositionBranch[] | undefined;
|
|
13
|
-
apiVersion
|
|
14
|
-
|
|
13
|
+
private readonly apiVersion;
|
|
14
|
+
private urls;
|
|
15
15
|
constructor(baseUrl: string, httpClient: HttpClientGot, resize?: number | undefined, workspaceId?: string | undefined, modelComposition?: ModelCompositionBranch[] | undefined, apiVersion?: string);
|
|
16
16
|
isImageRequired(instruction: string): Promise<boolean>;
|
|
17
17
|
private resizeIfNeeded;
|
|
@@ -23,9 +23,14 @@ export class InferenceClient {
|
|
|
23
23
|
this.modelComposition = modelComposition;
|
|
24
24
|
this.apiVersion = apiVersion;
|
|
25
25
|
const versionedBaseUrl = urljoin(this.baseUrl, 'api', this.apiVersion);
|
|
26
|
-
|
|
26
|
+
const url = workspaceId
|
|
27
27
|
? urljoin(versionedBaseUrl, 'workspaces', workspaceId)
|
|
28
28
|
: versionedBaseUrl;
|
|
29
|
+
this.urls = {
|
|
30
|
+
inference: urljoin(url, 'inference'),
|
|
31
|
+
isImageRequired: urljoin(url, 'instruction', 'is-image-required'),
|
|
32
|
+
};
|
|
33
|
+
this.httpClient.urlsToRetry = Object.values(this.urls);
|
|
29
34
|
if (this.resize !== undefined && this.resize <= 0) {
|
|
30
35
|
throw new ConfigurationError(`Resize must be a positive number. The current resize value "${this.resize}" is not valid.`);
|
|
31
36
|
}
|
|
@@ -33,11 +38,9 @@ export class InferenceClient {
|
|
|
33
38
|
}
|
|
34
39
|
isImageRequired(instruction) {
|
|
35
40
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
const
|
|
37
|
-
const requestBody = {
|
|
41
|
+
const response = yield this.httpClient.post(this.urls.isImageRequired, {
|
|
38
42
|
instruction,
|
|
39
|
-
};
|
|
40
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
43
|
+
});
|
|
41
44
|
return response.body.isImageRequired;
|
|
42
45
|
});
|
|
43
46
|
}
|
|
@@ -53,14 +56,12 @@ export class InferenceClient {
|
|
|
53
56
|
inference(customElements = [], image, instruction) {
|
|
54
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55
58
|
const resizedImage = yield this.resizeIfNeeded(customElements, image);
|
|
56
|
-
const
|
|
59
|
+
const response = yield this.httpClient.post(this.urls.inference, {
|
|
57
60
|
image: resizedImage.base64Image,
|
|
58
61
|
instruction,
|
|
59
62
|
customElements,
|
|
60
63
|
modelComposition: this.modelComposition,
|
|
61
|
-
};
|
|
62
|
-
const url = urljoin(this.url, 'inference');
|
|
63
|
-
const response = yield this.httpClient.post(url, requestBody);
|
|
64
|
+
});
|
|
64
65
|
InferenceClient.logMetaInformation(response);
|
|
65
66
|
return InferenceResponse.fromJson(response.body, resizedImage.resizeRatio, image);
|
|
66
67
|
});
|
|
@@ -13,7 +13,6 @@ import { InferenceClient } from './inference-client';
|
|
|
13
13
|
import { envCredentials } from './read-environment-credentials';
|
|
14
14
|
import { Analytics } from '../utils/analytics';
|
|
15
15
|
import { envProxyAgents } from '../utils/proxy/proxy-builder';
|
|
16
|
-
import { AnnotationLevel } from './annotation-level';
|
|
17
16
|
import { ExecutionRuntime } from './execution-runtime';
|
|
18
17
|
import { DEFAULT_REPORTER, StepReporter, } from '../core/reporting';
|
|
19
18
|
export class UiControlClientDependencyBuilder {
|
|
@@ -60,9 +59,9 @@ export class UiControlClientDependencyBuilder {
|
|
|
60
59
|
};
|
|
61
60
|
}
|
|
62
61
|
static getClientArgsWithDefaults(clientArgs) {
|
|
63
|
-
var _a, _b, _c, _d
|
|
62
|
+
var _a, _b, _c, _d;
|
|
64
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
return Object.assign(Object.assign({}, clientArgs), { uiControllerUrl: (_a = clientArgs.uiControllerUrl) !== null && _a !== void 0 ? _a : 'http://127.0.0.1:6769', inferenceServerUrl: (_b = clientArgs.inferenceServerUrl) !== null && _b !== void 0 ? _b : 'https://inference.askui.com',
|
|
64
|
+
return Object.assign(Object.assign({}, clientArgs), { uiControllerUrl: (_a = clientArgs.uiControllerUrl) !== null && _a !== void 0 ? _a : 'http://127.0.0.1:6769', inferenceServerUrl: (_b = clientArgs.inferenceServerUrl) !== null && _b !== void 0 ? _b : 'https://inference.askui.com', credentials: (_c = clientArgs.credentials) !== null && _c !== void 0 ? _c : envCredentials(), proxyAgents: (_d = clientArgs.proxyAgents) !== null && _d !== void 0 ? _d : yield envProxyAgents(), reporter: UiControlClientDependencyBuilder.buildReporter(clientArgs.reporter) });
|
|
66
65
|
});
|
|
67
66
|
}
|
|
68
67
|
}
|
|
@@ -6,7 +6,6 @@ import { AnnotationRequest } from '../core/model/annotation-result/annotation-in
|
|
|
6
6
|
import { DetectedElement } from '../core/model/annotation-result/detected-element';
|
|
7
7
|
import { ClientArgs } from './ui-controller-client-interface';
|
|
8
8
|
export declare class UiControlClient extends ApiCommands {
|
|
9
|
-
private config;
|
|
10
9
|
private executionRuntime;
|
|
11
10
|
private stepReporter;
|
|
12
11
|
private constructor();
|
|
@@ -28,7 +27,6 @@ export declare class UiControlClient extends ApiCommands {
|
|
|
28
27
|
startVideoRecording(): Promise<void>;
|
|
29
28
|
stopVideoRecording(): Promise<void>;
|
|
30
29
|
readVideoRecording(): Promise<string>;
|
|
31
|
-
private shouldWriteAnntotationAfterCommandExecution;
|
|
32
30
|
private shouldAnnotateAfterCommandExecution;
|
|
33
31
|
private afterCommandExecution;
|
|
34
32
|
annotate(annotationRequest?: AnnotationRequest): Promise<Annotation>;
|
|
@@ -11,13 +11,10 @@ import { CustomElement } from '../core/model/custom-element';
|
|
|
11
11
|
import { ApiCommands, Separators, } from './dsl';
|
|
12
12
|
import { AnnotationWriter } from '../core/annotation/annotation-writer';
|
|
13
13
|
import { logger } from '../lib/logger';
|
|
14
|
-
import { AnnotationLevel } from './annotation-level';
|
|
15
|
-
import { UiControlClientError } from './ui-control-client-error';
|
|
16
14
|
import { UiControlClientDependencyBuilder } from './ui-control-client-dependency-builder';
|
|
17
15
|
export class UiControlClient extends ApiCommands {
|
|
18
|
-
constructor(
|
|
16
|
+
constructor(executionRuntime, stepReporter) {
|
|
19
17
|
super();
|
|
20
|
-
this.config = config;
|
|
21
18
|
this.executionRuntime = executionRuntime;
|
|
22
19
|
this.stepReporter = stepReporter;
|
|
23
20
|
this.secretText = undefined;
|
|
@@ -27,9 +24,7 @@ export class UiControlClient extends ApiCommands {
|
|
|
27
24
|
const builder = UiControlClientDependencyBuilder;
|
|
28
25
|
const clientArgsWithDefaults = yield builder.getClientArgsWithDefaults(clientArgs);
|
|
29
26
|
const { executionRuntime, stepReporter } = yield builder.build(clientArgsWithDefaults);
|
|
30
|
-
return new UiControlClient(
|
|
31
|
-
annotationLevel: clientArgsWithDefaults.annotationLevel,
|
|
32
|
-
}, executionRuntime, stepReporter);
|
|
27
|
+
return new UiControlClient(executionRuntime, stepReporter);
|
|
33
28
|
});
|
|
34
29
|
}
|
|
35
30
|
/**
|
|
@@ -69,14 +64,8 @@ export class UiControlClient extends ApiCommands {
|
|
|
69
64
|
return this.executionRuntime.readVideoRecording();
|
|
70
65
|
});
|
|
71
66
|
}
|
|
72
|
-
shouldWriteAnntotationAfterCommandExecution(error) {
|
|
73
|
-
const { annotationLevel } = this.config;
|
|
74
|
-
return annotationLevel === AnnotationLevel.ALL
|
|
75
|
-
|| (annotationLevel === AnnotationLevel.ON_FAILURE && error !== undefined);
|
|
76
|
-
}
|
|
77
67
|
shouldAnnotateAfterCommandExecution(error) {
|
|
78
|
-
return this.
|
|
79
|
-
|| (this.stepReporter.config.withDetectedElements === 'onFailure' && error !== undefined)
|
|
68
|
+
return (this.stepReporter.config.withDetectedElements === 'onFailure' && error !== undefined)
|
|
80
69
|
|| (this.stepReporter.config.withDetectedElements === 'always');
|
|
81
70
|
}
|
|
82
71
|
afterCommandExecution(instruction, error) {
|
|
@@ -88,9 +77,6 @@ export class UiControlClient extends ApiCommands {
|
|
|
88
77
|
if (this.shouldAnnotateAfterCommandExecution(error)) {
|
|
89
78
|
annotation = yield this.executionRuntime.annotateImage(undefined, instruction.customElements);
|
|
90
79
|
}
|
|
91
|
-
if (annotation !== undefined && this.shouldWriteAnntotationAfterCommandExecution(error)) {
|
|
92
|
-
AnnotationWriter.write(annotation.toHtml(), undefined, `${error !== undefined ? 'failed' : 'passed'}_testStep_annotation`);
|
|
93
|
-
}
|
|
94
80
|
if (annotation !== undefined || this.stepReporter.config.withScreenshots === 'always') {
|
|
95
81
|
screenshot = (_a = annotation === null || annotation === void 0 ? void 0 : annotation.image) !== null && _a !== void 0 ? _a : yield this.executionRuntime.getScreenshot();
|
|
96
82
|
}
|
|
@@ -144,7 +130,7 @@ export class UiControlClient extends ApiCommands {
|
|
|
144
130
|
}
|
|
145
131
|
catch (error) {
|
|
146
132
|
yield this.afterCommandExecution(instruction, error instanceof Error ? error : new Error(String(error)));
|
|
147
|
-
return Promise.reject(
|
|
133
|
+
return Promise.reject(error);
|
|
148
134
|
}
|
|
149
135
|
});
|
|
150
136
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { AnnotationLevel } from './annotation-level';
|
|
2
1
|
import { CredentialArgs } from './credentials-args';
|
|
3
2
|
import { ProxyAgentArgs } from '../shared/proxy-agent-args';
|
|
4
3
|
import { ModelCompositionBranch } from './model-composition-branch';
|
|
5
|
-
import { Reporter, ReporterConfig } from '
|
|
4
|
+
import { Reporter, ReporterConfig } from '../core/reporting';
|
|
6
5
|
/**
|
|
7
6
|
* Configuration options for the askui UI Control Client
|
|
8
7
|
*
|
|
@@ -18,10 +17,6 @@ import { Reporter, ReporterConfig } from '@/core/reporting';
|
|
|
18
17
|
* But it can cause a decrease in the prediction quality.
|
|
19
18
|
* @param {string} inferenceServerUrl - Default: https://inference.askui.com`
|
|
20
19
|
* Address of the askui Inference server.
|
|
21
|
-
* @param {AnnotationLevel} annotationLevel - Default: AnnotationLevel.DISABLED
|
|
22
|
-
* Usage of annotate command
|
|
23
|
-
* after execution of test steps.
|
|
24
|
-
* You have three options: `DISABLED`, `ON_FAILURE`, `ALL`.
|
|
25
20
|
* @param {CredentialArgs} credentials - We need to provide credentials for
|
|
26
21
|
* the authentication of the askui Inference Server.
|
|
27
22
|
* You have three options: `DISABLED`, `ON_FAILURE`, `ALL`.
|
|
@@ -31,7 +26,6 @@ import { Reporter, ReporterConfig } from '@/core/reporting';
|
|
|
31
26
|
export interface ClientArgs {
|
|
32
27
|
readonly uiControllerUrl?: string;
|
|
33
28
|
readonly inferenceServerUrl?: string;
|
|
34
|
-
readonly annotationLevel?: AnnotationLevel;
|
|
35
29
|
readonly credentials?: CredentialArgs | undefined;
|
|
36
30
|
readonly proxyAgents?: ProxyAgentArgs | undefined;
|
|
37
31
|
readonly resize?: number;
|
|
@@ -41,11 +35,7 @@ export interface ClientArgs {
|
|
|
41
35
|
export interface ClientArgsWithDefaults extends ClientArgs {
|
|
42
36
|
readonly uiControllerUrl: string;
|
|
43
37
|
readonly inferenceServerUrl: string;
|
|
44
|
-
readonly annotationLevel: AnnotationLevel;
|
|
45
38
|
readonly reporter: Required<Reporter> & {
|
|
46
39
|
config: Required<ReporterConfig>;
|
|
47
40
|
};
|
|
48
41
|
}
|
|
49
|
-
export interface UiControlClientConfig {
|
|
50
|
-
annotationLevel: AnnotationLevel;
|
|
51
|
-
}
|
|
@@ -3,7 +3,7 @@ import { CaptureScreenshotRequest, ControlRequest, StartRecordingRequest, StopRe
|
|
|
3
3
|
import { logger } from '../lib/logger';
|
|
4
4
|
import { UiControllerClientConnectionState } from './ui-controller-client-connection-state';
|
|
5
5
|
import { ReadRecordingResponseStreamHandler } from './read-recording-response-stream-handler';
|
|
6
|
-
import {
|
|
6
|
+
import { UiControllerClientError } from './ui-controller-client-error';
|
|
7
7
|
export class UiControllerClient {
|
|
8
8
|
constructor(url) {
|
|
9
9
|
this.url = url;
|
|
@@ -41,13 +41,13 @@ export class UiControllerClient {
|
|
|
41
41
|
});
|
|
42
42
|
this.ws.on('error', (error) => {
|
|
43
43
|
this.connectionState = UiControllerClientConnectionState.ERROR;
|
|
44
|
-
reject(new
|
|
44
|
+
reject(new UiControllerClientError(`Connection to UI Controller cannot be established,
|
|
45
45
|
Probably it was not started. Make sure you started UI Controller with this
|
|
46
|
-
Url ${this.url}.
|
|
46
|
+
Url ${this.url}. Cause: ${error}`));
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
catch (error) {
|
|
50
|
-
reject(new
|
|
50
|
+
reject(new UiControllerClientError(`Connection to UI Controller cannot be established. Cause: ${error}`));
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -61,17 +61,16 @@ export class UiControllerClient {
|
|
|
61
61
|
this.currentReject = reject;
|
|
62
62
|
try {
|
|
63
63
|
this.send(msg, requestTimeout);
|
|
64
|
-
this.timeout = setTimeout(() => this.currentReject(
|
|
65
|
-
It seems that the UI Controller is not running. Please, make sure that it is running when executing tests.`), UiControllerClient.REQUEST_TIMEOUT_IN_MS);
|
|
64
|
+
this.timeout = setTimeout(() => this.currentReject(new UiControllerClientError('Request to UI Controller timed out. It seems that the UI Controller is not running. Please, make sure that it is running when executing tests.')), UiControllerClient.REQUEST_TIMEOUT_IN_MS);
|
|
66
65
|
}
|
|
67
66
|
catch (error) {
|
|
68
|
-
this.currentReject(`The communication to the UI Controller is broken.
|
|
67
|
+
this.currentReject(new UiControllerClientError(`The communication to the UI Controller is broken. Cause: ${error}`));
|
|
69
68
|
}
|
|
70
69
|
});
|
|
71
70
|
}
|
|
72
71
|
send(msg, _requestTimeout = UiControllerClient.REQUEST_TIMEOUT_IN_MS) {
|
|
73
72
|
if (!this.currentReject || !this.currentResolve) {
|
|
74
|
-
throw
|
|
73
|
+
throw new UiControllerClientError('Request is not finished! It is not possible to have multiple requests at the same time.');
|
|
75
74
|
}
|
|
76
75
|
logger.debug(`Send: ${JSON.stringify(msg.msgName)}`);
|
|
77
76
|
this.ws.send(JSON.stringify(msg));
|
package/dist/esm/main.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { UiController } from './lib';
|
|
2
|
-
export {
|
|
2
|
+
export { UiControlClient } from './execution';
|
|
3
3
|
export { Instruction, Reporter, ReporterConfig, Snapshot, SnapshotDetailLevel, Step, StepStatus, StepStatusEnd, } from './core/reporting';
|
|
4
|
+
export { Annotation } from './core/annotation/annotation';
|
|
5
|
+
export { DetectedElement } from './core/model/annotation-result/detected-element';
|
|
4
6
|
export { LogLevels } from './shared';
|
package/dist/esm/main.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { UiController } from './lib';
|
|
2
|
-
export {
|
|
2
|
+
export { UiControlClient } from './execution';
|
|
3
|
+
export { Annotation } from './core/annotation/annotation';
|
|
4
|
+
export { DetectedElement } from './core/model/annotation-result/detected-element';
|
|
3
5
|
export { LogLevels } from './shared';
|
|
@@ -12,10 +12,14 @@ export declare class HttpClientGot {
|
|
|
12
12
|
} | undefined;
|
|
13
13
|
private headers;
|
|
14
14
|
private askuiGot;
|
|
15
|
+
urlsToRetry: string[];
|
|
15
16
|
constructor(token?: string | undefined, customHeaders?: Record<string, string> | undefined, cookies?: Record<string, string>, proxyAgents?: {
|
|
16
17
|
http: http.Agent;
|
|
17
18
|
https: https.Agent;
|
|
18
19
|
} | undefined);
|
|
20
|
+
private buildGotExtendOptions;
|
|
21
|
+
private shouldRetryOnError;
|
|
22
|
+
private shouldRetryPostRequest;
|
|
19
23
|
private initHeaders;
|
|
20
24
|
private injectHeadersAndCookies;
|
|
21
25
|
post<T>(url: string, data: Record<string | number | symbol, unknown>): Promise<{
|
|
@@ -19,8 +19,55 @@ export class HttpClientGot {
|
|
|
19
19
|
this.cookies = cookies;
|
|
20
20
|
this.proxyAgents = proxyAgents;
|
|
21
21
|
this.headers = {};
|
|
22
|
+
this.urlsToRetry = [];
|
|
22
23
|
this.initHeaders(token, customHeaders);
|
|
23
|
-
|
|
24
|
+
const gotExtendOptions = this.buildGotExtendOptions(proxyAgents);
|
|
25
|
+
this.askuiGot = got.extend(gotExtendOptions);
|
|
26
|
+
}
|
|
27
|
+
buildGotExtendOptions(proxyAgents) {
|
|
28
|
+
const gotExtendOptions = {
|
|
29
|
+
retry: {
|
|
30
|
+
limit: 5,
|
|
31
|
+
methods: ['POST', 'GET', 'PUT', 'HEAD', 'DELETE', 'OPTIONS', 'TRACE'],
|
|
32
|
+
statusCodes: [408, 413, 429, 500, 502, 503, 504, 521, 522, 524],
|
|
33
|
+
errorCodes: [
|
|
34
|
+
'ETIMEDOUT',
|
|
35
|
+
'ECONNRESET',
|
|
36
|
+
'EADDRINUSE',
|
|
37
|
+
'ECONNREFUSED',
|
|
38
|
+
'EPIPE',
|
|
39
|
+
'ENOTFOUND',
|
|
40
|
+
'ENETUNREACH',
|
|
41
|
+
'EAI_AGAIN',
|
|
42
|
+
],
|
|
43
|
+
calculateDelay: ({ attemptCount, retryOptions, error, computedValue, }) => {
|
|
44
|
+
var _a, _b, _c;
|
|
45
|
+
if (attemptCount > retryOptions.limit
|
|
46
|
+
|| !this.shouldRetryOnError(error)) {
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
|
49
|
+
if (error.response !== undefined
|
|
50
|
+
&& error.response.headers['retry-after'] === undefined) {
|
|
51
|
+
logger.debug(`Request to ${(_a = error.request) === null || _a === void 0 ? void 0 : _a.requestUrl} failed with status code ${(_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode}.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
52
|
+
return Math.min(1000 * Math.pow(2, (attemptCount - 1)) + Math.random() * 100, Number.MAX_SAFE_INTEGER);
|
|
53
|
+
}
|
|
54
|
+
logger.debug(`Request to ${(_c = error.request) === null || _c === void 0 ? void 0 : _c.requestUrl} failed.\n${error.message}\nRetrying... (attempt ${attemptCount})`);
|
|
55
|
+
return computedValue;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
if (proxyAgents) {
|
|
60
|
+
gotExtendOptions.agent = proxyAgents;
|
|
61
|
+
}
|
|
62
|
+
return gotExtendOptions;
|
|
63
|
+
}
|
|
64
|
+
shouldRetryOnError(error) {
|
|
65
|
+
var _a;
|
|
66
|
+
return (((_a = error.request) === null || _a === void 0 ? void 0 : _a.options.method) !== 'POST'
|
|
67
|
+
|| this.shouldRetryPostRequest(error.request));
|
|
68
|
+
}
|
|
69
|
+
shouldRetryPostRequest(request) {
|
|
70
|
+
return (request !== undefined && this.urlsToRetry.includes(request.requestUrl));
|
|
24
71
|
}
|
|
25
72
|
initHeaders(token, customHeaders = {}) {
|
|
26
73
|
const credentials = token ? new Credentials(token) : undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "askui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
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",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"commander": "8.3.0",
|
|
53
53
|
"fkill": "7.2.1",
|
|
54
54
|
"fs-extra": "10.0.0",
|
|
55
|
-
"got": "11.8.
|
|
55
|
+
"got": "11.8.6",
|
|
56
56
|
"jsdom": "20.0.0",
|
|
57
57
|
"node-machine-id": "1.1.12",
|
|
58
58
|
"pino": "7.8.1",
|