@sap_oss/wdio-qmate-service 1.0.0 → 1.0.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/README.md +2 -1
- package/{test/core/package-lock.json → docs/bestPractices/spec.md} +0 -0
- package/docs/doc.md +176 -353
- package/docs/gettingStarted/setup.md +2 -2
- package/docs/index.md +1 -1
- package/docs/sections/bestPractices/authentication.md +151 -0
- package/docs/sections/bestPractices/dataHandling.md +61 -0
- package/docs/sections/bestPractices/selectors.md +44 -0
- package/docs/{contact.md → sections/contact.md} +0 -0
- package/docs/sections/features/advancedDataHandling.md +252 -0
- package/docs/sections/features/config.md +171 -0
- package/docs/sections/features/dataHandling.md +83 -0
- package/docs/{gettingStarted → sections/features}/selectors.md +0 -0
- package/docs/sections/features/spec.md +0 -0
- package/docs/sections/gettingStarted/config.md +18 -0
- package/docs/sections/gettingStarted/execution.md +7 -0
- package/docs/sections/gettingStarted/setup.md +9 -0
- package/docs/sections/gettingStarted/spec.md +31 -0
- package/docs/sections/gettingStarted/specs.md +19 -0
- package/docs/sections/support/bugReporting.md +19 -0
- package/docs/sections/support/knownIssuesAndLimitations.md +0 -0
- package/docs/sections/support/troubleshooting.md +16 -0
- package/docs/sources/images/fiori_form.PNG +0 -0
- package/docs/sources/images/sapCloud_form.PNG +0 -0
- package/lib/index.js +59 -82
- package/lib/index.js.map +1 -1
- package/lib/reuse/authenticator/authHandler.js +12 -23
- package/lib/reuse/authenticator/authHandler.js.map +1 -1
- package/lib/reuse/authenticator/basicUrlAuthenticator.js +21 -32
- package/lib/reuse/authenticator/basicUrlAuthenticator.js.map +1 -1
- package/lib/reuse/authenticator/customAuthenticator.js +42 -55
- package/lib/reuse/authenticator/customAuthenticator.js.map +1 -1
- package/lib/reuse/authenticator/formAuthenticator.js +37 -50
- package/lib/reuse/authenticator/formAuthenticator.js.map +1 -1
- package/lib/reuse/authenticator/plainAuthenticator.js +5 -16
- package/lib/reuse/authenticator/plainAuthenticator.js.map +1 -1
- package/lib/reuse/helper/jsDocGen.js +4 -12
- package/lib/reuse/helper/jsDocGen.js.map +1 -1
- package/lib/reuse/index.js +20 -5
- package/lib/reuse/index.js.map +1 -1
- package/lib/reuse/modules/common/navigation.js +10 -23
- package/lib/reuse/modules/common/navigation.js.map +1 -1
- package/lib/reuse/modules/common/userInteraction.js +40 -73
- package/lib/reuse/modules/common/userInteraction.js.map +1 -1
- package/lib/reuse/modules/nonUi5/assertion.js +31 -52
- package/lib/reuse/modules/nonUi5/assertion.js.map +1 -1
- package/lib/reuse/modules/nonUi5/element.js +266 -331
- package/lib/reuse/modules/nonUi5/element.js.map +1 -1
- package/lib/reuse/modules/nonUi5/navigation.js +10 -21
- package/lib/reuse/modules/nonUi5/navigation.js.map +1 -1
- package/lib/reuse/modules/nonUi5/userInteraction.js +176 -215
- package/lib/reuse/modules/nonUi5/userInteraction.js.map +1 -1
- package/lib/reuse/modules/service/odata.d.ts +106 -94
- package/lib/reuse/modules/service/odata.js +209 -204
- package/lib/reuse/modules/service/odata.js.map +1 -1
- package/lib/reuse/modules/service/rest.js +64 -81
- package/lib/reuse/modules/service/rest.js.map +1 -1
- package/lib/reuse/modules/ui5/assertion.js +217 -268
- package/lib/reuse/modules/ui5/assertion.js.map +1 -1
- package/lib/reuse/modules/ui5/confirmationDialog.js +17 -42
- package/lib/reuse/modules/ui5/confirmationDialog.js.map +1 -1
- package/lib/reuse/modules/ui5/control.js +12 -33
- package/lib/reuse/modules/ui5/control.js.map +1 -1
- package/lib/reuse/modules/ui5/date.js +70 -89
- package/lib/reuse/modules/ui5/date.js.map +1 -1
- package/lib/reuse/modules/ui5/element.js +121 -156
- package/lib/reuse/modules/ui5/element.js.map +1 -1
- package/lib/reuse/modules/ui5/errorDialog.js +4 -17
- package/lib/reuse/modules/ui5/errorDialog.js.map +1 -1
- package/lib/reuse/modules/ui5/footerBar.js +28 -63
- package/lib/reuse/modules/ui5/footerBar.js.map +1 -1
- package/lib/reuse/modules/ui5/mockserver.js +390 -427
- package/lib/reuse/modules/ui5/mockserver.js.map +1 -1
- package/lib/reuse/modules/ui5/navigation.js +105 -132
- package/lib/reuse/modules/ui5/navigation.js.map +1 -1
- package/lib/reuse/modules/ui5/navigationBar.js +58 -77
- package/lib/reuse/modules/ui5/navigationBar.js.map +1 -1
- package/lib/reuse/modules/ui5/qunit.js +16 -27
- package/lib/reuse/modules/ui5/qunit.js.map +1 -1
- package/lib/reuse/modules/ui5/session.js +200 -236
- package/lib/reuse/modules/ui5/session.js.map +1 -1
- package/lib/reuse/modules/ui5/table.js +79 -98
- package/lib/reuse/modules/ui5/table.js.map +1 -1
- package/lib/reuse/modules/ui5/userInteraction.js +264 -335
- package/lib/reuse/modules/ui5/userInteraction.js.map +1 -1
- package/lib/reuse/modules/util/browser.js +131 -178
- package/lib/reuse/modules/util/browser.js.map +1 -1
- package/lib/reuse/modules/util/data.js +3 -2
- package/lib/reuse/modules/util/data.js.map +1 -1
- package/lib/reuse/modules/util/file.js +71 -90
- package/lib/reuse/modules/util/file.js.map +1 -1
- package/lib/reuse/modules/util/function.js +68 -87
- package/lib/reuse/modules/util/function.js.map +1 -1
- package/lib/reuse/modules/util/system.js +22 -33
- package/lib/reuse/modules/util/system.js.map +1 -1
- package/lib/scripts/dataExchange/dataExchange.js +145 -160
- package/lib/scripts/dataExchange/dataExchange.js.map +1 -1
- package/lib/scripts/dataExchange/dataExchangeUtil.js +93 -114
- package/lib/scripts/dataExchange/dataExchangeUtil.js.map +1 -1
- package/lib/scripts/hooks/after.js +3 -14
- package/lib/scripts/hooks/after.js.map +1 -1
- package/lib/scripts/hooks/before.js +9 -20
- package/lib/scripts/hooks/before.js.map +1 -1
- package/lib/scripts/hooks/beforeSession.js +7 -18
- package/lib/scripts/hooks/beforeSession.js.map +1 -1
- package/lib/scripts/hooks/onComplete.js +2 -13
- package/lib/scripts/hooks/onComplete.js.map +1 -1
- package/lib/scripts/hooks/onPrepare.js +9 -20
- package/lib/scripts/hooks/onPrepare.js.map +1 -1
- package/lib/scripts/hooks/utils/addLocatorCommands.js +109 -172
- package/lib/scripts/hooks/utils/addLocatorCommands.js.map +1 -1
- package/lib/scripts/hooks/utils/browserLog.js +18 -31
- package/lib/scripts/hooks/utils/browserLog.js.map +1 -1
- package/lib/scripts/hooks/utils/dataExchangeCommands.js +13 -24
- package/lib/scripts/hooks/utils/dataExchangeCommands.js.map +1 -1
- package/lib/scripts/hooks/utils/decryption.d.ts +1 -1
- package/lib/scripts/hooks/utils/decryption.js +33 -14
- package/lib/scripts/hooks/utils/decryption.js.map +1 -1
- package/lib/scripts/hooks/utils/lib.js +249 -272
- package/lib/scripts/hooks/utils/lib.js.map +1 -1
- package/lib/scripts/hooks/utils/locatorCommands.js +154 -183
- package/lib/scripts/hooks/utils/locatorCommands.js.map +1 -1
- package/mkdocs.yml +16 -3
- package/package.json +14 -11
- package/test/authenticator/staticLogin/specs/custom.spec.js +30 -1
- package/test/reuse/nonUi5/element/getById.spec.js +17 -0
- package/test/reuse/service/odata/get.spec.js +61 -0
- package/test/reuse/service/odata/getEntitySet.spec.js +87 -0
- package/test/reuse/service/odata/test.odata.conf.js +15 -0
- package/test/reuse/ui5/confirmationDialog/clickButton.spec.js +87 -0
- package/test/reuse/ui5/confirmationDialog/test.confirmationDialog.conf.js +2 -1
- package/test/reuse/ui5/element/test.element.conf.js +2 -1
- package/test/reuse/ui5/element/waitForAll.spec.js +46 -0
- package/test/reuse/ui5/userInteraction/clearAndFillSmartFieldInputAndRetry.spec.js +28 -0
- package/test/reuse/ui5/userInteraction/test.userInteraction.conf.js +1 -0
- package/test/reuse/util/browser/switchToNewWindow.spec.js +2 -2
- package/test/reuse/util/console/console.spec.js +27 -0
- package/test/reuse/util/console/test.console.conf.js +12 -0
- package/test/reuse/util/data/data/test.secure.json +7 -3
- package/test/reuse/util/data/getSecureData.spec.js +9 -3
- package/test/reuse/util/file/pdfParser.spec.js +33 -8
- package/test/reuse/util/system/system.spec.js +16 -0
- package/test/reuse/util/system/test.system.conf.js +12 -0
- package/tsconfig.json +1 -1
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.File = void 0;
|
|
13
4
|
/**
|
|
@@ -29,35 +20,33 @@ class File {
|
|
|
29
20
|
* @example await util.file.upload(["path/to/text1.txt", "path/to/text2.txt"]); // uses the default uploader control
|
|
30
21
|
* @example await util.file.upload(["path/to/text1.txt", "path/to/text2.txt"], "input[id='myUpload']"); // upload to file uploader with matching selector
|
|
31
22
|
*/
|
|
32
|
-
upload(files, selector = "input[type = 'file']") {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
yield elem.waitForDisplayed();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
else if (typeof selector === "object") {
|
|
48
|
-
const elemId = yield ui5.element.getId(selector);
|
|
49
|
-
elem = yield nonUi5.element.getByXPath(`.//input[contains(@id,'${elemId}')][@type='file']`);
|
|
50
|
-
}
|
|
51
|
-
for (const file of files) {
|
|
52
|
-
const filePath = this.path.resolve(file);
|
|
53
|
-
const remoteFilePath = yield browser.uploadFile(filePath);
|
|
54
|
-
yield elem.setValue(remoteFilePath);
|
|
23
|
+
async upload(files, selector = "input[type = 'file']") {
|
|
24
|
+
let elem;
|
|
25
|
+
try {
|
|
26
|
+
if (typeof selector === "string") {
|
|
27
|
+
elem = await $(selector);
|
|
28
|
+
const isDisplayed = await elem.isDisplayed();
|
|
29
|
+
if (!isDisplayed) {
|
|
30
|
+
await browser.execute(function (selector) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
document.querySelector(selector).style.visibility = "visible";
|
|
33
|
+
}, selector);
|
|
34
|
+
await elem.waitForDisplayed();
|
|
55
35
|
}
|
|
56
36
|
}
|
|
57
|
-
|
|
58
|
-
|
|
37
|
+
else if (typeof selector === "object") {
|
|
38
|
+
const elemId = await ui5.element.getId(selector);
|
|
39
|
+
elem = await nonUi5.element.getByXPath(`.//input[contains(@id,'${elemId}')][@type='file']`);
|
|
59
40
|
}
|
|
60
|
-
|
|
41
|
+
for (const file of files) {
|
|
42
|
+
const filePath = this.path.resolve(file);
|
|
43
|
+
const remoteFilePath = await browser.uploadFile(filePath);
|
|
44
|
+
await elem.setValue(remoteFilePath);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
throw new Error(`Function 'upload' failed': ${error}`);
|
|
49
|
+
}
|
|
61
50
|
}
|
|
62
51
|
;
|
|
63
52
|
// =================================== PDF ===================================
|
|
@@ -71,18 +60,16 @@ class File {
|
|
|
71
60
|
* @see <a href="TODO">Parse PDF</a>
|
|
72
61
|
* @example await util.file.parsePdf(pdfStream, customRenderingMethod);
|
|
73
62
|
*/
|
|
74
|
-
parsePdf(pdfStream, renderingMethod = this._renderPage) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return data.text;
|
|
85
|
-
});
|
|
63
|
+
async parsePdf(pdfStream, renderingMethod = this._renderPage) {
|
|
64
|
+
if (typeof renderingMethod !== "function") {
|
|
65
|
+
throw new Error("Function 'parsePdf' failed: Please provide a custom rendering method as second parameter.");
|
|
66
|
+
}
|
|
67
|
+
const options = {
|
|
68
|
+
pagerender: renderingMethod,
|
|
69
|
+
};
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
const data = await this.pdf(pdfStream, options);
|
|
72
|
+
return data.text;
|
|
86
73
|
}
|
|
87
74
|
/**
|
|
88
75
|
* @function expectPdfContainsText
|
|
@@ -94,14 +81,12 @@ class File {
|
|
|
94
81
|
* @see <a href="TODO">Parse pdf</a>
|
|
95
82
|
* @example await util.file.expectPdfContainsText(pdfStream, "abc");
|
|
96
83
|
*/
|
|
97
|
-
expectPdfContainsText(pdfStream, text, renderingMethod = this._renderPage) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
return expect(parsedText).toContain(text);
|
|
104
|
-
});
|
|
84
|
+
async expectPdfContainsText(pdfStream, text, renderingMethod = this._renderPage) {
|
|
85
|
+
if (!text) {
|
|
86
|
+
throw new Error("Function 'expectPdfContainsText' failed: Please provide a text as second parameter.");
|
|
87
|
+
}
|
|
88
|
+
const parsedText = await this.parsePdf(pdfStream, renderingMethod);
|
|
89
|
+
return expect(parsedText).toContain(text);
|
|
105
90
|
}
|
|
106
91
|
/**
|
|
107
92
|
* @function expectPdfNotContainsText
|
|
@@ -113,45 +98,41 @@ class File {
|
|
|
113
98
|
* @see <a href="TODO">Parse pdf</a>
|
|
114
99
|
* @example await util.file.expectPdfNotContainsText(pdfStream, "abc");
|
|
115
100
|
*/
|
|
116
|
-
expectPdfNotContainsText(pdfStream, text, renderingMethod = this._renderPage) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return expect(parsedText).not.toContain(text);
|
|
123
|
-
});
|
|
101
|
+
async expectPdfNotContainsText(pdfStream, text, renderingMethod = this._renderPage) {
|
|
102
|
+
if (!text) {
|
|
103
|
+
throw new Error("Function 'expectPdfNotContainsText' failed: Please provide a text as second parameter.");
|
|
104
|
+
}
|
|
105
|
+
const parsedText = await this.parsePdf(pdfStream, renderingMethod);
|
|
106
|
+
return expect(parsedText).not.toContain(text);
|
|
124
107
|
}
|
|
125
108
|
// =================================== HELPER ===================================
|
|
126
|
-
_renderPage(pageData) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
text += " " + item.str;
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
text += "\n" + item.str;
|
|
141
|
-
}
|
|
142
|
-
lastY = item.transform[5];
|
|
109
|
+
async _renderPage(pageData) {
|
|
110
|
+
// should be in scope of render page due to library specific implementation
|
|
111
|
+
const _parseText = function (textContent) {
|
|
112
|
+
if (textContent === undefined || textContent === null || !textContent.items || !Array.isArray(textContent.items)) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
let lastY, text = "";
|
|
116
|
+
for (const item of textContent.items) {
|
|
117
|
+
if (Array.isArray(item.transform) && item.transform.length === 6) {
|
|
118
|
+
if (lastY == item.transform[5] || !lastY) {
|
|
119
|
+
text += " " + item.str;
|
|
143
120
|
}
|
|
121
|
+
else {
|
|
122
|
+
text += "\n" + item.str;
|
|
123
|
+
}
|
|
124
|
+
lastY = item.transform[5];
|
|
144
125
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
126
|
+
}
|
|
127
|
+
return text;
|
|
128
|
+
};
|
|
129
|
+
const render_options = {
|
|
130
|
+
// replaces all occurrences of whitespace with standard spaces (0x20). The default value is `false`.
|
|
131
|
+
normalizeWhitespace: false,
|
|
132
|
+
// do not attempt to combine same line TextItem's. The default value is `false`.
|
|
133
|
+
disableCombineTextItems: false,
|
|
134
|
+
};
|
|
135
|
+
return pageData.getTextContent(render_options).then(_parseText);
|
|
155
136
|
}
|
|
156
137
|
}
|
|
157
138
|
exports.File = File;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/file.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.FunctionModule = void 0;
|
|
13
4
|
/**
|
|
@@ -34,12 +25,10 @@ class FunctionModule {
|
|
|
34
25
|
* }, [], 2, 30000);
|
|
35
26
|
*/
|
|
36
27
|
// NOTE: Don't set default values since they will be calculated with "_getRetryProperties".
|
|
37
|
-
retry(fct, args, retries, interval, scope = null) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
yield this._retry(fct, args, res.retries, res.interval, scope);
|
|
42
|
-
});
|
|
28
|
+
async retry(fct, args, retries, interval, scope = null) {
|
|
29
|
+
this.overallRetries = retries;
|
|
30
|
+
const res = await this._getRetryProperties(retries, interval);
|
|
31
|
+
await this._retry(fct, args, res.retries, res.interval, scope);
|
|
43
32
|
}
|
|
44
33
|
;
|
|
45
34
|
/**
|
|
@@ -53,21 +42,19 @@ class FunctionModule {
|
|
|
53
42
|
* await ui5.userInteraction.fill(selector, "ABC");
|
|
54
43
|
* }, []);
|
|
55
44
|
*/
|
|
56
|
-
executeOptional(fct, args = []) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
45
|
+
async executeOptional(fct, args = []) {
|
|
46
|
+
try {
|
|
47
|
+
await fct.apply(this, args);
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
if (fct.name) {
|
|
51
|
+
util.console.info(`Optional function '${fct.name}' not executed, continue ...`);
|
|
60
52
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
util.console.info(`Optional function '${fct.name}' not executed, continue ...`);
|
|
64
|
-
}
|
|
65
|
-
else {
|
|
66
|
-
util.console.info(`Optional anonymous function not executed, continue ...`);
|
|
67
|
-
}
|
|
68
|
-
return Promise.resolve();
|
|
53
|
+
else {
|
|
54
|
+
util.console.info(`Optional anonymous function not executed, continue ...`);
|
|
69
55
|
}
|
|
70
|
-
|
|
56
|
+
return Promise.resolve();
|
|
57
|
+
}
|
|
71
58
|
}
|
|
72
59
|
;
|
|
73
60
|
// =================================== HELPER ===================================
|
|
@@ -80,79 +67,73 @@ class FunctionModule {
|
|
|
80
67
|
* @param {string} action - An action performed upon the element ("click", "fill")
|
|
81
68
|
* @example await util.function.mapWdioErrorToQmateErrorMessage(error, "click");
|
|
82
69
|
*/
|
|
83
|
-
mapWdioErrorToQmateErrorMessage(wdioError, action) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
qmateMessage = `Function fill failed. Element can not be filled - make sure that the selector matches input \n\n` + wdioError.stack;
|
|
90
|
-
}
|
|
70
|
+
async mapWdioErrorToQmateErrorMessage(wdioError, action) {
|
|
71
|
+
const errorMessage = wdioError.message;
|
|
72
|
+
let qmateMessage = "";
|
|
73
|
+
if (action === "fill") {
|
|
74
|
+
if (errorMessage.match(new RegExp(/(invalid element state|element not interactable)/))) {
|
|
75
|
+
qmateMessage = `Function fill failed. Element can not be filled - make sure that the selector matches input \n\n` + wdioError.stack;
|
|
91
76
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
else if (foundAttributes.includes("class=")) {
|
|
103
|
-
// @ts-ignore
|
|
104
|
-
elementAttributes = foundAttributes.match(new RegExp(/(?=class)(.*)(?<=")/));
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (wdioError && wdioError.stack && elementAttributes) {
|
|
108
|
-
qmateMessage = `Element with attribute(s) ${elementAttributes[0]} is hidden by another element \n\n` + wdioError.stack;
|
|
77
|
+
}
|
|
78
|
+
else if (action === "click") {
|
|
79
|
+
if (errorMessage.match(new RegExp(/is not clickable at point/))) {
|
|
80
|
+
const reg = new RegExp(/(?<=Element <.* )(.*)(?=>...<)/).exec(errorMessage);
|
|
81
|
+
const foundAttributes = reg ? reg[0] : undefined;
|
|
82
|
+
let elementAttributes = foundAttributes;
|
|
83
|
+
if (reg && foundAttributes) {
|
|
84
|
+
if (foundAttributes.includes("id=")) {
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
elementAttributes = foundAttributes.match(new RegExp(/(?=id)(.*)(?<=")/));
|
|
109
87
|
}
|
|
110
|
-
else {
|
|
111
|
-
|
|
88
|
+
else if (foundAttributes.includes("class=")) {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
elementAttributes = foundAttributes.match(new RegExp(/(?=class)(.*)(?<=")/));
|
|
112
91
|
}
|
|
113
92
|
}
|
|
93
|
+
if (wdioError && wdioError.stack && elementAttributes) {
|
|
94
|
+
qmateMessage = `Element with attribute(s) ${elementAttributes[0]} is hidden by another element \n\n` + wdioError.stack;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
qmateMessage = "Error clicking element \n\n" + wdioError;
|
|
98
|
+
}
|
|
114
99
|
}
|
|
115
|
-
|
|
116
|
-
|
|
100
|
+
}
|
|
101
|
+
return qmateMessage;
|
|
117
102
|
}
|
|
118
103
|
;
|
|
119
104
|
// =================================== HELPER ===================================
|
|
120
|
-
_getRetryProperties(retries, interval) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
105
|
+
async _getRetryProperties(retries, interval) {
|
|
106
|
+
const res = {
|
|
107
|
+
retries: retries,
|
|
108
|
+
interval: interval
|
|
109
|
+
};
|
|
110
|
+
if (res.retries === undefined) {
|
|
111
|
+
res.retries = browser.config.stepsRetries;
|
|
126
112
|
if (res.retries === undefined) {
|
|
127
|
-
res.retries =
|
|
128
|
-
if (res.retries === undefined) {
|
|
129
|
-
res.retries = 3;
|
|
130
|
-
}
|
|
113
|
+
res.retries = 3;
|
|
131
114
|
}
|
|
115
|
+
}
|
|
116
|
+
if (res.interval === undefined) {
|
|
117
|
+
res.interval = browser.config.stepRetriesIntervals;
|
|
132
118
|
if (res.interval === undefined) {
|
|
133
|
-
res.interval =
|
|
134
|
-
if (res.interval === undefined) {
|
|
135
|
-
res.interval = 5000;
|
|
136
|
-
}
|
|
119
|
+
res.interval = 5000;
|
|
137
120
|
}
|
|
138
|
-
|
|
139
|
-
|
|
121
|
+
}
|
|
122
|
+
return res;
|
|
140
123
|
}
|
|
141
|
-
_retry(fct, args, retries, interval, scope = null) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
throw new Error(`Retries done. Failed to execute the function: ${e}`);
|
|
150
|
-
}
|
|
151
|
-
yield browser.pause(interval);
|
|
152
|
-
util.console.log(`Retrying function again (${this.overallRetries - retries}/${this.overallRetries})`);
|
|
153
|
-
yield this._retry(fct, args, retries, interval, scope);
|
|
124
|
+
async _retry(fct, args, retries, interval, scope = null) {
|
|
125
|
+
try {
|
|
126
|
+
return await fct.apply(scope, args);
|
|
127
|
+
}
|
|
128
|
+
catch (e) {
|
|
129
|
+
retries = retries - 1;
|
|
130
|
+
if (retries < 0) {
|
|
131
|
+
throw new Error(`Retries done. Failed to execute the function: ${e}`);
|
|
154
132
|
}
|
|
155
|
-
|
|
133
|
+
await browser.pause(interval);
|
|
134
|
+
util.console.log(`Retrying function again (${this.overallRetries - retries}/${this.overallRetries})`);
|
|
135
|
+
await this._retry(fct, args, retries, interval, scope);
|
|
136
|
+
}
|
|
156
137
|
}
|
|
157
138
|
}
|
|
158
139
|
exports.FunctionModule = FunctionModule;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/function.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/function.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,4 @@
|
|
|
1
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
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
3
|
exports.System = void 0;
|
|
13
4
|
/**
|
|
@@ -25,30 +16,28 @@ class System {
|
|
|
25
16
|
* @returns {String} AIX | Android | MacOS | FreeBSD | Linux | OpenBSD | Windows | SunOS
|
|
26
17
|
* @example const os = await util.system.getOS();
|
|
27
18
|
*/
|
|
28
|
-
getOS() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
});
|
|
19
|
+
async getOS() {
|
|
20
|
+
const platform = this.operatingSystem.platform();
|
|
21
|
+
switch (platform) {
|
|
22
|
+
case "aix":
|
|
23
|
+
return "AIX";
|
|
24
|
+
case "android":
|
|
25
|
+
return "Android";
|
|
26
|
+
case "darwin":
|
|
27
|
+
return "MacOS";
|
|
28
|
+
case "freebsd":
|
|
29
|
+
return "FreeBSD";
|
|
30
|
+
case "linux":
|
|
31
|
+
return "Linux";
|
|
32
|
+
case "openbsd":
|
|
33
|
+
return "OpenBSD";
|
|
34
|
+
case "sunos":
|
|
35
|
+
return "SunOS";
|
|
36
|
+
case "win32":
|
|
37
|
+
return "Windows";
|
|
38
|
+
default:
|
|
39
|
+
return "unknown platform";
|
|
40
|
+
}
|
|
52
41
|
}
|
|
53
42
|
;
|
|
54
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/system.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC
|
|
1
|
+
{"version":3,"file":"system.js","sourceRoot":"","sources":["../../../../src/reuse/modules/util/system.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;AACb;;;GAGG;AACH,MAAa,MAAM;IAAnB;QACE,oBAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAiClC,CAAC;IA/BC;;;;;;OAMG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;QACjD,QAAQ,QAAQ,EAAE;YAChB,KAAK,KAAK;gBACR,OAAO,KAAK,CAAC;YACf,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAC;YACnB,KAAK,QAAQ;gBACX,OAAO,OAAO,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO,OAAO,CAAC;YACjB,KAAK,SAAS;gBACZ,OAAO,SAAS,CAAC;YACnB,KAAK,OAAO;gBACV,OAAO,OAAO,CAAC;YACjB,KAAK,OAAO;gBACV,OAAO,SAAS,CAAC;YACnB;gBACE,OAAO,kBAAkB,CAAC;SAC7B;IACH,CAAC;IAAA,CAAC;CAEH;AAlCD,wBAkCC;AAAA,CAAC;AACF,kBAAe,IAAI,MAAM,EAAE,CAAC"}
|