@thinkwise/testwise 0.0.2-alpha.2
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/.ci/azure-pipelines.yaml +80 -0
- package/.eslintcache +1 -0
- package/.gitattributes +3 -0
- package/.gitconfig +2 -0
- package/.vscode/settings.json +18 -0
- package/Testwise.ts +22 -0
- package/components/BaseComponent.ts +95 -0
- package/components/BaseComponentObjects.ts +10 -0
- package/components/IComponentObjects.ts +5 -0
- package/components/Splitter.ts +11 -0
- package/components/TSFComponent.ts +8 -0
- package/components/actionbar/Actionbar.ts +57 -0
- package/components/actionbar/ActionbarObjects.ts +67 -0
- package/components/export/ExportComponent.ts +70 -0
- package/components/export/ExportComponentObjects.ts +23 -0
- package/components/filter/FilterForm.ts +11 -0
- package/components/filter/FindForm.ts +11 -0
- package/components/form/Form.ts +31 -0
- package/components/grid/Grid.ts +221 -0
- package/components/grid/GridObjects.ts +45 -0
- package/components/index.ts +6 -0
- package/components/pop-up/PopUpComponent.ts +14 -0
- package/components/pop-up/PopUpComponentModels.ts +13 -0
- package/components/tab/Tab.ts +29 -0
- package/components/task/TaskBar.ts +11 -0
- package/components/task/TaskTiles.ts +11 -0
- package/config.json +10 -0
- package/dist/Testwise.d.ts +2 -0
- package/dist/Testwise.js +14 -0
- package/dist/Testwise.js.map +1 -0
- package/dist/components/BaseComponent.d.ts +29 -0
- package/dist/components/BaseComponent.js +67 -0
- package/dist/components/BaseComponent.js.map +1 -0
- package/dist/components/BaseComponentObjects.d.ts +6 -0
- package/dist/components/BaseComponentObjects.js +6 -0
- package/dist/components/BaseComponentObjects.js.map +1 -0
- package/dist/components/IComponentObjects.d.ts +4 -0
- package/dist/components/IComponentObjects.js +2 -0
- package/dist/components/IComponentObjects.js.map +1 -0
- package/dist/components/Splitter.d.ts +5 -0
- package/dist/components/Splitter.js +10 -0
- package/dist/components/Splitter.js.map +1 -0
- package/dist/components/TSFComponent.d.ts +6 -0
- package/dist/components/TSFComponent.js +2 -0
- package/dist/components/TSFComponent.js.map +1 -0
- package/dist/components/actionbar/Actionbar.d.ts +27 -0
- package/dist/components/actionbar/Actionbar.js +35 -0
- package/dist/components/actionbar/Actionbar.js.map +1 -0
- package/dist/components/actionbar/ActionbarObjects.d.ts +24 -0
- package/dist/components/actionbar/ActionbarObjects.js +30 -0
- package/dist/components/actionbar/ActionbarObjects.js.map +1 -0
- package/dist/components/export/ExportComponent.d.ts +12 -0
- package/dist/components/export/ExportComponent.js +55 -0
- package/dist/components/export/ExportComponent.js.map +1 -0
- package/dist/components/export/ExportComponentObjects.d.ts +11 -0
- package/dist/components/export/ExportComponentObjects.js +12 -0
- package/dist/components/export/ExportComponentObjects.js.map +1 -0
- package/dist/components/form/Form.d.ts +7 -0
- package/dist/components/form/Form.js +31 -0
- package/dist/components/form/Form.js.map +1 -0
- package/dist/components/grid/Grid.d.ts +93 -0
- package/dist/components/grid/Grid.js +183 -0
- package/dist/components/grid/Grid.js.map +1 -0
- package/dist/components/grid/GridObjects.d.ts +20 -0
- package/dist/components/grid/GridObjects.js +25 -0
- package/dist/components/grid/GridObjects.js.map +1 -0
- package/dist/components/index.d.ts +6 -0
- package/dist/components/index.js +7 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/pop-up/PopUpComponent.d.ts +7 -0
- package/dist/components/pop-up/PopUpComponent.js +9 -0
- package/dist/components/pop-up/PopUpComponent.js.map +1 -0
- package/dist/components/pop-up/PopUpComponentModels.d.ts +7 -0
- package/dist/components/pop-up/PopUpComponentModels.js +8 -0
- package/dist/components/pop-up/PopUpComponentModels.js.map +1 -0
- package/dist/config.json +10 -0
- package/dist/enums/ActionbarRegions.d.ts +5 -0
- package/dist/enums/ActionbarRegions.js +7 -0
- package/dist/enums/ActionbarRegions.js.map +1 -0
- package/dist/enums/ButtonEnums.d.ts +24 -0
- package/dist/enums/ButtonEnums.js +29 -0
- package/dist/enums/ButtonEnums.js.map +1 -0
- package/dist/enums/ExportFormat.d.ts +5 -0
- package/dist/enums/ExportFormat.js +7 -0
- package/dist/enums/ExportFormat.js.map +1 -0
- package/dist/enums/LogLevel.d.ts +8 -0
- package/dist/enums/LogLevel.js +11 -0
- package/dist/enums/LogLevel.js.map +1 -0
- package/dist/example-code/TestifyService.d.ts +22 -0
- package/dist/example-code/TestifyService.js +191 -0
- package/dist/example-code/TestifyService.js.map +1 -0
- package/dist/helpers/InflightRequestTracker.d.ts +10 -0
- package/dist/helpers/InflightRequestTracker.js +26 -0
- package/dist/helpers/InflightRequestTracker.js.map +1 -0
- package/dist/helpers/LoginHelper.d.ts +38 -0
- package/dist/helpers/LoginHelper.js +112 -0
- package/dist/helpers/LoginHelper.js.map +1 -0
- package/dist/helpers/UserSimulationHelper.d.ts +20 -0
- package/dist/helpers/UserSimulationHelper.js +62 -0
- package/dist/helpers/UserSimulationHelper.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/page-extensions/GoToDeepLink.d.ts +11 -0
- package/dist/page-extensions/GoToDeepLink.js +17 -0
- package/dist/page-extensions/GoToDeepLink.js.map +1 -0
- package/dist/page-extensions/LoginFeatures.d.ts +16 -0
- package/dist/page-extensions/LoginFeatures.js +30 -0
- package/dist/page-extensions/LoginFeatures.js.map +1 -0
- package/dist/page-extensions/UserSimulation.d.ts +15 -0
- package/dist/page-extensions/UserSimulation.js +30 -0
- package/dist/page-extensions/UserSimulation.js.map +1 -0
- package/dist/page-overrides/ClickOverride.d.ts +6 -0
- package/dist/page-overrides/ClickOverride.js +73 -0
- package/dist/page-overrides/ClickOverride.js.map +1 -0
- package/dist/services/ConfigBuilder.d.ts +12 -0
- package/dist/services/ConfigBuilder.js +30 -0
- package/dist/services/ConfigBuilder.js.map +1 -0
- package/dist/services/Logger.d.ts +8 -0
- package/dist/services/Logger.js +106 -0
- package/dist/services/Logger.js.map +1 -0
- package/dist/services/ReportingService.d.ts +8 -0
- package/dist/services/ReportingService.js +29 -0
- package/dist/services/ReportingService.js.map +1 -0
- package/dist/types/CoreTypes.d.ts +2 -0
- package/dist/types/CoreTypes.js +2 -0
- package/dist/types/CoreTypes.js.map +1 -0
- package/dist/types/universal.d.ts +25 -0
- package/dist/types/universal.js +2 -0
- package/dist/types/universal.js.map +1 -0
- package/enums/ActionbarRegions.ts +5 -0
- package/enums/ButtonEnums.ts +28 -0
- package/enums/ExportFormat.ts +5 -0
- package/enums/LogLevel.ts +9 -0
- package/example-code/TestifyService.ts +201 -0
- package/helpers/InflightRequestTracker.ts +33 -0
- package/helpers/LoginHelper.ts +140 -0
- package/helpers/UserSimulationHelper.ts +72 -0
- package/index.ts +28 -0
- package/package.json +40 -0
- package/page-extensions/GoToDeepLink.ts +29 -0
- package/page-extensions/LoginFeatures.ts +50 -0
- package/page-extensions/UserSimulation.ts +49 -0
- package/page-overrides/ClickOverride.ts +89 -0
- package/promptCredentials.js +113 -0
- package/scripts/Testwise.template.json +19 -0
- package/scripts/add-config.js +23 -0
- package/services/ConfigBuilder.ts +40 -0
- package/services/Logger.ts +125 -0
- package/services/ReportingService.ts +41 -0
- package/types/CoreTypes.ts +9 -0
- package/types/universal.ts +26 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export var ActionbarRegion;
|
|
2
|
+
(function (ActionbarRegion) {
|
|
3
|
+
ActionbarRegion["Near"] = "near";
|
|
4
|
+
ActionbarRegion["Far"] = "far";
|
|
5
|
+
ActionbarRegion["Overflow"] = "overflow";
|
|
6
|
+
})(ActionbarRegion || (ActionbarRegion = {}));
|
|
7
|
+
//# sourceMappingURL=ActionbarRegions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ActionbarRegions.js","sourceRoot":"","sources":["../../enums/ActionbarRegions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,eAIX;AAJD,WAAY,eAAe;IACzB,gCAAa,CAAA;IACb,8BAAW,CAAA;IACX,wCAAqB,CAAA;AACvB,CAAC,EAJW,eAAe,KAAf,eAAe,QAI1B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare enum ButtonType {
|
|
2
|
+
ADD = "actionbar__add",
|
|
3
|
+
SAVE = "actionbar__save",
|
|
4
|
+
CANCEL = "actionbar__cancel",
|
|
5
|
+
COPY = "actionbar__copy",
|
|
6
|
+
UPDATE = "actionbar__update",
|
|
7
|
+
DELETE = "actionbar__delete",
|
|
8
|
+
REFRESH = "actionbar__refresh",
|
|
9
|
+
QuickFilter = "actionbar__quick-filter",
|
|
10
|
+
Filter = "actionbar__filter",
|
|
11
|
+
ClearAllFilters = "actionbar__clear-filters",
|
|
12
|
+
Sort = "actionbar__sort",
|
|
13
|
+
RestoreSortOrder = "actionbar__restore-sort",
|
|
14
|
+
Import = "actionbar__import",
|
|
15
|
+
Export = "actionbar__export",
|
|
16
|
+
ExportImmediately = "actionbar__export-immediately",
|
|
17
|
+
MassUpdate = "actionbar__mass-update"
|
|
18
|
+
}
|
|
19
|
+
export declare enum ButtonState {
|
|
20
|
+
ENABLED = "enabled",
|
|
21
|
+
DISABLED = "disabled",
|
|
22
|
+
HIDDEN = "hidden",
|
|
23
|
+
NON_EXISTENT = "nonExistent"
|
|
24
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export var ButtonType;
|
|
2
|
+
(function (ButtonType) {
|
|
3
|
+
// --- CRUD buttons ---
|
|
4
|
+
ButtonType["ADD"] = "actionbar__add";
|
|
5
|
+
ButtonType["SAVE"] = "actionbar__save";
|
|
6
|
+
ButtonType["CANCEL"] = "actionbar__cancel";
|
|
7
|
+
ButtonType["COPY"] = "actionbar__copy";
|
|
8
|
+
ButtonType["UPDATE"] = "actionbar__update";
|
|
9
|
+
ButtonType["DELETE"] = "actionbar__delete";
|
|
10
|
+
ButtonType["REFRESH"] = "actionbar__refresh";
|
|
11
|
+
// --- Overflow menu buttons
|
|
12
|
+
ButtonType["QuickFilter"] = "actionbar__quick-filter";
|
|
13
|
+
ButtonType["Filter"] = "actionbar__filter";
|
|
14
|
+
ButtonType["ClearAllFilters"] = "actionbar__clear-filters";
|
|
15
|
+
ButtonType["Sort"] = "actionbar__sort";
|
|
16
|
+
ButtonType["RestoreSortOrder"] = "actionbar__restore-sort";
|
|
17
|
+
ButtonType["Import"] = "actionbar__import";
|
|
18
|
+
ButtonType["Export"] = "actionbar__export";
|
|
19
|
+
ButtonType["ExportImmediately"] = "actionbar__export-immediately";
|
|
20
|
+
ButtonType["MassUpdate"] = "actionbar__mass-update";
|
|
21
|
+
})(ButtonType || (ButtonType = {}));
|
|
22
|
+
export var ButtonState;
|
|
23
|
+
(function (ButtonState) {
|
|
24
|
+
ButtonState["ENABLED"] = "enabled";
|
|
25
|
+
ButtonState["DISABLED"] = "disabled";
|
|
26
|
+
ButtonState["HIDDEN"] = "hidden";
|
|
27
|
+
ButtonState["NON_EXISTENT"] = "nonExistent";
|
|
28
|
+
})(ButtonState || (ButtonState = {}));
|
|
29
|
+
//# sourceMappingURL=ButtonEnums.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ButtonEnums.js","sourceRoot":"","sources":["../../enums/ButtonEnums.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,UAoBX;AApBD,WAAY,UAAU;IACpB,uBAAuB;IACvB,oCAAsB,CAAA;IACtB,sCAAwB,CAAA;IACxB,0CAA4B,CAAA;IAC5B,sCAAwB,CAAA;IACxB,0CAA4B,CAAA;IAC5B,0CAA4B,CAAA;IAC5B,4CAA8B,CAAA;IAE9B,4BAA4B;IAC5B,qDAAuC,CAAA;IACvC,0CAA4B,CAAA;IAC5B,0DAA4C,CAAA;IAC5C,sCAAwB,CAAA;IACxB,0DAA4C,CAAA;IAC5C,0CAA4B,CAAA;IAC5B,0CAA4B,CAAA;IAC5B,iEAAmD,CAAA;IACnD,mDAAqC,CAAA;AACvC,CAAC,EApBW,UAAU,KAAV,UAAU,QAoBrB;AAED,MAAM,CAAN,IAAY,WAKX;AALD,WAAY,WAAW;IACrB,kCAAmB,CAAA;IACnB,oCAAqB,CAAA;IACrB,gCAAiB,CAAA;IACjB,2CAA4B,CAAA;AAC9B,CAAC,EALW,WAAW,KAAX,WAAW,QAKtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportFormat.js","sourceRoot":"","sources":["../../enums/ExportFormat.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,2BAAW,CAAA;IACX,6BAAa,CAAA;IACb,2BAAW,CAAA;AACb,CAAC,EAJW,YAAY,KAAZ,YAAY,QAIvB"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export var LogLevel;
|
|
2
|
+
(function (LogLevel) {
|
|
3
|
+
// Order by severity
|
|
4
|
+
LogLevel["FATAL"] = "FATAL";
|
|
5
|
+
LogLevel["ERROR"] = "ERROR";
|
|
6
|
+
LogLevel["WARN"] = "WARN";
|
|
7
|
+
LogLevel["INFO"] = "INFO";
|
|
8
|
+
LogLevel["STEP"] = "STEP";
|
|
9
|
+
LogLevel["DEBUG"] = "DEBUG";
|
|
10
|
+
})(LogLevel || (LogLevel = {}));
|
|
11
|
+
//# sourceMappingURL=LogLevel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LogLevel.js","sourceRoot":"","sources":["../../enums/LogLevel.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,QAQX;AARD,WAAY,QAAQ;IAClB,oBAAoB;IACpB,2BAAe,CAAA;IACf,2BAAe,CAAA;IACf,yBAAa,CAAA;IACb,yBAAa,CAAA;IACb,yBAAa,CAAA;IACb,2BAAe,CAAA;AACjB,CAAC,EARW,QAAQ,KAAR,QAAQ,QAQnB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class TestifyService {
|
|
2
|
+
private token;
|
|
3
|
+
private projectId;
|
|
4
|
+
private baseUrl;
|
|
5
|
+
private axiosInstance;
|
|
6
|
+
testRunId: string;
|
|
7
|
+
constructor();
|
|
8
|
+
createTestRun(): Promise<void>;
|
|
9
|
+
private getTestRunId;
|
|
10
|
+
private createTestRunRequest;
|
|
11
|
+
private getProjectName;
|
|
12
|
+
reportTestResult(testName: string, passed: boolean): Promise<void>;
|
|
13
|
+
private updateResult;
|
|
14
|
+
private getTestResultId;
|
|
15
|
+
private getTestCaseId;
|
|
16
|
+
private addTestCaseToTestRun;
|
|
17
|
+
private createTestCase;
|
|
18
|
+
private testCaseExists;
|
|
19
|
+
private getTestCases;
|
|
20
|
+
closeTestRun(): Promise<void>;
|
|
21
|
+
private headers;
|
|
22
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/* Ignore this file for reviewing, it is used for Testify integration and only serves as an example*/
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
import axios from 'axios';
|
|
4
|
+
export class TestifyService {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.testRunId = '';
|
|
7
|
+
this.token = `Bearer ${process.env.TESTIFY_TOKEN}`;
|
|
8
|
+
this.projectId = process.env.TESTIFY_PROJECT_ID || '';
|
|
9
|
+
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
|
10
|
+
this.baseUrl = process.env.TESTIFY_BASE_URL.replace(/\/$/, '');
|
|
11
|
+
this.axiosInstance = axios.create({
|
|
12
|
+
baseURL: this.baseUrl,
|
|
13
|
+
headers: {
|
|
14
|
+
Authorization: this.token,
|
|
15
|
+
accept: '*/*'
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
async createTestRun() {
|
|
20
|
+
try {
|
|
21
|
+
const projectName = await this.getProjectName();
|
|
22
|
+
const testRunName = `${projectName} ${new Date().toISOString()}`;
|
|
23
|
+
if (!this.testRunId) {
|
|
24
|
+
await this.createTestRunRequest(testRunName);
|
|
25
|
+
this.testRunId = await this.getTestRunId(testRunName);
|
|
26
|
+
}
|
|
27
|
+
await new Promise((res) => setTimeout(res, 1000));
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
console.error('createTestRun failed:', err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async getTestRunId(testRunName) {
|
|
34
|
+
try {
|
|
35
|
+
const url = `/api/v1/TestRun?projectId=${this.projectId}`;
|
|
36
|
+
const response = await this.axiosInstance.get(url, { headers: this.headers('text/plain') });
|
|
37
|
+
const testRunList = response.data;
|
|
38
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
39
|
+
const found = testRunList.find((tr) => tr.name?.toLowerCase() === testRunName.toLowerCase());
|
|
40
|
+
return found?.id?.toString() ?? '';
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error('getTestRunId failed:', err);
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async createTestRunRequest(testRunName) {
|
|
48
|
+
try {
|
|
49
|
+
const encodedName = encodeURIComponent(testRunName);
|
|
50
|
+
const url = `/api/v1/TestRun/Create?testRunName=${encodedName}&projectId=${this.projectId}`;
|
|
51
|
+
await this.axiosInstance.post(url, null, { headers: this.headers() });
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
console.error('createTestRunRequest failed:', err);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async getProjectName() {
|
|
58
|
+
try {
|
|
59
|
+
const url = `/api/v1/Project/${this.projectId}`;
|
|
60
|
+
const response = await this.axiosInstance.get(url, { headers: this.headers('text/plain') });
|
|
61
|
+
const project = response.data;
|
|
62
|
+
return project.name;
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error('getProjectName failed:', err);
|
|
66
|
+
return '';
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
async reportTestResult(testName, passed) {
|
|
70
|
+
try {
|
|
71
|
+
const testCases = await this.getTestCases();
|
|
72
|
+
if (!this.testCaseExists(testCases, testName)) {
|
|
73
|
+
await this.createTestCase(testName);
|
|
74
|
+
}
|
|
75
|
+
const testCaseId = await this.getTestCaseId(testName);
|
|
76
|
+
if (!testCaseId) {
|
|
77
|
+
console.error(`Could not find or create test case ID for "${testName}"`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await this.addTestCaseToTestRun(testCaseId);
|
|
81
|
+
const testResultId = await this.getTestResultId(testCaseId);
|
|
82
|
+
if (!testResultId) {
|
|
83
|
+
console.error(`Could not find test result ID for test case "${testName}"`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
await this.updateResult(testResultId, passed);
|
|
87
|
+
await new Promise((res) => setTimeout(res, 200));
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
console.error('reportTestResult failed:', err);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async updateResult(testResultId, passed) {
|
|
94
|
+
try {
|
|
95
|
+
const status = passed ? '1' : '2';
|
|
96
|
+
const url = `/api/v1/Result/${testResultId}/UpdateStatus?newStatus=${status}`;
|
|
97
|
+
await this.axiosInstance.put(url, null, { headers: this.headers() });
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
console.error('updateResult failed:', err);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async getTestResultId(testCaseId) {
|
|
104
|
+
try {
|
|
105
|
+
const url = `/api/v1/Result?testRunId=${this.testRunId}`;
|
|
106
|
+
const response = await this.axiosInstance.get(url, { headers: this.headers('text/plain') });
|
|
107
|
+
const results = response.data;
|
|
108
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
109
|
+
const found = results.find((r) => r.testCaseId?.toString() === testCaseId);
|
|
110
|
+
return found?.id?.toString() ?? '';
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
console.error('getTestResultId failed:', err);
|
|
114
|
+
return '';
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async getTestCaseId(testCaseName) {
|
|
118
|
+
try {
|
|
119
|
+
const testCases = await this.getTestCases();
|
|
120
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
121
|
+
const found = testCases.find((tc) => tc.name === testCaseName);
|
|
122
|
+
return found?.id?.toString() ?? '';
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
console.error('getTestCaseId failed:', err);
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async addTestCaseToTestRun(testCaseId) {
|
|
130
|
+
try {
|
|
131
|
+
const url = `/api/v1/Result/Create?caseId=${testCaseId}&testRunId=${this.testRunId}`;
|
|
132
|
+
await this.axiosInstance.post(url, null, { headers: this.headers() });
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
console.error('addTestCaseToTestRun failed:', err);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async createTestCase(testCaseName) {
|
|
139
|
+
try {
|
|
140
|
+
const encodedName = encodeURIComponent(testCaseName);
|
|
141
|
+
const url = `/api/v1/TestCase/Create?testCaseName=${encodedName}&projectId=${this.projectId}`;
|
|
142
|
+
await this.axiosInstance.post(url, null, { headers: this.headers() });
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
console.error('createTestCase failed:', err);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
149
|
+
testCaseExists(testCases, testName) {
|
|
150
|
+
try {
|
|
151
|
+
return testCases.some((tc) => tc.name?.toLowerCase() === testName.toLowerCase());
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.error('testCaseExists failed:', err);
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
159
|
+
async getTestCases() {
|
|
160
|
+
try {
|
|
161
|
+
const url = `/api/v1/TestCase?projectId=${this.projectId}`;
|
|
162
|
+
const response = await this.axiosInstance.get(url, { headers: this.headers('text/plain') });
|
|
163
|
+
return response.data;
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
console.error('getTestCases failed:', err);
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async closeTestRun() {
|
|
171
|
+
if (!this.testRunId) {
|
|
172
|
+
console.error('closeTestRun failed: testRunId is not set.');
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
try {
|
|
176
|
+
const url = `/api/v1/TestRun/${this.testRunId}/Close`;
|
|
177
|
+
await this.axiosInstance.put(url, null, { headers: this.headers() });
|
|
178
|
+
console.info(`Test run ${this.testRunId} closed successfully.`);
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
console.error('closeTestRun failed:', err);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
headers(accept = '*/*') {
|
|
185
|
+
return {
|
|
186
|
+
accept,
|
|
187
|
+
Authorization: this.token
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=TestifyService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TestifyService.js","sourceRoot":"","sources":["../../example-code/TestifyService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Page, Request } from '@playwright/test';
|
|
2
|
+
export declare class InflightRequestsTracker {
|
|
3
|
+
private _page;
|
|
4
|
+
private _requests;
|
|
5
|
+
constructor(page: Page);
|
|
6
|
+
_onStarted(request: Request): void;
|
|
7
|
+
_onFinished(request: Request): void;
|
|
8
|
+
inflightRequests(): Request[];
|
|
9
|
+
dispose(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class InflightRequestsTracker {
|
|
2
|
+
constructor(page) {
|
|
3
|
+
this._page = page;
|
|
4
|
+
this._requests = new Set();
|
|
5
|
+
this._onStarted = this._onStarted.bind(this);
|
|
6
|
+
this._onFinished = this._onFinished.bind(this);
|
|
7
|
+
this._page.on('request', this._onStarted);
|
|
8
|
+
this._page.on('requestfinished', this._onFinished);
|
|
9
|
+
this._page.on('requestfailed', this._onFinished);
|
|
10
|
+
}
|
|
11
|
+
_onStarted(request) {
|
|
12
|
+
this._requests.add(request);
|
|
13
|
+
}
|
|
14
|
+
_onFinished(request) {
|
|
15
|
+
this._requests.delete(request);
|
|
16
|
+
}
|
|
17
|
+
inflightRequests() {
|
|
18
|
+
return Array.from(this._requests);
|
|
19
|
+
}
|
|
20
|
+
dispose() {
|
|
21
|
+
this._page.removeListener('request', this._onStarted);
|
|
22
|
+
this._page.removeListener('requestfinished', this._onFinished);
|
|
23
|
+
this._page.removeListener('requestfailed', this._onFinished);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=InflightRequestTracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InflightRequestTracker.js","sourceRoot":"","sources":["../../helpers/InflightRequestTracker.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,uBAAuB;IAIlC,YAAY,IAAU;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,iBAAiB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QACnD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,WAAW,CAAC,OAAgB;QAC1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACpC,CAAC;IAED,OAAO;QACL,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtD,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,iBAAiB,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IAC/D,CAAC;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Page } from '@playwright/test';
|
|
2
|
+
import type { UniversalLoginOptions } from '../types/universal.js';
|
|
3
|
+
export declare class LoginHelper {
|
|
4
|
+
private _page;
|
|
5
|
+
private _serviceUrl;
|
|
6
|
+
private _metaEndpoint;
|
|
7
|
+
constructor(page: Page);
|
|
8
|
+
/**
|
|
9
|
+
* Log in and go to a specified application
|
|
10
|
+
* @param applicationName - Application name to launch
|
|
11
|
+
*/
|
|
12
|
+
logIn(applicationName?: string): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Log in with credentials
|
|
15
|
+
* @param username - The username to log in with
|
|
16
|
+
* @param password - The password to log in with
|
|
17
|
+
*/
|
|
18
|
+
logInWithCredentials(username: string, password: string): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Log in with options
|
|
21
|
+
* @param options - The login options
|
|
22
|
+
*/
|
|
23
|
+
logInWithOptions(options: UniversalLoginOptions): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Navigate to the home page and wait for the menu to load
|
|
26
|
+
*/
|
|
27
|
+
private navigateHomeAndWaitForMenuToLoad;
|
|
28
|
+
/**
|
|
29
|
+
* Log in and configure the application
|
|
30
|
+
* @param options - The login options
|
|
31
|
+
*/
|
|
32
|
+
private logInAndConfigureApplication;
|
|
33
|
+
/**
|
|
34
|
+
* Configure the application
|
|
35
|
+
* @param options - The configuration options
|
|
36
|
+
*/
|
|
37
|
+
private configureApplication;
|
|
38
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import { expect } from '@playwright/test';
|
|
5
|
+
import { testwiseConfig } from '../services/ConfigBuilder.js';
|
|
6
|
+
const _dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const configFixture = JSON.parse(fs.readFileSync(path.resolve(_dirname, '../config.json'), 'utf-8'));
|
|
8
|
+
export class LoginHelper {
|
|
9
|
+
constructor(page) {
|
|
10
|
+
this._page = page;
|
|
11
|
+
const serviceUrl = testwiseConfig().get('environmentSettings.serviceUrl');
|
|
12
|
+
const metaEndpoint = testwiseConfig().get('environmentSettings.metaEndpoint');
|
|
13
|
+
if (!serviceUrl || !metaEndpoint)
|
|
14
|
+
throw new Error('Either environmentSettings.serviceUrl or environmentSettings.metaEndpoint is not defined in the configuration.');
|
|
15
|
+
this._serviceUrl = serviceUrl;
|
|
16
|
+
this._metaEndpoint = metaEndpoint;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Log in and go to a specified application
|
|
20
|
+
* @param applicationName - Application name to launch
|
|
21
|
+
*/
|
|
22
|
+
async logIn(applicationName = configFixture.defaultApplication) {
|
|
23
|
+
await this.logInAndConfigureApplication({
|
|
24
|
+
config: {
|
|
25
|
+
defaultApplication: applicationName
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Log in with credentials
|
|
31
|
+
* @param username - The username to log in with
|
|
32
|
+
* @param password - The password to log in with
|
|
33
|
+
*/
|
|
34
|
+
async logInWithCredentials(username, password) {
|
|
35
|
+
const options = {
|
|
36
|
+
username: username,
|
|
37
|
+
password: password
|
|
38
|
+
};
|
|
39
|
+
await this.logInWithOptions(options);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Log in with options
|
|
43
|
+
* @param options - The login options
|
|
44
|
+
*/
|
|
45
|
+
async logInWithOptions(options) {
|
|
46
|
+
await this.logInAndConfigureApplication(options);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Navigate to the home page and wait for the menu to load
|
|
50
|
+
*/
|
|
51
|
+
async navigateHomeAndWaitForMenuToLoad() {
|
|
52
|
+
await this._page.goto('/');
|
|
53
|
+
await this._page.route('**/i_ui_menu?**', (route) => {
|
|
54
|
+
route.continue();
|
|
55
|
+
});
|
|
56
|
+
await expect.poll(async () => await this._page.url()).toContain('#application=');
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Log in and configure the application
|
|
60
|
+
* @param options - The login options
|
|
61
|
+
*/
|
|
62
|
+
async logInAndConfigureApplication(options = {}) {
|
|
63
|
+
const { serviceUrl, metaEndpoint, config } = options;
|
|
64
|
+
const username = options.username ?? process.env.SF_TEST_USERNAME;
|
|
65
|
+
const password = options.password ?? process.env.SF_TEST_PASSWORD;
|
|
66
|
+
if (!username || !password) {
|
|
67
|
+
throw new Error('Username and password are required for login.');
|
|
68
|
+
}
|
|
69
|
+
if (serviceUrl && metaEndpoint) {
|
|
70
|
+
this._serviceUrl = serviceUrl;
|
|
71
|
+
this._metaEndpoint = metaEndpoint;
|
|
72
|
+
}
|
|
73
|
+
const response = await this._page.request.post(`${this._serviceUrl}/account/api/login`, {
|
|
74
|
+
form: {
|
|
75
|
+
UserName: username,
|
|
76
|
+
Password: password
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
if (response.status() !== 204) {
|
|
80
|
+
console.error('Login failed', await response.status());
|
|
81
|
+
}
|
|
82
|
+
// Set the navigator.language property
|
|
83
|
+
await this._page.route('**/*', (route, request) => {
|
|
84
|
+
route.continue({
|
|
85
|
+
headers: {
|
|
86
|
+
...request.headers(),
|
|
87
|
+
'Accept-Language': 'en-US'
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
await this.configureApplication(config ?? {});
|
|
92
|
+
await this.navigateHomeAndWaitForMenuToLoad();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Configure the application
|
|
96
|
+
* @param options - The configuration options
|
|
97
|
+
*/
|
|
98
|
+
async configureApplication(options) {
|
|
99
|
+
await this._page.route('**/config.json', (route) => {
|
|
100
|
+
route.fulfill({
|
|
101
|
+
status: 200,
|
|
102
|
+
contentType: 'application/json',
|
|
103
|
+
body: JSON.stringify({
|
|
104
|
+
...configFixture,
|
|
105
|
+
serviceUrl: `${this._serviceUrl}/iam/${this._metaEndpoint}`,
|
|
106
|
+
...options
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=LoginHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginHelper.js","sourceRoot":"","sources":["../../helpers/LoginHelper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Page } from '@playwright/test';
|
|
2
|
+
export declare class UserSimulationHelper {
|
|
3
|
+
private _page;
|
|
4
|
+
private _serviceUrl;
|
|
5
|
+
constructor(page: Page);
|
|
6
|
+
/**
|
|
7
|
+
* Get the simulated user
|
|
8
|
+
* @returns The simulated user name
|
|
9
|
+
*/
|
|
10
|
+
getSimulatedUser(): Promise<string>;
|
|
11
|
+
/**
|
|
12
|
+
* Stop the user simulation
|
|
13
|
+
*/
|
|
14
|
+
stopSimulation(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Simulate a user
|
|
17
|
+
* @param userName - The name of the user to simulate
|
|
18
|
+
*/
|
|
19
|
+
simulateUser(userName: string): Promise<void>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { expect } from '@playwright/test';
|
|
2
|
+
import { testwiseConfig } from '../services/ConfigBuilder.js';
|
|
3
|
+
export class UserSimulationHelper {
|
|
4
|
+
constructor(page) {
|
|
5
|
+
this._page = page;
|
|
6
|
+
const serviceUrl = testwiseConfig().get('environmentSettings.serviceUrl');
|
|
7
|
+
if (!serviceUrl)
|
|
8
|
+
throw new Error('environmentSettings.serviceUrl is not defined in the configuration.');
|
|
9
|
+
this._serviceUrl = serviceUrl;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Get the simulated user
|
|
13
|
+
* @returns The simulated user name
|
|
14
|
+
*/
|
|
15
|
+
async getSimulatedUser() {
|
|
16
|
+
const response = await this._page.request.get(`${this._serviceUrl}/account/api/usersimulation`);
|
|
17
|
+
switch (response.status()) {
|
|
18
|
+
case 204:
|
|
19
|
+
console.error('User simulation not active', await response.status());
|
|
20
|
+
return '';
|
|
21
|
+
case 200:
|
|
22
|
+
return (await response.json()).simulated_user;
|
|
23
|
+
default:
|
|
24
|
+
throw new Error(`Get simulated user request failed with status: ${await response.status()}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Stop the user simulation
|
|
29
|
+
*/
|
|
30
|
+
async stopSimulation() {
|
|
31
|
+
const response = await this._page.request.delete(`${this._serviceUrl}/account/api/usersimulation`);
|
|
32
|
+
if (response.status() === 204) {
|
|
33
|
+
console.info('STOP User simulation request is successful', await response.status());
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
throw new Error(`STOP User simulation has unexpected status: ${await response.status()}`);
|
|
37
|
+
}
|
|
38
|
+
await expect.poll(async () => await this.getSimulatedUser()).toBe('');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Simulate a user
|
|
42
|
+
* @param userName - The name of the user to simulate
|
|
43
|
+
*/
|
|
44
|
+
async simulateUser(userName) {
|
|
45
|
+
const response = await this._page.request.patch(`${this._serviceUrl}/account/api/usersimulation`, {
|
|
46
|
+
headers: {
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
Accept: 'application/json'
|
|
49
|
+
},
|
|
50
|
+
data: JSON.stringify({
|
|
51
|
+
simulated_user: userName
|
|
52
|
+
})
|
|
53
|
+
});
|
|
54
|
+
if (response.status() === 200) {
|
|
55
|
+
console.info('User simulation request is successful', await response.status());
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new Error(`User simulation has unexpected status: ${await response.status()}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=UserSimulationHelper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserSimulationHelper.js","sourceRoot":"","sources":["../../helpers/UserSimulationHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,MAAM,OAAO,oBAAoB;IAI/B,YAAY,IAAU;QACpB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAElB,MAAM,UAAU,GAAG,cAAc,EAAE,CAAC,GAAG,CAAS,gCAAgC,CAAC,CAAC;QAElF,IAAI,CAAC,UAAU;YAAE,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;QAExG,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;IAChC,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,gBAAgB;QAC3B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,WAAW,6BAA6B,CAAC,CAAC;QAEhG,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,KAAK,GAAG;gBACN,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrE,OAAO,EAAE,CAAC;YACZ,KAAK,GAAG;gBACN,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,cAAc,CAAC;YAChD;gBACE,MAAM,IAAI,KAAK,CAAC,kDAAkD,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,cAAc;QACzB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,6BAA6B,CAAC,CAAC;QAEnG,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACtF,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,+CAA+C,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC5F,CAAC;QAED,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,YAAY,CAAC,QAAgB;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,WAAW,6BAA6B,EAAE;YAChG,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,MAAM,EAAE,kBAAkB;aAC3B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,cAAc,EAAE,QAAQ;aACzB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,uCAAuC,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACjF,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QACvF,CAAC;IACH,CAAC;CACF"}
|