askui 0.12.2 → 0.13.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/README.md +13 -19
- package/bin/askui +1 -1
- package/dist/cjs/core/model/test-case-dto/custom-element-json.d.ts +75 -0
- package/dist/cjs/core/model/test-case-dto/custom-element-json.js +2 -0
- package/dist/cjs/core/model/test-case-dto/custom-element.d.ts +21 -0
- package/dist/cjs/core/model/test-case-dto/custom-element.js +54 -0
- package/dist/cjs/core/model/test-case-dto/index.d.ts +3 -0
- package/dist/cjs/core/model/test-case-dto/index.js +5 -0
- package/dist/cjs/core/model/test-case-dto/test-step.d.ts +6 -0
- package/dist/cjs/core/model/test-case-dto/test-step.js +2 -0
- package/dist/cjs/core/model/test-case-result-dto/index.d.ts +2 -0
- package/dist/cjs/core/model/test-case-result-dto/index.js +7 -0
- package/dist/cjs/core/model/test-case-result-dto/test-step-result-dto.d.ts +9 -0
- package/dist/cjs/core/model/test-case-result-dto/test-step-result-dto.js +16 -0
- package/dist/cjs/core/model/test-case-result-dto/test-step-state.d.ts +4 -0
- package/dist/cjs/core/model/test-case-result-dto/test-step-state.js +8 -0
- package/dist/cjs/core/reporting/default-reporter.d.ts +10 -0
- package/dist/cjs/core/reporting/default-reporter.js +12 -0
- package/dist/cjs/execution/annotation-level.d.ts +5 -0
- package/dist/cjs/execution/annotation-level.js +9 -0
- package/dist/cjs/execution/ui-control-client-error.d.ts +2 -0
- package/dist/cjs/execution/ui-control-client-error.js +6 -0
- package/dist/cjs/lib/index.d.ts +1 -0
- package/dist/cjs/lib/index.js +3 -1
- package/dist/cjs/lib/interactive_cli/add-script-package-json.d.ts +1 -0
- package/dist/cjs/lib/interactive_cli/add-script-package-json.js +38 -0
- package/dist/cjs/lib/interactive_cli/cli-options-interface.d.ts +8 -0
- package/dist/cjs/lib/interactive_cli/cli-options-interface.js +2 -0
- package/dist/cjs/lib/interactive_cli/cli.d.ts +2 -0
- package/dist/cjs/lib/interactive_cli/cli.js +115 -0
- package/dist/cjs/lib/interactive_cli/create-example-project.d.ts +26 -0
- package/dist/cjs/lib/interactive_cli/create-example-project.js +293 -0
- package/dist/cjs/lib/interactive_cli/index.d.ts +1 -0
- package/dist/cjs/lib/interactive_cli/index.js +5 -0
- package/dist/cjs/lib/interactive_cli/replace-string-in-file.d.ts +1 -0
- package/dist/cjs/lib/interactive_cli/replace-string-in-file.js +31 -0
- package/dist/esm/core/model/test-case-dto/custom-element-json.d.ts +75 -0
- package/dist/esm/core/model/test-case-dto/custom-element-json.js +1 -0
- package/dist/esm/core/model/test-case-dto/custom-element.d.ts +21 -0
- package/dist/esm/core/model/test-case-dto/custom-element.js +50 -0
- package/dist/esm/core/model/test-case-dto/index.d.ts +3 -0
- package/dist/esm/core/model/test-case-dto/index.js +1 -0
- package/dist/esm/core/model/test-case-dto/test-step.d.ts +6 -0
- package/dist/esm/core/model/test-case-dto/test-step.js +1 -0
- package/dist/esm/core/model/test-case-result-dto/index.d.ts +2 -0
- package/dist/esm/core/model/test-case-result-dto/index.js +2 -0
- package/dist/esm/core/model/test-case-result-dto/test-step-result-dto.d.ts +9 -0
- package/dist/esm/core/model/test-case-result-dto/test-step-result-dto.js +12 -0
- package/dist/esm/core/model/test-case-result-dto/test-step-state.d.ts +4 -0
- package/dist/esm/core/model/test-case-result-dto/test-step-state.js +5 -0
- package/dist/esm/core/reporting/default-reporter.d.ts +10 -0
- package/dist/esm/core/reporting/default-reporter.js +9 -0
- package/dist/esm/execution/annotation-level.d.ts +5 -0
- package/dist/esm/execution/annotation-level.js +6 -0
- package/dist/esm/execution/ui-control-client-error.d.ts +2 -0
- package/dist/esm/execution/ui-control-client-error.js +2 -0
- package/dist/esm/lib/index.d.ts +1 -0
- package/dist/esm/lib/index.js +1 -0
- package/dist/esm/lib/interactive_cli/add-script-package-json.d.ts +1 -0
- package/dist/esm/lib/interactive_cli/add-script-package-json.js +31 -0
- package/dist/esm/lib/interactive_cli/cli-options-interface.d.ts +8 -0
- package/dist/esm/lib/interactive_cli/cli-options-interface.js +1 -0
- package/dist/esm/lib/interactive_cli/cli.d.ts +2 -0
- package/dist/esm/lib/interactive_cli/cli.js +108 -0
- package/dist/esm/lib/interactive_cli/create-example-project.d.ts +26 -0
- package/dist/esm/lib/interactive_cli/create-example-project.js +286 -0
- package/dist/esm/lib/interactive_cli/index.d.ts +1 -0
- package/dist/esm/lib/interactive_cli/index.js +1 -0
- package/dist/esm/lib/interactive_cli/replace-string-in-file.d.ts +1 -0
- package/dist/esm/lib/interactive_cli/replace-string-in-file.js +24 -0
- package/dist/example_projects_templates/configs/jasmine.config.json +12 -0
- package/dist/example_projects_templates/configs/jest.config.ts +13 -0
- package/dist/example_projects_templates/configs/tsconfig.json +7 -0
- package/dist/example_projects_templates/templates/askui-helper-windows.nj +35 -0
- package/dist/example_projects_templates/templates/askui-helper.nj +49 -0
- package/dist/example_projects_templates/typescript/.eslintignore +1 -0
- package/dist/example_projects_templates/typescript/.eslintignore-template +1 -0
- package/dist/example_projects_templates/typescript/.eslintrc.json +20 -0
- package/dist/example_projects_templates/typescript/.eslintrc.json-template +20 -0
- package/dist/example_projects_templates/typescript/askui_example/helpers/askui-helper.ts +39 -0
- package/dist/example_projects_templates/typescript/askui_example/my-first-askui-test-suite.test.ts +21 -0
- package/dist/example_projects_templates/typescript/tsconfig.json +7 -0
- package/package.json +8 -1
package/README.md
CHANGED
|
@@ -1,50 +1,44 @@
|
|
|
1
|
-
#
|
|
1
|
+
# AskUI - Humanizing UI Automation
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**AskUI** allows you to automate the interaction with an application, multiple applications or even the entire operating system.
|
|
4
4
|
You can use this to write end-to-end tests or automate any kind of application.
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
## Start
|
|
8
8
|
|
|
9
|
-
To use **
|
|
9
|
+
To use **AskUI** follow these steps:
|
|
10
10
|
|
|
11
|
-
### 0.
|
|
11
|
+
### 0. Initialize AskUI with All Needed Dependencies
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
npm init
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### 1. Install askui with Needed Dependencies
|
|
13
|
+
Answer the questions to set up **AskUI** when you run this command.
|
|
18
14
|
|
|
19
15
|
```
|
|
20
|
-
|
|
16
|
+
npx askui@latest init
|
|
21
17
|
```
|
|
22
18
|
|
|
23
|
-
###
|
|
19
|
+
### 1. Execute Your First Instruction
|
|
24
20
|
|
|
25
|
-
|
|
26
|
-
npx askui init
|
|
27
|
-
```
|
|
21
|
+
[Request an **Access Token** first.](https://docs.askui.com/docs/general/Getting%20Started/getting-started#access-token)
|
|
28
22
|
|
|
29
|
-
|
|
23
|
+
Then follow [our guide](https://docs.askui.com/docs/general/Getting%20Started/write-your-first-instruction#configuration) to run your first instruction:
|
|
30
24
|
|
|
31
25
|
```
|
|
32
|
-
|
|
26
|
+
npm run askui
|
|
33
27
|
```
|
|
34
28
|
|
|
35
29
|
## Documentation
|
|
36
30
|
|
|
37
|
-
Visit our [documentation](https://docs.askui.com) for examples and a full list of supported
|
|
31
|
+
Visit our [documentation](https://docs.askui.com) for examples and a [full list of supported instructions](https://docs.askui.com/docs/api/API/table-of-contents).
|
|
38
32
|
|
|
39
33
|
### Notes
|
|
40
34
|
|
|
41
35
|
Important note for Linux users: Currently, Wayland is not supported.
|
|
42
36
|
You can read more in our [troubleshooting chapter](https://docs.askui.com/docs/general/Troubleshooting/linux#wayland).
|
|
43
|
-
If you want to use the
|
|
37
|
+
If you want to use the AskUI library `libfuse2`` is needed ([libfuse2 installation](https://docs.askui.com/docs/general/Troubleshooting/linux#libfuse2)).
|
|
44
38
|
|
|
45
39
|
## Example
|
|
46
40
|
|
|
47
|
-
The following example shows the use of **
|
|
41
|
+
The following example shows the use of **AskUI** for testing a desktop application.
|
|
48
42
|
|
|
49
43
|
```typescript
|
|
50
44
|
it('should be able to add to liked songs', async () => {
|
package/bin/askui
CHANGED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines a 'custom element'. This is a UI element which is defined by
|
|
3
|
+
* providing an image and other parameters such as degree of rotation.
|
|
4
|
+
* It allows filtering for a UI element that is not recognized
|
|
5
|
+
* by our machine learning models by default.
|
|
6
|
+
* It can also be used for pixel assertions of elements using classical
|
|
7
|
+
* [template matching](https://en.wikipedia.org/wiki/Template_matching).
|
|
8
|
+
*
|
|
9
|
+
* **Important:** The `CustomElementJson` needs to capture as accurately as possible
|
|
10
|
+
* what the custom element looks like during test execution as otherwise
|
|
11
|
+
* our machine learning models cannot find it, even with the additional data
|
|
12
|
+
* provided. This is especially true for the resolution used while cropping
|
|
13
|
+
* the `CustomElementJson.customImage` which should match the resolution during
|
|
14
|
+
* test execution.
|
|
15
|
+
*
|
|
16
|
+
* Rotated custom elements can be filtered for using
|
|
17
|
+
* `CustomElementJson.rotationDegreePerStep`.
|
|
18
|
+
*/
|
|
19
|
+
export interface CustomElementJson {
|
|
20
|
+
/**
|
|
21
|
+
* An cropped image in form of a base64 string or file path,
|
|
22
|
+
* e.g., "./custom.png".
|
|
23
|
+
*/
|
|
24
|
+
customImage: string;
|
|
25
|
+
/**
|
|
26
|
+
* A unique name which can be used for filtering for the custom element,
|
|
27
|
+
* e.g.,
|
|
28
|
+
* ```typescript
|
|
29
|
+
* ...customElement({
|
|
30
|
+
* name: 'unique-name',
|
|
31
|
+
* // ... (rest of the custom element)
|
|
32
|
+
* }).withText('unique-name')
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* If not set, the text inside the custom element is
|
|
36
|
+
* detected via
|
|
37
|
+
* [OCR](https://en.wikipedia.org/wiki/Optical_character_recognition).
|
|
38
|
+
* It can also be used for filtering for the custom element.
|
|
39
|
+
*/
|
|
40
|
+
name?: string | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* A threshold for how similar UI elements shown during test execution
|
|
43
|
+
* need to be to the custom element as defined by the other fields in
|
|
44
|
+
* `CustomElementJson` to be recognized as such. Takes values between
|
|
45
|
+
* `0.0` (= all elements are recognized as the custom element which is
|
|
46
|
+
* probably not what you want) and `1.0` (= elements need to look exactly
|
|
47
|
+
* like defined by `CustomElementJson` which is unlikely to be achieved
|
|
48
|
+
* as even minor differences count). Defaults to `0.9`.
|
|
49
|
+
*/
|
|
50
|
+
threshold?: number | undefined;
|
|
51
|
+
/**
|
|
52
|
+
* A step size in rotation degree. Rotates the custom image by
|
|
53
|
+
* `rotationDegreePerStep` until 360° is exceeded. Range is between
|
|
54
|
+
* 0° - 360°. Defaults to 0°.
|
|
55
|
+
*
|
|
56
|
+
* **Important**: This increases the prediction time quite a bit. So only use
|
|
57
|
+
* it when absolutely necessary.
|
|
58
|
+
*/
|
|
59
|
+
rotationDegreePerStep?: number | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* A color compare style. Allows matching a custom element by color, e.g.,
|
|
62
|
+
* instead of filtering for all icons (blue and green ones),
|
|
63
|
+
* only the green ones captured by `customImage` are filtered for using 'RGB'.
|
|
64
|
+
* Defaults to 'grayscale'.
|
|
65
|
+
*
|
|
66
|
+
* **Important**: This increases the prediction time quite a bit. So only use
|
|
67
|
+
* it when absolutely necessary.
|
|
68
|
+
*/
|
|
69
|
+
imageCompareFormat?: 'RGB' | 'grayscale' | undefined;
|
|
70
|
+
/** A polygon to match only a certain area of the custom element. */
|
|
71
|
+
mask?: ({
|
|
72
|
+
x: number;
|
|
73
|
+
y: number;
|
|
74
|
+
})[] | undefined;
|
|
75
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CustomElementJson } from './custom-element-json';
|
|
2
|
+
export declare class CustomElement implements CustomElementJson {
|
|
3
|
+
customImage: string;
|
|
4
|
+
name?: string | undefined;
|
|
5
|
+
threshold?: number | undefined;
|
|
6
|
+
rotationDegreePerStep?: number | undefined;
|
|
7
|
+
imageCompareFormat?: "RGB" | "grayscale" | undefined;
|
|
8
|
+
mask?: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
}[] | undefined;
|
|
12
|
+
private static schema;
|
|
13
|
+
constructor(customImage: string, name?: string | undefined, threshold?: number | undefined, rotationDegreePerStep?: number | undefined, imageCompareFormat?: "RGB" | "grayscale" | undefined, mask?: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
}[] | undefined);
|
|
17
|
+
static fromJsonListWithImagePathOrImage(ceJson?: CustomElementJson[]): Promise<CustomElement[]>;
|
|
18
|
+
static fromJsonWithImagePathOrImage(ceJson: CustomElementJson): Promise<CustomElement>;
|
|
19
|
+
static fromJson(ceJson: CustomElementJson): CustomElement;
|
|
20
|
+
validate(): void;
|
|
21
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.CustomElement = void 0;
|
|
13
|
+
const yup_1 = require("yup");
|
|
14
|
+
const base_64_image_1 = require("../../../utils/base_64_image/base-64-image");
|
|
15
|
+
class CustomElement {
|
|
16
|
+
constructor(customImage, name, threshold, rotationDegreePerStep, imageCompareFormat, mask) {
|
|
17
|
+
this.customImage = customImage;
|
|
18
|
+
this.name = name;
|
|
19
|
+
this.threshold = threshold;
|
|
20
|
+
this.rotationDegreePerStep = rotationDegreePerStep;
|
|
21
|
+
this.imageCompareFormat = imageCompareFormat;
|
|
22
|
+
this.mask = mask;
|
|
23
|
+
}
|
|
24
|
+
static fromJsonListWithImagePathOrImage(ceJson = []) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
return Promise.all(ceJson.map((customElement) => CustomElement.fromJsonWithImagePathOrImage(customElement)));
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
static fromJsonWithImagePathOrImage(ceJson) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const customImage = (yield base_64_image_1.Base64Image.fromPathOrString(ceJson.customImage)).toString();
|
|
32
|
+
const customElement = CustomElement.fromJson(Object.assign(Object.assign({}, ceJson), { customImage }));
|
|
33
|
+
customElement.validate();
|
|
34
|
+
return customElement;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
static fromJson(ceJson) {
|
|
38
|
+
return new CustomElement(ceJson.customImage, ceJson.name, ceJson.threshold, ceJson.rotationDegreePerStep, ceJson.imageCompareFormat, ceJson.mask);
|
|
39
|
+
}
|
|
40
|
+
validate() {
|
|
41
|
+
try {
|
|
42
|
+
CustomElement.schema.validateSync(this, { abortEarly: false, strict: true });
|
|
43
|
+
}
|
|
44
|
+
catch (e) { // ValidationError
|
|
45
|
+
throw new yup_1.ValidationError(e.errors.join(', '));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.CustomElement = CustomElement;
|
|
50
|
+
CustomElement.schema = (0, yup_1.object)({
|
|
51
|
+
threshold: (0, yup_1.number)().optional().min(0).max(1),
|
|
52
|
+
rotationDegreePerStep: (0, yup_1.number)().optional().min(0).lessThan(360),
|
|
53
|
+
mask: (0, yup_1.array)().optional().min(3, 'mask must contain at least 3 points'),
|
|
54
|
+
});
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomElement = void 0;
|
|
4
|
+
var custom_element_1 = require("./custom-element");
|
|
5
|
+
Object.defineProperty(exports, "CustomElement", { enumerable: true, get: function () { return custom_element_1.CustomElement; } });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestStepState = exports.TestStepResultDto = void 0;
|
|
4
|
+
var test_step_result_dto_1 = require("./test-step-result-dto");
|
|
5
|
+
Object.defineProperty(exports, "TestStepResultDto", { enumerable: true, get: function () { return test_step_result_dto_1.TestStepResultDto; } });
|
|
6
|
+
var test_step_state_1 = require("./test-step-state");
|
|
7
|
+
Object.defineProperty(exports, "TestStepState", { enumerable: true, get: function () { return test_step_state_1.TestStepState; } });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TestStepState } from './test-step-state';
|
|
2
|
+
export declare class TestStepResultDto {
|
|
3
|
+
state: TestStepState;
|
|
4
|
+
comment: string;
|
|
5
|
+
createDate: Date;
|
|
6
|
+
updateDate: Date;
|
|
7
|
+
constructor(state: TestStepState, comment?: string, createDate?: Date, updateDate?: Date);
|
|
8
|
+
static fromJson(testStepResult: TestStepResultDto): TestStepResultDto;
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestStepResultDto = void 0;
|
|
4
|
+
const test_step_state_1 = require("./test-step-state");
|
|
5
|
+
class TestStepResultDto {
|
|
6
|
+
constructor(state, comment = '', createDate = new Date(), updateDate = new Date()) {
|
|
7
|
+
this.state = state;
|
|
8
|
+
this.comment = comment;
|
|
9
|
+
this.createDate = createDate;
|
|
10
|
+
this.updateDate = updateDate;
|
|
11
|
+
}
|
|
12
|
+
static fromJson(testStepResult) {
|
|
13
|
+
return new TestStepResultDto(test_step_state_1.TestStepState[testStepResult.state], testStepResult.comment, new Date(testStepResult.createDate), new Date(testStepResult.updateDate));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.TestStepResultDto = TestStepResultDto;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TestStepState = void 0;
|
|
4
|
+
var TestStepState;
|
|
5
|
+
(function (TestStepState) {
|
|
6
|
+
TestStepState["PASSED"] = "PASSED";
|
|
7
|
+
TestStepState["FAILED"] = "FAILED";
|
|
8
|
+
})(TestStepState = exports.TestStepState || (exports.TestStepState = {}));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Step } from './step';
|
|
2
|
+
export declare const DEFAULT_REPORTER: {
|
|
3
|
+
config: {
|
|
4
|
+
readonly withScreenshots: "onFailure";
|
|
5
|
+
readonly withDetectedElements: "onFailure";
|
|
6
|
+
};
|
|
7
|
+
onStepBegin: (_step: Step) => Promise<void>;
|
|
8
|
+
onStepRetry: (_step: Step) => Promise<void>;
|
|
9
|
+
onStepEnd: (_step: Step) => Promise<void>;
|
|
10
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_REPORTER = void 0;
|
|
4
|
+
exports.DEFAULT_REPORTER = {
|
|
5
|
+
config: {
|
|
6
|
+
withScreenshots: 'onFailure',
|
|
7
|
+
withDetectedElements: 'onFailure',
|
|
8
|
+
},
|
|
9
|
+
onStepBegin: (_step) => Promise.resolve(),
|
|
10
|
+
onStepRetry: (_step) => Promise.resolve(),
|
|
11
|
+
onStepEnd: (_step) => Promise.resolve(),
|
|
12
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnnotationLevel = void 0;
|
|
4
|
+
var AnnotationLevel;
|
|
5
|
+
(function (AnnotationLevel) {
|
|
6
|
+
AnnotationLevel["DISABLED"] = "disabled";
|
|
7
|
+
AnnotationLevel["ON_FAILURE"] = "onFailure";
|
|
8
|
+
AnnotationLevel["ALL"] = "all";
|
|
9
|
+
})(AnnotationLevel = exports.AnnotationLevel || (exports.AnnotationLevel = {}));
|
package/dist/cjs/lib/index.d.ts
CHANGED
package/dist/cjs/lib/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.logger = exports.UiController = exports.TimeoutError = exports.UnkownError = void 0;
|
|
3
|
+
exports.logger = exports.UiController = exports.TimeoutError = exports.UnkownError = exports.init = void 0;
|
|
4
|
+
var interactive_cli_1 = require("./interactive_cli");
|
|
5
|
+
Object.defineProperty(exports, "init", { enumerable: true, get: function () { return interactive_cli_1.init; } });
|
|
4
6
|
var unkown_error_1 = require("./unkown-error");
|
|
5
7
|
Object.defineProperty(exports, "UnkownError", { enumerable: true, get: function () { return unkown_error_1.UnkownError; } });
|
|
6
8
|
var timeout_error_1 = require("./timeout-error");
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addScript(filePath: string, name: string, command: string): Promise<void>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.addScript = void 0;
|
|
16
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
17
|
+
const logger_1 = require("../logger");
|
|
18
|
+
function addScript(filePath, name, command) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
try {
|
|
21
|
+
const data = yield fs_extra_1.default.readFile(filePath, 'utf8');
|
|
22
|
+
const jsonData = JSON.parse(data);
|
|
23
|
+
if (jsonData.scripts === undefined) {
|
|
24
|
+
jsonData.scripts = { [name]: `${command}` };
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
jsonData.scripts[name] = command;
|
|
28
|
+
}
|
|
29
|
+
const jsonString = JSON.stringify(jsonData, null, 2);
|
|
30
|
+
yield fs_extra_1.default.writeFile(filePath, jsonString, 'utf8');
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logger_1.logger.error(`Could write script '${command}' in file '${filePath}'`);
|
|
34
|
+
logger_1.logger.error(error.message);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
exports.addScript = addScript;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.init = void 0;
|
|
16
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
17
|
+
const commander_1 = require("commander");
|
|
18
|
+
const create_example_project_1 = require("./create-example-project");
|
|
19
|
+
const nonEmpty = (subject) => (input) => (input.trim().length > 0) || `${subject} is required.`;
|
|
20
|
+
const questions = [
|
|
21
|
+
{
|
|
22
|
+
type: 'list',
|
|
23
|
+
name: 'testFramework',
|
|
24
|
+
message: 'Which framework do you prefer',
|
|
25
|
+
choices: ['jest', 'jasmine'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: 'input',
|
|
29
|
+
name: 'workspaceId',
|
|
30
|
+
message: 'Your workspace id',
|
|
31
|
+
validate: nonEmpty('workspace id'),
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
type: 'password',
|
|
35
|
+
name: 'accessToken',
|
|
36
|
+
message: 'Your access token',
|
|
37
|
+
mask: '*',
|
|
38
|
+
validate: nonEmpty('access token'),
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
type: 'confirm',
|
|
42
|
+
name: 'usingProxy',
|
|
43
|
+
message: 'Are you using a proxy?',
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
type: 'confirm',
|
|
48
|
+
name: 'typescriptConfig',
|
|
49
|
+
message: 'Do you want to add the tsconfig.json file? This action will overwrite the file if it exists. Default True ',
|
|
50
|
+
default: true,
|
|
51
|
+
},
|
|
52
|
+
];
|
|
53
|
+
const options = [
|
|
54
|
+
{
|
|
55
|
+
option: '-f, --test-framework <value>',
|
|
56
|
+
choices: ['jasmine', 'jest'],
|
|
57
|
+
description: 'the test framework to use',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
option: '-w, --workspace-id <value>',
|
|
61
|
+
choices: [],
|
|
62
|
+
description: 'a workspace id',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
option: '-a, --access-token <value>',
|
|
66
|
+
choices: [],
|
|
67
|
+
description: 'an access token for the workspace with the id',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
option: '-p, --using-proxy <value>',
|
|
71
|
+
choices: ['true', 'false'],
|
|
72
|
+
description: 'use a proxy',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
option: '-t, --typescript-config <value>',
|
|
76
|
+
choices: ['true', 'false'],
|
|
77
|
+
description: 'overwrite tsconfig.json flag',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
const createProgram = () => {
|
|
81
|
+
const program = new commander_1.Command('askui');
|
|
82
|
+
program.usage('<command> [options]');
|
|
83
|
+
return program;
|
|
84
|
+
};
|
|
85
|
+
function init(argv) {
|
|
86
|
+
const args = argv || process.argv;
|
|
87
|
+
const program = createProgram();
|
|
88
|
+
const programInit = program.command('init');
|
|
89
|
+
programInit.description('Creates a askui example project');
|
|
90
|
+
// Loop through the options object and register each option with the program
|
|
91
|
+
options.forEach((opt) => {
|
|
92
|
+
const tempOption = new commander_1.Option(opt.option, opt.description);
|
|
93
|
+
if (opt.choices.length > 0) {
|
|
94
|
+
tempOption.choices(opt.choices);
|
|
95
|
+
}
|
|
96
|
+
programInit.addOption(tempOption);
|
|
97
|
+
});
|
|
98
|
+
programInit.usage('[-f test_framework] [-w workspace_id] [-a access_token] [-p boolean] [-t boolean]');
|
|
99
|
+
programInit
|
|
100
|
+
.action((_opts) => __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
const userAnswers = programInit.opts();
|
|
102
|
+
// Check which options are missing and prompt the user for them
|
|
103
|
+
const missingOptions = questions.filter((entry) => !(entry.name in userAnswers));
|
|
104
|
+
if (missingOptions.length > 0) {
|
|
105
|
+
inquirer_1.default.prompt(missingOptions).then((answers) => __awaiter(this, void 0, void 0, function* () {
|
|
106
|
+
yield new create_example_project_1.CreateExampleProject(Object.assign(Object.assign({}, userAnswers), answers)).createExampleProject();
|
|
107
|
+
}));
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
yield new create_example_project_1.CreateExampleProject(userAnswers).createExampleProject();
|
|
111
|
+
}
|
|
112
|
+
}));
|
|
113
|
+
return program.parse(args);
|
|
114
|
+
}
|
|
115
|
+
exports.init = init;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { CliOptions } from './cli-options-interface';
|
|
2
|
+
export declare class CreateExampleProject {
|
|
3
|
+
readonly cliOptions: CliOptions;
|
|
4
|
+
private distexampleFolderPath;
|
|
5
|
+
private exampleFolderName;
|
|
6
|
+
private baseDirPath;
|
|
7
|
+
private proxyDocUrl;
|
|
8
|
+
private remoteDeviceControllerUrl;
|
|
9
|
+
private helperTemplateConfig;
|
|
10
|
+
constructor(cliOptions: CliOptions);
|
|
11
|
+
private copyTemplateProject;
|
|
12
|
+
private copyTestFrameworkConfig;
|
|
13
|
+
private addTestFrameWorkTimeout;
|
|
14
|
+
private addReporterConfig;
|
|
15
|
+
private addAskuiRunCommand;
|
|
16
|
+
private addESLintRunCommand;
|
|
17
|
+
private createAskUIHelperFromTemplate;
|
|
18
|
+
private setupTestFrameWork;
|
|
19
|
+
private installTestFrameworkPackages;
|
|
20
|
+
private addUserCredentails;
|
|
21
|
+
private copyESLintConfigFiles;
|
|
22
|
+
private copyTsConfigFile;
|
|
23
|
+
private installProxy;
|
|
24
|
+
private normalizeCliOptions;
|
|
25
|
+
createExampleProject(): Promise<void>;
|
|
26
|
+
}
|