suitest-js-api 3.20.1 → 3.21.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/index.d.ts +51 -13
- package/lib/chains/imageChain.js +2 -0
- package/lib/commands/pairDevice.js +4 -4
- package/lib/commands/releaseDevice.js +2 -2
- package/lib/commands/setAppConfig.js +3 -3
- package/lib/commands/startRecording.js +3 -2
- package/lib/commands/stopRecording.js +3 -2
- package/lib/composers/index.js +2 -0
- package/lib/composers/onScreenComposer.js +14 -0
- package/lib/constants/composer.js +1 -0
- package/lib/utils/AuthContext.js +17 -9
- package/lib/validation/jsonSchemas.js +13 -1
- package/package.json +3 -3
- package/typeDefinition/ImageChain.d.ts +4 -0
- package/typeDefinition/modifiers.d.ts +5 -1
- package/typeDefinition/utils/index.d.ts +2 -1
package/index.d.ts
CHANGED
|
@@ -60,15 +60,39 @@ export = suitest;
|
|
|
60
60
|
|
|
61
61
|
declare namespace suitest {
|
|
62
62
|
export interface ISuitestBase extends NodeJS.EventEmitter {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
/**
|
|
64
|
+
* @throws {SuitestError}
|
|
65
|
+
*/
|
|
66
|
+
openSession(options: OpenSessionOptions): Promise<OpenSessionResult>;
|
|
67
|
+
/**
|
|
68
|
+
* @throws {SuitestError}
|
|
69
|
+
*/
|
|
70
|
+
closeSession(): Promise<void>;
|
|
71
|
+
/**
|
|
72
|
+
* @throws {SuitestError}
|
|
73
|
+
*/
|
|
74
|
+
setAppConfig(configId: string, options?: ConfigOverride): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* @throws {SuitestError}
|
|
77
|
+
*/
|
|
78
|
+
pairDevice(deviceId: string, recordingSettings?: {recording?: 'autostart' | 'manualstart' | 'none', webhookUrl?: string}): Promise<DeviceData>;
|
|
79
|
+
/**
|
|
80
|
+
* @throws {SuitestError}
|
|
81
|
+
*/
|
|
82
|
+
releaseDevice(): Promise<void>;
|
|
68
83
|
startREPL(options?: ReplOptions): Promise<void>;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
84
|
+
/**
|
|
85
|
+
* @throws {SuitestError}
|
|
86
|
+
*/
|
|
87
|
+
getAppConfig(): Promise<AppConfiguration>;
|
|
88
|
+
/**
|
|
89
|
+
* @throws {SuitestError}
|
|
90
|
+
*/
|
|
91
|
+
startRecording({webhookUrl}?: {webhookUrl: string}): Promise<string | undefined>;
|
|
92
|
+
/**
|
|
93
|
+
* @throws {SuitestError}
|
|
94
|
+
*/
|
|
95
|
+
stopRecording({discard}?: {discard: boolean}): Promise<void>;
|
|
72
96
|
|
|
73
97
|
// config
|
|
74
98
|
getConfig(): ConfigureOptions;
|
|
@@ -267,7 +291,7 @@ declare namespace suitest {
|
|
|
267
291
|
id: string;
|
|
268
292
|
firmware: string;
|
|
269
293
|
modelId: string;
|
|
270
|
-
recordingUrl
|
|
294
|
+
recordingUrl?: string;
|
|
271
295
|
}
|
|
272
296
|
|
|
273
297
|
interface ConfigOverride {
|
|
@@ -324,17 +348,31 @@ declare namespace suitest {
|
|
|
324
348
|
}
|
|
325
349
|
|
|
326
350
|
interface AuthContext {
|
|
327
|
-
headers:
|
|
351
|
+
headers: Record<string, string>;
|
|
328
352
|
tokenKey: string;
|
|
329
353
|
|
|
330
354
|
setContext(newContext: symbol, tokenId: string|undefined, tokenPassword: string|undefined): void;
|
|
331
355
|
clear(): void;
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* @throws {SuitestError}
|
|
359
|
+
*/
|
|
360
|
+
authorizeHttp<T extends object>(requestkey: string, requestObject: T, errorOptions?: SuitestErrorOptions): Promise<WithHeaders<T>>;
|
|
361
|
+
/**
|
|
362
|
+
* @throws {SuitestError}
|
|
363
|
+
*/
|
|
364
|
+
authorizeWs<T extends object>(contentObject: T, commandName: string): Promise<T>;
|
|
365
|
+
/**
|
|
366
|
+
* @throws {SuitestError}
|
|
367
|
+
*/
|
|
368
|
+
authorizeWsConnection<T extends object>(connectObject: T, commandName: string): Promise<WithHeaders<T>>;
|
|
335
369
|
getToken(): string;
|
|
336
370
|
}
|
|
337
371
|
|
|
372
|
+
type WithHeaders<T extends object> = T & {
|
|
373
|
+
headers: Record<string, string>
|
|
374
|
+
}
|
|
375
|
+
|
|
338
376
|
interface SuitestErrorOptions {
|
|
339
377
|
commandName?: string;
|
|
340
378
|
type?: string;
|
package/lib/chains/imageChain.js
CHANGED
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
notComposer,
|
|
13
13
|
inRegionComposer,
|
|
14
14
|
accuracyComposer,
|
|
15
|
+
onScreenComposer,
|
|
15
16
|
} = require('../composers');
|
|
16
17
|
const makeChain = require('../utils/makeChain');
|
|
17
18
|
const {getRequestType} = require('../utils/socketChainHelper');
|
|
@@ -102,6 +103,7 @@ const imageChainFactory = (classInstance) => {
|
|
|
102
103
|
thenComposer,
|
|
103
104
|
cloneComposer,
|
|
104
105
|
toJSONComposer,
|
|
106
|
+
onScreenComposer,
|
|
105
107
|
];
|
|
106
108
|
|
|
107
109
|
if (!data.isAssert) {
|
|
@@ -19,15 +19,15 @@ const SuitestError = require('../utils/SuitestError');
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Pair with device
|
|
22
|
-
* @param {
|
|
22
|
+
* @param {suitest.ISuitest} instance - main class instance
|
|
23
23
|
* @param {string} deviceId - device to connect to
|
|
24
|
-
* @param {
|
|
25
|
-
* @returns {
|
|
24
|
+
* @param {{recording?: 'autostart' | 'manualstart' | 'none', webhookUrl?: string}} [recordingSettings]
|
|
25
|
+
* @returns {Promise<DeviceData>}
|
|
26
26
|
*/
|
|
27
27
|
async function pairDevice(
|
|
28
28
|
{webSockets, authContext, logger, pairedDeviceContext, config},
|
|
29
29
|
deviceId,
|
|
30
|
-
recordingSettings
|
|
30
|
+
recordingSettings,
|
|
31
31
|
) {
|
|
32
32
|
// validate deviceId string to be in uuid format
|
|
33
33
|
validate(validators.UUID, deviceId, invalidInputMessage(pairDevice.name, 'Device id'));
|
|
@@ -10,8 +10,8 @@ const {disconnectedFromDevice, disconnectingFromDevice} = require('../texts');
|
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Release paired device
|
|
13
|
-
* @param {
|
|
14
|
-
* @returns {
|
|
13
|
+
* @param {suitest.ISuitest} instance of main class
|
|
14
|
+
* @returns {Promise<void>}
|
|
15
15
|
*/
|
|
16
16
|
async function releaseDevice({webSockets, authContext, pairedDeviceContext, logger}) {
|
|
17
17
|
logger.delayed(disconnectingFromDevice());
|
|
@@ -9,10 +9,10 @@ const {invalidInputMessage, usingAppConfig, usedAppConfig, useAppConfigOverrides
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Set application config
|
|
12
|
-
* @param {
|
|
12
|
+
* @param {suitest.ISuitest} instance of main class
|
|
13
13
|
* @param {string} configId - config Id
|
|
14
|
-
* @param {
|
|
15
|
-
* @returns {Promise
|
|
14
|
+
* @param {suitest.ConfigOverride} [configOverride] - an optional override of the configuration
|
|
15
|
+
* @returns {Promise<void>}
|
|
16
16
|
*/
|
|
17
17
|
async function setAppConfig({appContext, authContext, webSockets, logger}, configId, configOverride = {}) {
|
|
18
18
|
// validate input
|
|
@@ -8,8 +8,9 @@ const {startRecordingMessage} = require('../texts');
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Start recording
|
|
11
|
-
* @param {
|
|
12
|
-
* @
|
|
11
|
+
* @param {suitest.ISuitest} instance of main class
|
|
12
|
+
* @param {{webhookUrl: string}} [recordingSettings]
|
|
13
|
+
* @returns {Promise<string | undefined>}
|
|
13
14
|
*/
|
|
14
15
|
async function startRecording({webSockets, authContext, logger}, recordingSettings) {
|
|
15
16
|
const webhookUrl = recordingSettings ? recordingSettings.webhookUrl : undefined;
|
|
@@ -8,8 +8,9 @@ const {stopRecordingMessage} = require('../texts');
|
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Stop recording
|
|
11
|
-
* @param {
|
|
12
|
-
* @
|
|
11
|
+
* @param {suitest.ISuitest} instance of main class
|
|
12
|
+
* @param {{discard: boolean}} [recordingSettings]
|
|
13
|
+
* @returns {Promise<void>}
|
|
13
14
|
*/
|
|
14
15
|
async function stopRecording({webSockets, authContext, logger}, recordingSettings) {
|
|
15
16
|
const discard = recordingSettings ? recordingSettings.discard : false;
|
package/lib/composers/index.js
CHANGED
|
@@ -49,6 +49,7 @@ const withPropertiesComposer = require('./withPropertiesComposer');
|
|
|
49
49
|
const inRegionComposer = require('./inRegionComposer');
|
|
50
50
|
const languageComposer = require('./languageComposer');
|
|
51
51
|
const {accuracyComposer} = require('./accuracyComposer');
|
|
52
|
+
const onScreenComposer = require('./onScreenComposer');
|
|
52
53
|
|
|
53
54
|
module.exports = {
|
|
54
55
|
abandonComposer,
|
|
@@ -104,4 +105,5 @@ module.exports = {
|
|
|
104
105
|
inRegionComposer,
|
|
105
106
|
languageComposer,
|
|
106
107
|
accuracyComposer,
|
|
108
|
+
onScreenComposer,
|
|
107
109
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const {makeModifierComposer} = require('../utils/makeComposer');
|
|
2
|
+
const composers = require('../constants/composer');
|
|
3
|
+
|
|
4
|
+
const onScreenComposer = makeModifierComposer(composers.ON_SCREEN, ['onScreen'], (_, meta) => {
|
|
5
|
+
const newMetaData = {...meta};
|
|
6
|
+
|
|
7
|
+
if ('region' in newMetaData) {
|
|
8
|
+
delete newMetaData.region;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return newMetaData;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
module.exports = onScreenComposer;
|
package/lib/utils/AuthContext.js
CHANGED
|
@@ -56,9 +56,11 @@ const allowedRequests = {
|
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Decorate http requestObject with current context headers
|
|
59
|
-
* @
|
|
60
|
-
* @
|
|
61
|
-
* @
|
|
59
|
+
* @template T
|
|
60
|
+
* @template U
|
|
61
|
+
* @param {T} requestObject
|
|
62
|
+
* @param {U} headers
|
|
63
|
+
* @returns {T & {headers: U}} requestObject decorated with auth headers
|
|
62
64
|
*/
|
|
63
65
|
function decorateRequestObject(requestObject, headers) {
|
|
64
66
|
return Object.assign({}, requestObject, {headers});
|
|
@@ -128,10 +130,12 @@ class AuthContext extends Context {
|
|
|
128
130
|
/**
|
|
129
131
|
* Check if http request is allowed based on request key and current context.
|
|
130
132
|
* Decorate request object if allowed.
|
|
133
|
+
* @template T
|
|
131
134
|
* @param {string} requestKey
|
|
132
|
-
* @param {
|
|
135
|
+
* @param {T} requestObject
|
|
133
136
|
* @param {SuitestErrorOptions} errorOptions - function name which will be invoked by user.
|
|
134
|
-
* @
|
|
137
|
+
* @throws {SuitestError} if request is not allowed.
|
|
138
|
+
* @returns {Promise<T & {headers: Record<string, string>}>}
|
|
135
139
|
*/
|
|
136
140
|
authorizeHttp(requestKey, requestObject, errorOptions = {}) {
|
|
137
141
|
if (
|
|
@@ -146,9 +150,11 @@ class AuthContext extends Context {
|
|
|
146
150
|
|
|
147
151
|
/**
|
|
148
152
|
* Check if ws request is allowed based on content type and current context.
|
|
149
|
-
* @
|
|
153
|
+
* @template T
|
|
154
|
+
* @param {T} contentObject
|
|
150
155
|
* @param {string} commandName - function name which will be invoked by user.
|
|
151
|
-
* @
|
|
156
|
+
* @throws {SuitestError} if request is not allowed.
|
|
157
|
+
* @returns {Promise<T>}
|
|
152
158
|
*/
|
|
153
159
|
authorizeWs(contentObject, commandName) {
|
|
154
160
|
if (contentObject && allowedRequests.ws[super.context].includes(contentObject.type)) { // check if ws content type is allowed
|
|
@@ -160,9 +166,11 @@ class AuthContext extends Context {
|
|
|
160
166
|
|
|
161
167
|
/**
|
|
162
168
|
* Check if ws connection is allowed based on current context.
|
|
163
|
-
* @
|
|
169
|
+
* @template T
|
|
170
|
+
* @param {T} connectObject
|
|
164
171
|
* @param {string} commandName - function name which will be invoked by user.
|
|
165
|
-
* @
|
|
172
|
+
* @throws {SuitestError} if request is not allowed.
|
|
173
|
+
* @returns {Promise<T & {headers: Record<string, string>}>}
|
|
166
174
|
*/
|
|
167
175
|
authorizeWsConnection(connectObject, commandName) {
|
|
168
176
|
if (super.context !== sessionConstants.GUEST) {
|
|
@@ -49,6 +49,18 @@ const regionSchema = () => ({
|
|
|
49
49
|
'additionalItems': false,
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
const regionWithNullableValuesSchema = () => ({
|
|
53
|
+
'type': 'array',
|
|
54
|
+
'items': [
|
|
55
|
+
{type: ['number', 'null'], minimum: 0, maximum: 100},
|
|
56
|
+
{type: ['number', 'null'], minimum: 0, maximum: 100},
|
|
57
|
+
{type: ['number', 'null'], exclusiveMinimum: 0, maximum: 100},
|
|
58
|
+
{type: ['number', 'null'], exclusiveMinimum: 0, maximum: 100},
|
|
59
|
+
],
|
|
60
|
+
'minItems': 4,
|
|
61
|
+
'additionalItems': false,
|
|
62
|
+
});
|
|
63
|
+
|
|
52
64
|
const CONFIG_OVERRIDE_PROPERTIES = {
|
|
53
65
|
'url': {'type': 'string'},
|
|
54
66
|
'suitestify': {'type': 'boolean'},
|
|
@@ -594,7 +606,7 @@ schemas[validationKeys.OCR_OPTIONS] = {
|
|
|
594
606
|
|
|
595
607
|
schemas[validationKeys.REGION] = {
|
|
596
608
|
'schemaId': validationKeys.REGION,
|
|
597
|
-
...
|
|
609
|
+
...regionWithNullableValuesSchema(),
|
|
598
610
|
};
|
|
599
611
|
|
|
600
612
|
schemas[validationKeys.IMAGE_DATA] = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suitest-js-api",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.21.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"repository": "git@github.com:SuitestAutomation/suitest-js-api.git",
|
|
6
6
|
"author": "Suitest <hello@suite.st>",
|
|
@@ -90,11 +90,11 @@
|
|
|
90
90
|
"nock": "^12.0.3",
|
|
91
91
|
"nyc": "15.1.0",
|
|
92
92
|
"sinon": "^9.0.2",
|
|
93
|
-
"typescript": "
|
|
93
|
+
"typescript": "5.8.3"
|
|
94
94
|
},
|
|
95
95
|
"dependencies": {
|
|
96
96
|
"@suitest/smst-to-text": "^4.13.0",
|
|
97
|
-
"@suitest/translate": "^4.
|
|
97
|
+
"@suitest/translate": "^4.24.0",
|
|
98
98
|
"@types/node": "^14.0.10",
|
|
99
99
|
"ajv": "^6.12.2",
|
|
100
100
|
"ansi-regex": "^5.0.0",
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
Negatable,
|
|
8
8
|
Assertable,
|
|
9
9
|
BaseEmptyChain,
|
|
10
|
+
OnScreenModifier,
|
|
10
11
|
} from './modifiers';
|
|
11
12
|
import {
|
|
12
13
|
AccuracyModifierNames,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
VisibleMethodsNames,
|
|
18
19
|
Chainable,
|
|
19
20
|
ChainWithoutMethods,
|
|
21
|
+
OnScreenModifierNames,
|
|
20
22
|
} from './utils';
|
|
21
23
|
|
|
22
24
|
interface ImageBase extends
|
|
@@ -28,6 +30,8 @@ interface ImageBase extends
|
|
|
28
30
|
VisibleModifier<ChainWithoutMethods<ImageBase, VisibleMethodsNames>>,
|
|
29
31
|
// inRegion(...)
|
|
30
32
|
InRegionModifier<ChainWithoutMethods<ImageBase, InRegionMethodsNames>>,
|
|
33
|
+
// onScreen()
|
|
34
|
+
OnScreenModifier<ChainWithoutMethods<ImageBase, OnScreenModifierNames>>,
|
|
31
35
|
// accuracy(...)
|
|
32
36
|
AccuracyModifier<ChainWithoutMethods<ImageBase, AccuracyModifierNames>>,
|
|
33
37
|
// toAssert(...)
|
|
@@ -273,7 +273,7 @@ export interface GetAttributesModifier<T> {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
export interface InRegionModifier<T> {
|
|
276
|
-
inRegion(region: [number, number, number, number]): T;
|
|
276
|
+
inRegion(region: [number | null, number | null, number | null, number | null]): T;
|
|
277
277
|
}
|
|
278
278
|
|
|
279
279
|
export interface Language<T> {
|
|
@@ -283,3 +283,7 @@ export interface Language<T> {
|
|
|
283
283
|
export interface AccuracyModifier<T> {
|
|
284
284
|
accuracy(accuracy: ValueOf<Accuracy>): T;
|
|
285
285
|
}
|
|
286
|
+
|
|
287
|
+
export interface OnScreenModifier<T> {
|
|
288
|
+
onScreen(): T;
|
|
289
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {AccuracyModifier, Assertable, InRegionModifier, Negatable, Timeout, VisibleModifier} from '../modifiers';
|
|
1
|
+
import {AccuracyModifier, Assertable, InRegionModifier, Negatable, Timeout, VisibleModifier, OnScreenModifier} from '../modifiers';
|
|
2
2
|
|
|
3
3
|
export type ValueOf<T> = T[keyof T];
|
|
4
4
|
|
|
@@ -54,3 +54,4 @@ export type VisibleMethodsNames = keyof VisibleModifier<any>;
|
|
|
54
54
|
export type InRegionMethodsNames = keyof InRegionModifier<any>;
|
|
55
55
|
export type AssertableMethodsNames = keyof Assertable<any>;
|
|
56
56
|
export type AccuracyModifierNames = keyof AccuracyModifier<any>;
|
|
57
|
+
export type OnScreenModifierNames = keyof OnScreenModifier<any>;
|