@playq/core 0.2.77
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 +41 -0
- package/bin/playq.js +175 -0
- package/cucumber.js +10 -0
- package/dist/exec/featureFileCache.d.ts +21 -0
- package/dist/exec/featureFileCache.js +124 -0
- package/dist/exec/featureFilePreProcess.d.ts +12 -0
- package/dist/exec/featureFilePreProcess.js +208 -0
- package/dist/exec/preLoader.d.ts +1 -0
- package/dist/exec/preLoader.js +72 -0
- package/dist/exec/preProcessEntry.d.ts +1 -0
- package/dist/exec/preProcessEntry.js +83 -0
- package/dist/exec/preProcess_old_todelete.d.ts +1 -0
- package/dist/exec/preProcess_old_todelete.js +258 -0
- package/dist/exec/runner.d.ts +1 -0
- package/dist/exec/runner.js +221 -0
- package/dist/exec/runner_orchestrator.d.ts +1 -0
- package/dist/exec/runner_orchestrator.js +85 -0
- package/dist/exec/sgGenerator.d.ts +11 -0
- package/dist/exec/sgGenerator.js +310 -0
- package/dist/global.d.ts +15 -0
- package/dist/global.js +185 -0
- package/dist/helper/actions/api/apiRequestActions.d.ts +117 -0
- package/dist/helper/actions/api/apiRequestActions.js +374 -0
- package/dist/helper/actions/api/apiValidationActions.d.ts +119 -0
- package/dist/helper/actions/api/apiValidationActions.js +615 -0
- package/dist/helper/actions/apiActions.d.ts +18 -0
- package/dist/helper/actions/apiActions.js +34 -0
- package/dist/helper/actions/apiStepDefs.d.ts +1 -0
- package/dist/helper/actions/apiStepDefs.js +64 -0
- package/dist/helper/actions/comm/commonActions.d.ts +58 -0
- package/dist/helper/actions/comm/commonActions.js +198 -0
- package/dist/helper/actions/comm/utilityActions.d.ts +131 -0
- package/dist/helper/actions/comm/utilityActions.js +351 -0
- package/dist/helper/actions/commActions.d.ts +18 -0
- package/dist/helper/actions/commActions.js +34 -0
- package/dist/helper/actions/commStepDefs.d.ts +1 -0
- package/dist/helper/actions/commStepDefs.js +57 -0
- package/dist/helper/actions/stepGroupStepDefs.d.ts +1 -0
- package/dist/helper/actions/stepGroupStepDefs.js +15 -0
- package/dist/helper/actions/web/alertActions.d.ts +61 -0
- package/dist/helper/actions/web/alertActions.js +224 -0
- package/dist/helper/actions/web/cookieActions.d.ts +45 -0
- package/dist/helper/actions/web/cookieActions.js +186 -0
- package/dist/helper/actions/web/downloadActions.d.ts +40 -0
- package/dist/helper/actions/web/downloadActions.js +153 -0
- package/dist/helper/actions/web/elementReaderActions.d.ts +95 -0
- package/dist/helper/actions/web/elementReaderActions.js +326 -0
- package/dist/helper/actions/web/formActions.d.ts +122 -0
- package/dist/helper/actions/web/formActions.js +423 -0
- package/dist/helper/actions/web/iframeActions.d.ts +23 -0
- package/dist/helper/actions/web/iframeActions.js +108 -0
- package/dist/helper/actions/web/javascriptActions.d.ts +14 -0
- package/dist/helper/actions/web/javascriptActions.js +77 -0
- package/dist/helper/actions/web/keyboardActions.d.ts +35 -0
- package/dist/helper/actions/web/keyboardActions.js +118 -0
- package/dist/helper/actions/web/localStorageActions.d.ts +51 -0
- package/dist/helper/actions/web/localStorageActions.js +163 -0
- package/dist/helper/actions/web/mouseActions.d.ts +240 -0
- package/dist/helper/actions/web/mouseActions.js +609 -0
- package/dist/helper/actions/web/reportingActions.d.ts +34 -0
- package/dist/helper/actions/web/reportingActions.js +58 -0
- package/dist/helper/actions/web/screenshotActions.d.ts +34 -0
- package/dist/helper/actions/web/screenshotActions.js +151 -0
- package/dist/helper/actions/web/testDataActions.d.ts +21 -0
- package/dist/helper/actions/web/testDataActions.js +211 -0
- package/dist/helper/actions/web/validationActions.d.ts +547 -0
- package/dist/helper/actions/web/validationActions.js +1754 -0
- package/dist/helper/actions/web/waitActions.d.ts +191 -0
- package/dist/helper/actions/web/waitActions.js +589 -0
- package/dist/helper/actions/web/webNavigation.d.ts +104 -0
- package/dist/helper/actions/web/webNavigation.js +288 -0
- package/dist/helper/actions/webActions.d.ts +32 -0
- package/dist/helper/actions/webActions.js +48 -0
- package/dist/helper/actions/webStepDefs.d.ts +1 -0
- package/dist/helper/actions/webStepDefs.js +455 -0
- package/dist/helper/browsers/browserManager.d.ts +1 -0
- package/dist/helper/browsers/browserManager.js +56 -0
- package/dist/helper/bundle/defaultEntries.d.ts +6 -0
- package/dist/helper/bundle/defaultEntries.js +200 -0
- package/dist/helper/bundle/env.d.ts +1 -0
- package/dist/helper/bundle/env.js +157 -0
- package/dist/helper/bundle/vars.d.ts +9 -0
- package/dist/helper/bundle/vars.js +375 -0
- package/dist/helper/faker/customFaker.d.ts +55 -0
- package/dist/helper/faker/customFaker.js +45 -0
- package/dist/helper/faker/modules/data/postcodes_valid_sg.json +17 -0
- package/dist/helper/faker/modules/dateTime.d.ts +18 -0
- package/dist/helper/faker/modules/dateTime.js +106 -0
- package/dist/helper/faker/modules/mobile.d.ts +4 -0
- package/dist/helper/faker/modules/mobile.js +59 -0
- package/dist/helper/faker/modules/nric.d.ts +32 -0
- package/dist/helper/faker/modules/nric.js +84 -0
- package/dist/helper/faker/modules/passport.d.ts +3 -0
- package/dist/helper/faker/modules/passport.js +36 -0
- package/dist/helper/faker/modules/person.d.ts +14 -0
- package/dist/helper/faker/modules/person.js +73 -0
- package/dist/helper/faker/modules/postcode.d.ts +6 -0
- package/dist/helper/faker/modules/postcode.js +47 -0
- package/dist/helper/fixtures/locAggregate.d.ts +7 -0
- package/dist/helper/fixtures/locAggregate.js +94 -0
- package/dist/helper/fixtures/logFixture.d.ts +8 -0
- package/dist/helper/fixtures/logFixture.js +56 -0
- package/dist/helper/fixtures/webFixture.d.ts +19 -0
- package/dist/helper/fixtures/webFixture.js +186 -0
- package/dist/helper/fixtures/webLocFixture.d.ts +2 -0
- package/dist/helper/fixtures/webLocFixture.js +144 -0
- package/dist/helper/report/allureStepLogger.d.ts +0 -0
- package/dist/helper/report/allureStepLogger.js +25 -0
- package/dist/helper/report/customiseReport.d.ts +1 -0
- package/dist/helper/report/customiseReport.js +55 -0
- package/dist/helper/report/init.d.ts +1 -0
- package/dist/helper/report/init.js +14 -0
- package/dist/helper/report/report.d.ts +1 -0
- package/dist/helper/report/report.js +102 -0
- package/dist/helper/util/dataLoader.d.ts +10 -0
- package/dist/helper/util/dataLoader.js +73 -0
- package/dist/helper/util/logger.d.ts +4 -0
- package/dist/helper/util/logger.js +61 -0
- package/dist/helper/util/session/sessionUtil.d.ts +26 -0
- package/dist/helper/util/session/sessionUtil.js +729 -0
- package/dist/helper/util/stepHelpers.d.ts +2 -0
- package/dist/helper/util/stepHelpers.js +16 -0
- package/dist/helper/util/test-data/dataLoader.d.ts +7 -0
- package/dist/helper/util/test-data/dataLoader.js +145 -0
- package/dist/helper/util/test-data/dataTest.d.ts +10 -0
- package/dist/helper/util/test-data/dataTest.js +216 -0
- package/dist/helper/util/totp/totpHelper.d.ts +38 -0
- package/dist/helper/util/totp/totpHelper.js +117 -0
- package/dist/helper/util/utilities/cryptoUtil.d.ts +2 -0
- package/dist/helper/util/utilities/cryptoUtil.js +53 -0
- package/dist/helper/util/utilities/schemaGeneratorUtil.d.ts +2 -0
- package/dist/helper/util/utilities/schemaGeneratorUtil.js +129 -0
- package/dist/helper/util/utils.d.ts +2 -0
- package/dist/helper/util/utils.js +22 -0
- package/dist/helper/wrapper/PlaywrightWrappers.d.ts +8 -0
- package/dist/helper/wrapper/PlaywrightWrappers.js +26 -0
- package/dist/helper/wrapper/assert.d.ts +9 -0
- package/dist/helper/wrapper/assert.js +23 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +57 -0
- package/dist/scripts/get-versions.d.ts +1 -0
- package/dist/scripts/get-versions.js +98 -0
- package/dist/scripts/posttest.d.ts +1 -0
- package/dist/scripts/posttest.js +29 -0
- package/dist/scripts/pretest.d.ts +1 -0
- package/dist/scripts/pretest.js +57 -0
- package/dist/scripts/util.d.ts +1 -0
- package/dist/scripts/util.js +376 -0
- package/package.json +68 -0
- package/src/exec/featureFileCache.ts +80 -0
- package/src/exec/featureFilePreProcess.ts +239 -0
- package/src/exec/preLoader.ts +72 -0
- package/src/exec/preProcessEntry.ts +59 -0
- package/src/exec/preProcess_old_todelete.ts +289 -0
- package/src/exec/runner.ts +241 -0
- package/src/exec/runnerCuke.js +90 -0
- package/src/exec/runner_orchestrator.ts +91 -0
- package/src/exec/sgGenerator.ts +373 -0
- package/src/global.ts +130 -0
- package/src/helper/actions/api/apiRequestActions.ts +362 -0
- package/src/helper/actions/api/apiValidationActions.ts +594 -0
- package/src/helper/actions/apiActions.ts +18 -0
- package/src/helper/actions/apiStepDefs.ts +80 -0
- package/src/helper/actions/comm/commonActions.ts +165 -0
- package/src/helper/actions/comm/utilityActions.ts +344 -0
- package/src/helper/actions/commActions.ts +18 -0
- package/src/helper/actions/commStepDefs.ts +72 -0
- package/src/helper/actions/stepGroupStepDefs.ts +17 -0
- package/src/helper/actions/web/alertActions.ts +179 -0
- package/src/helper/actions/web/cookieActions.ts +124 -0
- package/src/helper/actions/web/downloadActions.ts +129 -0
- package/src/helper/actions/web/elementReaderActions.ts +323 -0
- package/src/helper/actions/web/formActions.ts +469 -0
- package/src/helper/actions/web/iframeActions.ts +67 -0
- package/src/helper/actions/web/javascriptActions.ts +38 -0
- package/src/helper/actions/web/keyboardActions.ts +101 -0
- package/src/helper/actions/web/localStorageActions.ts +109 -0
- package/src/helper/actions/web/mouseActions.ts +864 -0
- package/src/helper/actions/web/reportingActions.ts +53 -0
- package/src/helper/actions/web/screenshotActions.ts +124 -0
- package/src/helper/actions/web/testDataActions.ts +162 -0
- package/src/helper/actions/web/validationActions.ts +2287 -0
- package/src/helper/actions/web/waitActions.ts +757 -0
- package/src/helper/actions/web/webNavigation.ts +313 -0
- package/src/helper/actions/webActions.ts +33 -0
- package/src/helper/actions/webStepDefs.ts +505 -0
- package/src/helper/browsers/browserManager.ts +23 -0
- package/src/helper/bundle/defaultEntries.ts +208 -0
- package/src/helper/bundle/env.ts +119 -0
- package/src/helper/bundle/vars.ts +368 -0
- package/src/helper/faker/customFaker.ts +107 -0
- package/src/helper/faker/modules/data/postcodes_valid_sg.json +17 -0
- package/src/helper/faker/modules/dateTime.ts +121 -0
- package/src/helper/faker/modules/mobile.ts +58 -0
- package/src/helper/faker/modules/nric.ts +109 -0
- package/src/helper/faker/modules/passport.ts +34 -0
- package/src/helper/faker/modules/person.ts +93 -0
- package/src/helper/faker/modules/postcode.ts +57 -0
- package/src/helper/fixtures/locAggregate.ts +61 -0
- package/src/helper/fixtures/logFixture.ts +57 -0
- package/src/helper/fixtures/webFixture.ts +206 -0
- package/src/helper/fixtures/webLocFixture.ts +143 -0
- package/src/helper/report/allureStepLogger.ts +26 -0
- package/src/helper/report/customiseReport.ts +61 -0
- package/src/helper/report/init.ts +18 -0
- package/src/helper/report/report.ts +72 -0
- package/src/helper/util/dataLoader.ts +42 -0
- package/src/helper/util/logger.ts +32 -0
- package/src/helper/util/session/sessionUtil.ts +839 -0
- package/src/helper/util/stepHelpers.ts +14 -0
- package/src/helper/util/test-data/dataLoader.ts +108 -0
- package/src/helper/util/test-data/dataTest.ts +191 -0
- package/src/helper/util/test-data/registerUser.json +7 -0
- package/src/helper/util/totp/totpHelper.ts +102 -0
- package/src/helper/util/utilities/cryptoUtil.ts +53 -0
- package/src/helper/util/utilities/schemaGeneratorUtil.ts +143 -0
- package/src/helper/util/utils.ts +28 -0
- package/src/helper/wrapper/PlaywrightWrappers.ts +28 -0
- package/src/helper/wrapper/assert.ts +25 -0
- package/src/index.ts +17 -0
- package/src/scripts/get-versions.ts +68 -0
- package/src/scripts/posttest.ts +32 -0
- package/src/scripts/pretest.ts +48 -0
- package/src/scripts/util.ts +406 -0
- package/tsconfig.json +30 -0
|
@@ -0,0 +1,1754 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.see = see;
|
|
37
|
+
exports.dontSee = dontSee;
|
|
38
|
+
exports.count = count;
|
|
39
|
+
exports.seePageTitle = seePageTitle;
|
|
40
|
+
exports.verifyPageTitle = verifyPageTitle;
|
|
41
|
+
exports.verifyHeaderText = verifyHeaderText;
|
|
42
|
+
exports.verifyTextOnPage = verifyTextOnPage;
|
|
43
|
+
exports.verifyTextNotEmptyAtLocation = verifyTextNotEmptyAtLocation;
|
|
44
|
+
exports.verifyTextAtLocation = verifyTextAtLocation;
|
|
45
|
+
exports.verifyInputFieldIsBlank = verifyInputFieldIsBlank;
|
|
46
|
+
exports.verifyInputFieldPresent = verifyInputFieldPresent;
|
|
47
|
+
exports.verifyInputFieldValue = verifyInputFieldValue;
|
|
48
|
+
exports.verifyLockedInputFieldValue = verifyLockedInputFieldValue;
|
|
49
|
+
exports.verifyTabField = verifyTabField;
|
|
50
|
+
exports.verifyToastTextContains = verifyToastTextContains;
|
|
51
|
+
exports.verifyTextToDisappearAtLocation = verifyTextToDisappearAtLocation;
|
|
52
|
+
exports.verifyFieldIsLocked = verifyFieldIsLocked;
|
|
53
|
+
exports.verifyFieldIsMandatory = verifyFieldIsMandatory;
|
|
54
|
+
exports.verifyFieldIsSecured = verifyFieldIsSecured;
|
|
55
|
+
exports.verifySelectDropdownValue = verifySelectDropdownValue;
|
|
56
|
+
exports.verifySelectListNotHaveGivenValue = verifySelectListNotHaveGivenValue;
|
|
57
|
+
exports.verifyElementPresent = verifyElementPresent;
|
|
58
|
+
exports.verifyElementNotPresent = verifyElementNotPresent;
|
|
59
|
+
exports.verifyElementEnabled = verifyElementEnabled;
|
|
60
|
+
exports.verifyElementDisabled = verifyElementDisabled;
|
|
61
|
+
exports.verifyElementSelected = verifyElementSelected;
|
|
62
|
+
exports.verifyElementHasAttribute = verifyElementHasAttribute;
|
|
63
|
+
exports.verifyElementCount = verifyElementCount;
|
|
64
|
+
exports.verifyElementOrder = verifyElementOrder;
|
|
65
|
+
exports.verifyElementInViewport = verifyElementInViewport;
|
|
66
|
+
/**
|
|
67
|
+
* @file validationActions.ts
|
|
68
|
+
*
|
|
69
|
+
* Validation helpers for PlayQ web actions.
|
|
70
|
+
* Provides see/don't see, page title checks, header/text verifications,
|
|
71
|
+
* input value checks, tab field validations, toast checks, and more with
|
|
72
|
+
* runner-aware step wrappers and screenshot options.
|
|
73
|
+
*
|
|
74
|
+
* Authors: PlayQ Team
|
|
75
|
+
* Version: v1.0.0
|
|
76
|
+
*/
|
|
77
|
+
const allure = __importStar(require("allure-js-commons"));
|
|
78
|
+
const global_1 = require("../../../global");
|
|
79
|
+
const screenshotActions_1 = require("./screenshotActions");
|
|
80
|
+
const commonActions_1 = require("../comm/commonActions");
|
|
81
|
+
const waitActions_1 = require("./waitActions");
|
|
82
|
+
const test_1 = require("@playwright/test");
|
|
83
|
+
const vars_1 = require("../../bundle/vars");
|
|
84
|
+
const config = {};
|
|
85
|
+
function isPlaywrightRunner() { return process.env.TEST_RUNNER === 'playwright'; }
|
|
86
|
+
const __allureAny_val = allure;
|
|
87
|
+
if (typeof __allureAny_val.step !== 'function') {
|
|
88
|
+
__allureAny_val.step = async (_n, f) => await f();
|
|
89
|
+
}
|
|
90
|
+
// Allure compatibility shim: if step is unavailable, just run the body
|
|
91
|
+
const __allureAny_web = allure;
|
|
92
|
+
if (typeof __allureAny_web.step !== 'function') {
|
|
93
|
+
__allureAny_web.step = async (_name, fn) => await fn();
|
|
94
|
+
}
|
|
95
|
+
async function see(page, text, options) {
|
|
96
|
+
const resolvedText = global_1.vars.replaceVariables(text);
|
|
97
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
98
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, partialMatch = false, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
99
|
+
const stepName = `Web: Verify text on page -text: ${resolvedText} -options: ${JSON.stringify(options_json)}`;
|
|
100
|
+
async function run() {
|
|
101
|
+
if (!page)
|
|
102
|
+
throw new Error("Page not initialized");
|
|
103
|
+
let matched = false;
|
|
104
|
+
let allText = await page.textContent("body");
|
|
105
|
+
let actual = allText || "";
|
|
106
|
+
let expected = resolvedText;
|
|
107
|
+
if (ignoreCase) {
|
|
108
|
+
actual = actual.toLowerCase();
|
|
109
|
+
expected = expected.toLowerCase();
|
|
110
|
+
}
|
|
111
|
+
matched = partialMatch ? actual.includes(expected) : actual.includes(expected);
|
|
112
|
+
if (!matched) {
|
|
113
|
+
const message = `❌ Text "${resolvedText}" not found in page content.`;
|
|
114
|
+
await (0, commonActions_1.attachLog)(message, "text/plain");
|
|
115
|
+
if (assert !== false)
|
|
116
|
+
throw new Error(message);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
await (0, commonActions_1.attachLog)(`✅ Text "${resolvedText}" found in page.`, "text/plain");
|
|
120
|
+
}
|
|
121
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText || `Verify text in page: ${resolvedText}`, screenshotFullPage);
|
|
122
|
+
}
|
|
123
|
+
if (isPlaywrightRunner()) {
|
|
124
|
+
await __allureAny_val.step(stepName, run);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
await run();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async function dontSee(page, text, options) {
|
|
131
|
+
const options_json = typeof options === 'string' ? global_1.vars.parseLooseJson(options) : options || {};
|
|
132
|
+
const stepName = `Web: Dont See -text: ${text}`;
|
|
133
|
+
if (isPlaywrightRunner()) {
|
|
134
|
+
await __allureAny_val.step(stepName, async () => { await doDontSee(); });
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
await doDontSee();
|
|
138
|
+
}
|
|
139
|
+
async function doDontSee() {
|
|
140
|
+
const content = await page.content();
|
|
141
|
+
if (content.includes(text)) {
|
|
142
|
+
await (0, commonActions_1.attachLog)(`❌ Text found but expected to be absent: ${text}`, "text/plain");
|
|
143
|
+
throw new Error(`Text '${text}' should not be visible`);
|
|
144
|
+
}
|
|
145
|
+
await (0, commonActions_1.attachLog)(`✅ Text not visible as expected: ${text}`, "text/plain");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function count(page, field, options) {
|
|
149
|
+
const options_json = typeof options === 'string' ? global_1.vars.parseLooseJson(options) : options || {};
|
|
150
|
+
const locator = typeof field === 'string'
|
|
151
|
+
? await (0, global_1.webLocResolver)((options_json === null || options_json === void 0 ? void 0 : options_json.fieldType) || '', field, page, options_json === null || options_json === void 0 ? void 0 : options_json.pattern, typeof (options_json === null || options_json === void 0 ? void 0 : options_json.actionTimeout) === 'number' ? options_json.actionTimeout : undefined, (options_json === null || options_json === void 0 ? void 0 : options_json.smartAiRefresh) || '')
|
|
152
|
+
: field;
|
|
153
|
+
const stepName = `Web: Count Elements -field: ${typeof field === 'string' ? field : '<locator>'}`;
|
|
154
|
+
let result = 0;
|
|
155
|
+
if (isPlaywrightRunner()) {
|
|
156
|
+
await __allureAny_val.step(stepName, async () => { result = await locator.count(); });
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
result = await locator.count();
|
|
160
|
+
}
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Web: See Page Title -text: {param} -options: {param}
|
|
165
|
+
*
|
|
166
|
+
* Verifies the page title matches the expected text.
|
|
167
|
+
* Supports exact and partial match, case sensitivity, and screenshot capture.
|
|
168
|
+
*
|
|
169
|
+
* @param page Playwright Page instance
|
|
170
|
+
* @param expectedTitle The expected page title to match (e.g., "Your store").
|
|
171
|
+
* @param options Optional JSON string or object:
|
|
172
|
+
* - partialMatch: [boolean] Perform partial match on title (default: false)
|
|
173
|
+
* - ignoreCase: [boolean] Case-insensitive comparison (default: false)
|
|
174
|
+
* - assert: [boolean] If false, logs failure but does not throw (default: true)
|
|
175
|
+
* - screenshot: [boolean] Capture a screenshot (default: true)
|
|
176
|
+
* - screenshotText: [string] Description for screenshot
|
|
177
|
+
* - screenshotFullPage: [boolean] Full page screenshot (default: true)
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* Web: See Page Title -text: "Your store" -options: "{partialMatch: true, ignoreCase: false, assert: true}"
|
|
181
|
+
*/
|
|
182
|
+
async function seePageTitle(page, expectedTitle, options) {
|
|
183
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
184
|
+
const { partialMatch = false, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
185
|
+
const stepName = `Web: See Page Title -text: ${expectedTitle} -options: ${JSON.stringify(options_json)}`;
|
|
186
|
+
async function run() {
|
|
187
|
+
let actualTitle = await page.title();
|
|
188
|
+
let expected = global_1.vars.replaceVariables(expectedTitle);
|
|
189
|
+
let actual = actualTitle;
|
|
190
|
+
if (ignoreCase) {
|
|
191
|
+
expected = expected.toLowerCase();
|
|
192
|
+
actual = actual.toLowerCase();
|
|
193
|
+
}
|
|
194
|
+
if (partialMatch ? actual.includes(expected) : actual === expected) {
|
|
195
|
+
await global_1.comm.attachLog(`✅ Page title matched: expected: "${expectedTitle}", found: "${actualTitle}"`, "text/plain", "Validation");
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
await global_1.comm.attachLog(`❌ Page title mismatch: expected: "${expectedTitle}", found: "${actualTitle}"`, "text/plain", "Validation");
|
|
199
|
+
if (assert !== false)
|
|
200
|
+
throw new Error(`❌ Page title verification failed`);
|
|
201
|
+
}
|
|
202
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText || `Verify page title: ${expectedTitle}`, screenshotFullPage);
|
|
203
|
+
}
|
|
204
|
+
if (isPlaywrightRunner()) {
|
|
205
|
+
await __allureAny_val.step(stepName, run);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
await run();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Web: Verify page title -text: {param} -options: {param}
|
|
213
|
+
*
|
|
214
|
+
* Verifies the page title matches the expected text.
|
|
215
|
+
*
|
|
216
|
+
* @param expectedTitle - The expected page title to match (e.g., "Your store").
|
|
217
|
+
* @param options - Optional JSON string or object, supporting fields:
|
|
218
|
+
* - partial_check: [boolean] Perform partial match (default: false).
|
|
219
|
+
* - ignoreCase: [boolean] Case-sensitive match (default: true).
|
|
220
|
+
* - assert: [boolean] If false, continues the test even if the verification fails. Default: true.
|
|
221
|
+
* - screenshot: [boolean] Capture screenshot after verification (default: true).
|
|
222
|
+
* - screenshotText: [string] Description for screenshot attachment.
|
|
223
|
+
* - screenshotFullPage: [boolean] Full page screenshot (default: true).
|
|
224
|
+
*
|
|
225
|
+
* Example usage:
|
|
226
|
+
* * Web: Verify page title -text: "Your store" -options: "{partial_check: true, ignoreCase: false, assert: true}"
|
|
227
|
+
*/
|
|
228
|
+
async function verifyPageTitle(page, expectedTitle, options) {
|
|
229
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
230
|
+
const { partialMatch = false, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
231
|
+
if (isPlaywrightRunner()) {
|
|
232
|
+
await __allureAny_val.step(`Web: Verify page title -text: ${expectedTitle} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
233
|
+
await doVerifyPageTitle();
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
await doVerifyPageTitle();
|
|
238
|
+
}
|
|
239
|
+
async function doVerifyPageTitle() {
|
|
240
|
+
await (0, waitActions_1.waitForPageToLoad)(page);
|
|
241
|
+
let actualTitle = await page.title();
|
|
242
|
+
let expected = global_1.vars.replaceVariables(expectedTitle);
|
|
243
|
+
let actual = actualTitle;
|
|
244
|
+
if (!ignoreCase) {
|
|
245
|
+
expected = expected.toLowerCase();
|
|
246
|
+
actual = actual.toLowerCase();
|
|
247
|
+
}
|
|
248
|
+
if (partialMatch ? actual.includes(expected) : actual === expected) {
|
|
249
|
+
await (0, commonActions_1.attachLog)(`✅ Page title matched: expected: "${expectedTitle}", found: "${actualTitle}"`, "text/plain");
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
await (0, commonActions_1.attachLog)(`❌ Page title mismatch: expected: "${expectedTitle}", found: "${actualTitle}"`, "text/plain");
|
|
253
|
+
if (assert !== false) {
|
|
254
|
+
throw new Error(`❌ Page title verification failed`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Web: Verify header text -field: {param} -options: {param}
|
|
262
|
+
*
|
|
263
|
+
* Verifies that a header element's text (e.g., h1, h2, h3) matches the expected text. Supports partial or exact match, case sensitivity, and optional screenshot capture. The field parameter is the expected text, while pattern refines element selection if needed.
|
|
264
|
+
*
|
|
265
|
+
* @param field - The expected header text to match (e.g., "Welcome", "Dashboard").
|
|
266
|
+
* @param options - Optional JSON string or object:
|
|
267
|
+
* - actionTimeout: [number] Optional Action timeout in milliseconds for waiting. Default: Configured timeout.
|
|
268
|
+
* - navigationTimeout: [number] Optional Navigation timeout in milliseconds for waiting. Default: Configured timeout.
|
|
269
|
+
* - partialMatch: [boolean] Perform a partial match instead of an exact match. Default: false.
|
|
270
|
+
* - pattern: [string] Override the default pattern from config for element resolution. Default: Configured pattern in config.
|
|
271
|
+
* - ignoreCase: [boolean] Perform a case-sensitive match. Default: false.
|
|
272
|
+
* - assert: [boolean] If false, continues the test even if the verification fails. Default: true.
|
|
273
|
+
* - locator: [string] Optional locator to refine element search. Default: "". Eg:locator: locator: "xpath=(//h3[@class='module-title'])[1]"
|
|
274
|
+
* - headerType: [string] Specify a header level (e.g., "h1", "h2", "h3"). Default: Checks all headers from h1 to h4.
|
|
275
|
+
* - screenshot: [boolean] Capture a screenshot during verification. Default: true.
|
|
276
|
+
* - screenshotText: [string] Text description for the screenshot. Default: "".
|
|
277
|
+
* - screenshotFullPage: [boolean] Capture a full page screenshot. Default: true.
|
|
278
|
+
*
|
|
279
|
+
* @example
|
|
280
|
+
* Web: Verify header text -field: "Your Account Has Been Created!" -options: "{partialMatch: true, screenshot: true, screenshotText: 'After account creation', locator: "xpath=(//h3[@class='module-title'])[1]" }"
|
|
281
|
+
*/
|
|
282
|
+
async function verifyHeaderText(page, expectedText, options) {
|
|
283
|
+
let resolved_expectedText = global_1.vars.replaceVariables(expectedText);
|
|
284
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
285
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), navigationTimeout = Number(global_1.vars.getConfigValue("testExecution.navigationTimeout")), partialMatch = false, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
286
|
+
if (isPlaywrightRunner()) {
|
|
287
|
+
await __allureAny_val.step(`Web: Verify header -text: ${resolved_expectedText} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
288
|
+
await doverifyHeaderText();
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
await doverifyHeaderText();
|
|
293
|
+
}
|
|
294
|
+
async function doverifyHeaderText() {
|
|
295
|
+
if (!page)
|
|
296
|
+
throw new Error("Page not initialized");
|
|
297
|
+
await (0, waitActions_1.waitForPageToLoad)(page, navigationTimeout);
|
|
298
|
+
await page.waitForSelector("h1, h2, h3, h4, h5, h6", {
|
|
299
|
+
timeout: actionTimeout,
|
|
300
|
+
});
|
|
301
|
+
const startTime = Date.now();
|
|
302
|
+
let matchFound = false;
|
|
303
|
+
while (Date.now() - startTime < actionTimeout) {
|
|
304
|
+
const target = page.locator("h1, h2, h3, h4, h5, h6");
|
|
305
|
+
const count = await target.count();
|
|
306
|
+
for (let i = 0; i < count; i++) {
|
|
307
|
+
let actualText = await target.nth(i).innerText();
|
|
308
|
+
let expected = resolved_expectedText;
|
|
309
|
+
let actual = actualText;
|
|
310
|
+
if (!ignoreCase) {
|
|
311
|
+
expected = expected.toLowerCase();
|
|
312
|
+
actual = actual.toLowerCase();
|
|
313
|
+
}
|
|
314
|
+
if (partialMatch ? actual.includes(expected) : actual === expected) {
|
|
315
|
+
await (0, commonActions_1.attachLog)(`✅ Header matched: "${actualText}"`, "text/plain");
|
|
316
|
+
matchFound = true;
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (matchFound)
|
|
321
|
+
break;
|
|
322
|
+
await (0, commonActions_1.waitInMilliSeconds)(500); // Wait for 500ms before retrying
|
|
323
|
+
}
|
|
324
|
+
if (!matchFound) {
|
|
325
|
+
const msg = `❌ Header text verification failed for "${resolved_expectedText}"`;
|
|
326
|
+
await (0, commonActions_1.attachLog)(msg, "text/plain");
|
|
327
|
+
if (assert !== false)
|
|
328
|
+
throw new Error(msg);
|
|
329
|
+
}
|
|
330
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Web: Verify text on page -text: {param} -options: {param}
|
|
335
|
+
*
|
|
336
|
+
* Verifies that the provided text is present somewhere in the page.
|
|
337
|
+
*
|
|
338
|
+
* @param text - The expected text to search for on the page.
|
|
339
|
+
* @param options - Optional JSON string or object:
|
|
340
|
+
* - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
|
|
341
|
+
* - partialMatch: [boolean] Perform a partial match instead of an exact match. Default: false.
|
|
342
|
+
* - ignoreCase: [boolean] Perform a case-sensitive match. Default: false.
|
|
343
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
344
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
345
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
346
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* Web: Verify text on page -text: "Welcome back!" -options: "{partialMatch: true, screenshot: true, screenshotText: 'Verifying greeting'}"
|
|
350
|
+
*/
|
|
351
|
+
async function verifyTextOnPage(page, text, options) {
|
|
352
|
+
const resolvedText = global_1.vars.replaceVariables(text);
|
|
353
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
354
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), partialMatch = false, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
355
|
+
if (isPlaywrightRunner()) {
|
|
356
|
+
await __allureAny_val.step(`Web: Verify text on page -text: ${resolvedText} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
357
|
+
await doVerifyTextOnPage();
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
await doVerifyTextOnPage();
|
|
362
|
+
}
|
|
363
|
+
async function doVerifyTextOnPage() {
|
|
364
|
+
if (!page)
|
|
365
|
+
throw new Error("Page not initialized");
|
|
366
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
367
|
+
let matched = false;
|
|
368
|
+
let allText = await page.textContent("body");
|
|
369
|
+
let actual = allText || "";
|
|
370
|
+
let expected = resolvedText;
|
|
371
|
+
if (!ignoreCase) {
|
|
372
|
+
actual = actual.toLowerCase();
|
|
373
|
+
expected = expected.toLowerCase();
|
|
374
|
+
}
|
|
375
|
+
matched = partialMatch
|
|
376
|
+
? actual.includes(expected)
|
|
377
|
+
: actual.includes(expected);
|
|
378
|
+
if (!matched) {
|
|
379
|
+
const message = `❌ Text "${resolvedText}" not found in page content.`;
|
|
380
|
+
await (0, commonActions_1.attachLog)(message, "text/plain");
|
|
381
|
+
if (assert !== false)
|
|
382
|
+
throw new Error(message);
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
await (0, commonActions_1.attachLog)(`✅ Text "${resolvedText}" found in page.`, "text/plain");
|
|
386
|
+
}
|
|
387
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText || `Verify text in page: ${resolvedText}`, screenshotFullPage);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Web: Verify text not empty at location -field: {param} -options: {param}
|
|
392
|
+
*
|
|
393
|
+
* Verifies that the text content of an element is not empty.
|
|
394
|
+
*
|
|
395
|
+
* @param page - Playwright Page instance
|
|
396
|
+
* @param field - The label, id, name, or selector of the element to verify
|
|
397
|
+
* @param options - Optional JSON string or object:
|
|
398
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
399
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
400
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
401
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
402
|
+
* - screenshotText: [string] Screenshot description.
|
|
403
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
404
|
+
*/
|
|
405
|
+
async function verifyTextNotEmptyAtLocation(page, field, options) {
|
|
406
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
407
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
408
|
+
if (isPlaywrightRunner()) {
|
|
409
|
+
await __allureAny_val.step(`Web: Verify text not empty at location -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
410
|
+
await doVerifyTextNotEmptyAtLocation();
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
await doVerifyTextNotEmptyAtLocation();
|
|
415
|
+
}
|
|
416
|
+
async function doVerifyTextNotEmptyAtLocation() {
|
|
417
|
+
if (!page)
|
|
418
|
+
throw new Error("Page not initialized");
|
|
419
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
420
|
+
const target = typeof field === "string"
|
|
421
|
+
? await (0, global_1.webLocResolver)("text", field, page, pattern, actionTimeout)
|
|
422
|
+
: field;
|
|
423
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
424
|
+
const actualText = (await target.innerText()).trim();
|
|
425
|
+
if (!actualText) {
|
|
426
|
+
await (0, commonActions_1.attachLog)(`❌ Text at location "${field}" is empty!`, "text/plain");
|
|
427
|
+
if (assert !== false) {
|
|
428
|
+
throw new Error(`❌ Text at location "${field}" is empty.`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
else {
|
|
432
|
+
await (0, commonActions_1.attachLog)(`✅ Text at location "${field}" is not empty: "${actualText}"`, "text/plain");
|
|
433
|
+
}
|
|
434
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Web: Verify text at location -field: {param} -value: {param} -options: {param}
|
|
439
|
+
*
|
|
440
|
+
* Verifies that the text content of an element matches the expected value.
|
|
441
|
+
*
|
|
442
|
+
* @param field - The label, id, name, or selector of the element to verify.
|
|
443
|
+
* @param expectedText - The expected text content.
|
|
444
|
+
* @param options - Optional JSON string or object:
|
|
445
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
446
|
+
* - partialMatch: [boolean] If true, performs substring match. Default: false.
|
|
447
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
448
|
+
* - ignoreCase: [boolean] Whether the match is case-sensitive. Default: true.
|
|
449
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
450
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
451
|
+
* - screenshotText: [string] Screenshot description.
|
|
452
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
453
|
+
*/
|
|
454
|
+
async function verifyTextAtLocation(page, field, expectedText, options) {
|
|
455
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
456
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), partialMatch = false, pattern, ignoreCase = true, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
457
|
+
const resolvedExpectedValue = global_1.vars.replaceVariables(expectedText);
|
|
458
|
+
if (isPlaywrightRunner()) {
|
|
459
|
+
await __allureAny_val.step(`Web: Verify text at location -field: ${field} -value: ${resolvedExpectedValue} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
460
|
+
await doVerifyTextAtLocation();
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
await doVerifyTextAtLocation();
|
|
465
|
+
}
|
|
466
|
+
async function doVerifyTextAtLocation() {
|
|
467
|
+
if (!page)
|
|
468
|
+
throw new Error("Page not initialized");
|
|
469
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
470
|
+
const target = typeof field === "string"
|
|
471
|
+
? await (0, global_1.webLocResolver)("text", field, page, pattern, actionTimeout)
|
|
472
|
+
: field;
|
|
473
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
474
|
+
const tagName = await target.evaluate(el => el.tagName.toLowerCase());
|
|
475
|
+
let actualText;
|
|
476
|
+
if (tagName === 'textarea' || tagName === 'input') {
|
|
477
|
+
actualText = (await target.inputValue()).trim();
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
actualText = (await target.innerText()).trim();
|
|
481
|
+
}
|
|
482
|
+
const expected = global_1.vars.getValue(resolvedExpectedValue).trim();
|
|
483
|
+
let match = false;
|
|
484
|
+
if (ignoreCase) {
|
|
485
|
+
match = partialMatch
|
|
486
|
+
? actualText.includes(expected)
|
|
487
|
+
: actualText === expected;
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
match = partialMatch
|
|
491
|
+
? actualText.toLowerCase().includes(expected.toLowerCase())
|
|
492
|
+
: actualText.toLowerCase() === expected.toLowerCase();
|
|
493
|
+
}
|
|
494
|
+
if (match) {
|
|
495
|
+
await (0, commonActions_1.attachLog)(`✅ Text matched: "${actualText}"`, "text/plain");
|
|
496
|
+
}
|
|
497
|
+
else {
|
|
498
|
+
await (0, commonActions_1.attachLog)(`❌ Text mismatch: expected "${expected}", got "${actualText}"`, "text/plain");
|
|
499
|
+
if (assert !== false) {
|
|
500
|
+
throw new Error(`❌ Text mismatch for field "${field}"`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Web: Verify input field is blank -field: {param} -options: {param}
|
|
508
|
+
*
|
|
509
|
+
* Verifies that an input field is blank (empty value).
|
|
510
|
+
*
|
|
511
|
+
* @param page - Playwright Page instance
|
|
512
|
+
* @param field - The label, id, name, selector, or Locator for the input field
|
|
513
|
+
* @param options - Optional JSON string or object:
|
|
514
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
515
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
516
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
517
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
518
|
+
* - screenshotText: [string] Screenshot description.
|
|
519
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
520
|
+
*/
|
|
521
|
+
async function verifyInputFieldIsBlank(page, field, options) {
|
|
522
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
523
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
524
|
+
if (isPlaywrightRunner()) {
|
|
525
|
+
await __allureAny_val.step(`Web: Verify input field is blank -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
526
|
+
await doVerifyInputFieldIsBlank();
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
await doVerifyInputFieldIsBlank();
|
|
531
|
+
}
|
|
532
|
+
async function doVerifyInputFieldIsBlank() {
|
|
533
|
+
if (!page)
|
|
534
|
+
throw new Error("Page not initialized");
|
|
535
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
536
|
+
const target = typeof field === "string"
|
|
537
|
+
? await (0, global_1.webLocResolver)("input", field, page, pattern, actionTimeout)
|
|
538
|
+
: field;
|
|
539
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
540
|
+
const actualValue = (await target.inputValue()).trim();
|
|
541
|
+
if (actualValue === "") {
|
|
542
|
+
await (0, commonActions_1.attachLog)(`✅ Input field "${field}" is blank.`, "text/plain");
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
await (0, commonActions_1.attachLog)(`❌ Input field "${field}" is not blank. Value: "${actualValue}"`, "text/plain");
|
|
546
|
+
if (assert !== false) {
|
|
547
|
+
throw new Error(`❌ Input field "${field}" is not blank.`);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Web: Verify input field is present -field: {param} -options: {param}
|
|
555
|
+
*
|
|
556
|
+
* Verifies that an input field is present on the page, identified by label, text, id, name, or pattern.
|
|
557
|
+
*
|
|
558
|
+
* @param field - The label, text, id, name, or selector of the input field to verify (e.g., "Email", "Password").
|
|
559
|
+
* @param options - Optional JSON string or object:
|
|
560
|
+
* - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: Configured timeout.
|
|
561
|
+
* - pattern: [string] Optional pattern to refine element search. Default: Configured pattern.
|
|
562
|
+
* - assert: [boolean] If false, continues the test even if the verification fails. Default: true.
|
|
563
|
+
* - screenshot: [boolean] Capture a screenshot during verification. Default: true.
|
|
564
|
+
* - screenshotText: [string] Text description for the screenshot. Default: "".
|
|
565
|
+
* - screenshotFullPage: [boolean] Capture a full page screenshot. Default: true.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* Web: Verify input field is present -field: "Email" -options: "{screenshot: true, screenshotText: 'Verifying Email input field'}"
|
|
569
|
+
*/
|
|
570
|
+
async function verifyInputFieldPresent(page, field, options) {
|
|
571
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
572
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
573
|
+
if (!page)
|
|
574
|
+
throw new Error("Page not initialized");
|
|
575
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
576
|
+
const target = typeof field === "string"
|
|
577
|
+
? await (0, global_1.webLocResolver)("input", field, page, pattern, actionTimeout)
|
|
578
|
+
: field;
|
|
579
|
+
const isVisible = await target.isVisible();
|
|
580
|
+
if (isVisible) {
|
|
581
|
+
await (0, commonActions_1.attachLog)(`✅ Input field "${field}" is present and visible.`, "text/plain");
|
|
582
|
+
}
|
|
583
|
+
else {
|
|
584
|
+
await (0, commonActions_1.attachLog)(`❌ Input field "${field}" is not visible.`, "text/plain");
|
|
585
|
+
if (assert !== false) {
|
|
586
|
+
throw new Error(`❌ Input field "${field}" is not visible.`);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Web: Verify input field value -field: {param} -value: {param} -options: {param}
|
|
593
|
+
*
|
|
594
|
+
* Verifies that the value of an input field matches the expected value.
|
|
595
|
+
*
|
|
596
|
+
* @param field - The label, id, name, or selector of the input field to verify.
|
|
597
|
+
* @param expectedValue - The expected value of the input field.
|
|
598
|
+
* @param options - Optional JSON string or object:
|
|
599
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
600
|
+
* - partialMatch: [boolean] If true, performs substring match. Default: false.
|
|
601
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
602
|
+
* - ignoreCase: [boolean] Whether the match is case-sensitive. Default: true.
|
|
603
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
604
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
605
|
+
* - screenshotText: [string] Screenshot description.
|
|
606
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
607
|
+
*/
|
|
608
|
+
async function verifyInputFieldValue(page, field, expectedValue, options) {
|
|
609
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
610
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), partialMatch = false, pattern, ignoreCase = true, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
611
|
+
const resolvedExpectedValue = global_1.vars.replaceVariables(expectedValue);
|
|
612
|
+
if (isPlaywrightRunner()) {
|
|
613
|
+
await __allureAny_val.step(`Web: Verify input field value -field: ${field} -value: ${resolvedExpectedValue} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
614
|
+
await doVerifyInputFieldValue();
|
|
615
|
+
});
|
|
616
|
+
}
|
|
617
|
+
else {
|
|
618
|
+
await doVerifyInputFieldValue();
|
|
619
|
+
}
|
|
620
|
+
async function doVerifyInputFieldValue() {
|
|
621
|
+
if (!page)
|
|
622
|
+
throw new Error("Page not initialized");
|
|
623
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
624
|
+
const target = typeof field === "string"
|
|
625
|
+
? await (0, global_1.webLocResolver)("input", field, page, pattern, actionTimeout)
|
|
626
|
+
: field;
|
|
627
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
628
|
+
const tagName = await target.evaluate(el => el.tagName.toLowerCase());
|
|
629
|
+
let actualValue;
|
|
630
|
+
if (tagName === 'textarea' || tagName === 'input') {
|
|
631
|
+
actualValue = (await target.inputValue()).trim();
|
|
632
|
+
}
|
|
633
|
+
else {
|
|
634
|
+
actualValue = (await target.innerText()).trim();
|
|
635
|
+
}
|
|
636
|
+
const expected = global_1.vars.getValue(resolvedExpectedValue).trim();
|
|
637
|
+
let match = false;
|
|
638
|
+
if (ignoreCase) {
|
|
639
|
+
match = partialMatch
|
|
640
|
+
? actualValue.includes(expected)
|
|
641
|
+
: actualValue === expected;
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
match = partialMatch
|
|
645
|
+
? actualValue.toLowerCase().includes(expected.toLowerCase())
|
|
646
|
+
: actualValue.toLowerCase() === expected.toLowerCase();
|
|
647
|
+
}
|
|
648
|
+
if (match) {
|
|
649
|
+
await (0, commonActions_1.attachLog)(`✅ Input value matched: "${actualValue}"`, "text/plain");
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
await (0, commonActions_1.attachLog)(`❌ Input value mismatch: expected "${expected}", got "${actualValue}"`, "text/plain");
|
|
653
|
+
if (assert !== false) {
|
|
654
|
+
throw new Error(`❌ Input value mismatch for field "${field}"`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
/**
|
|
661
|
+
* Web: Verify locked input field value -field: {param} -value: {param} -options: {param}
|
|
662
|
+
*
|
|
663
|
+
* Verifies that the value of an locked input field matches the expected value.
|
|
664
|
+
*
|
|
665
|
+
* @param field - The label, id, name, or selector of the input field to verify.
|
|
666
|
+
* @param expectedValue - The expected value of the input field.
|
|
667
|
+
* @param options - Optional JSON string or object:
|
|
668
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
669
|
+
* - partialMatch: [boolean] If true, performs substring match. Default: false.
|
|
670
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
671
|
+
* - ignoreCase: [boolean] Whether the match is case-sensitive. Default: true.
|
|
672
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
673
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
674
|
+
* - screenshotText: [string] Screenshot description.
|
|
675
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
676
|
+
*/
|
|
677
|
+
async function verifyLockedInputFieldValue(page, field, expectedValue, options) {
|
|
678
|
+
var _a;
|
|
679
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
680
|
+
const { actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, partialMatch = false, pattern, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
681
|
+
const resolvedExpectedValue = global_1.vars.replaceVariables(expectedValue);
|
|
682
|
+
if (isPlaywrightRunner()) {
|
|
683
|
+
await __allureAny_web.step(`Web: Verify input field value -field: ${field} -value: ${resolvedExpectedValue} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
684
|
+
await doVerifyInputFieldValue();
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
await doVerifyInputFieldValue();
|
|
689
|
+
}
|
|
690
|
+
async function doVerifyInputFieldValue() {
|
|
691
|
+
if (!page)
|
|
692
|
+
throw new Error("Page not initialized");
|
|
693
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
694
|
+
const target = typeof field === "string"
|
|
695
|
+
? await (0, global_1.webLocResolver)("input", field, page, pattern, actionTimeout)
|
|
696
|
+
: field;
|
|
697
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
698
|
+
const actualValue = (await target.inputValue()).trim();
|
|
699
|
+
const expected = global_1.vars.getValue(resolvedExpectedValue).trim();
|
|
700
|
+
let match = false;
|
|
701
|
+
if (ignoreCase) {
|
|
702
|
+
match = partialMatch
|
|
703
|
+
? actualValue.includes(expected)
|
|
704
|
+
: actualValue === expected;
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
match = partialMatch
|
|
708
|
+
? actualValue.toLowerCase().includes(expected.toLowerCase())
|
|
709
|
+
: actualValue.toLowerCase() === expected.toLowerCase();
|
|
710
|
+
}
|
|
711
|
+
if (match) {
|
|
712
|
+
await (0, commonActions_1.attachLog)(`✅ Input value matched: "${actualValue}"`, "text/plain");
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
await (0, commonActions_1.attachLog)(`❌ Locked input value mismatch: expected "${expected}", got "${actualValue}"`, "text/plain");
|
|
716
|
+
if (assert !== false) {
|
|
717
|
+
throw new Error(`❌ Locked input value mismatch for field "${field}"`);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Web: Verify Tab field Present -field: {param} -options: {param}
|
|
725
|
+
*
|
|
726
|
+
* Verifies that a "Tab" field is present on the page, identified by label, text, id, name, or pattern.
|
|
727
|
+
*
|
|
728
|
+
* @param field - The label, text, id, name, or selector of the tab to verify (e.g., "Overview", "Settings").
|
|
729
|
+
* @param options - Optional JSON string or object:
|
|
730
|
+
* - actionTimeout: [number] Optional timeout in milliseconds for waiting. Default: from [config] or 30000.
|
|
731
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
732
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
733
|
+
* - isPresent: [boolean] Check Tab is present on the page. Default: true.
|
|
734
|
+
* - isEnabled: [boolean] Check if Tab is enabled. Default: false.
|
|
735
|
+
* - isSelected: [boolean] Check if Tab is selected. Default: false.
|
|
736
|
+
* - isNotSelected: [boolean] Check if Tab is not selected. Default: false.
|
|
737
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
738
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
739
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
740
|
+
*/
|
|
741
|
+
async function verifyTabField(page, field, options) {
|
|
742
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
743
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, assert = true, isPresent = true, isEnabled = false, isSelected = false, isNotSelected = false, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
744
|
+
if (isPlaywrightRunner()) {
|
|
745
|
+
await __allureAny_val.step(` Web: Verify Tab field Present -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
746
|
+
await doVerifyTabField();
|
|
747
|
+
});
|
|
748
|
+
}
|
|
749
|
+
else {
|
|
750
|
+
await doVerifyTabField();
|
|
751
|
+
}
|
|
752
|
+
async function doVerifyTabField() {
|
|
753
|
+
if (!page)
|
|
754
|
+
throw new Error("Page not initialized");
|
|
755
|
+
await (0, waitActions_1.waitForPageToLoad)(page);
|
|
756
|
+
const target = typeof field === "string"
|
|
757
|
+
? await (0, global_1.webLocResolver)("tab", field, page, pattern, actionTimeout)
|
|
758
|
+
: field;
|
|
759
|
+
await (0, waitActions_1.waitForEnabled)(target, actionTimeout);
|
|
760
|
+
let failureReason = "";
|
|
761
|
+
if (isPresent) {
|
|
762
|
+
const isVisible = await target.isVisible();
|
|
763
|
+
if (!isVisible) {
|
|
764
|
+
failureReason += `❌ Tab "${field}" is not visible.\n`;
|
|
765
|
+
}
|
|
766
|
+
else {
|
|
767
|
+
await (0, commonActions_1.attachLog)(`✅ Tab "${field}" is visible.`, "text/plain");
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
if (isEnabled) {
|
|
771
|
+
const isEnabled = await target.isEnabled();
|
|
772
|
+
if (!isEnabled) {
|
|
773
|
+
failureReason += `❌ Tab "${field}" is disabled.\n`;
|
|
774
|
+
}
|
|
775
|
+
else {
|
|
776
|
+
await (0, commonActions_1.attachLog)(`✅ Tab "${field}" is enabled.`, "text/plain");
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
if (isSelected) {
|
|
780
|
+
const ariaSelected = await target.getAttribute("aria-selected");
|
|
781
|
+
const tabIndex = await target.getAttribute("tabindex");
|
|
782
|
+
if (ariaSelected !== "true" || tabIndex !== "0") {
|
|
783
|
+
failureReason += `❌ Tab "${field}" is not selected (aria-selected != true).\n`;
|
|
784
|
+
}
|
|
785
|
+
else {
|
|
786
|
+
await (0, commonActions_1.attachLog)(`✅ Tab "${field}" is selected (aria-selected = true).`, "text/plain");
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
if (isNotSelected) {
|
|
790
|
+
const ariaSelected = await target.getAttribute("aria-selected");
|
|
791
|
+
const tabIndex = await target.getAttribute("tabindex");
|
|
792
|
+
if (ariaSelected !== "false" || tabIndex !== "-1") {
|
|
793
|
+
failureReason += `❌ Tab "${field}" is focused (expected not focused).\n`;
|
|
794
|
+
}
|
|
795
|
+
else {
|
|
796
|
+
await (0, commonActions_1.attachLog)(`✅ Tab "${field}" is not focused.`, "text/plain");
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
if (failureReason) {
|
|
800
|
+
await (0, commonActions_1.attachLog)(failureReason.trim(), "text/plain");
|
|
801
|
+
if (assert !== false) {
|
|
802
|
+
throw new Error(failureReason.trim());
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
/**
|
|
809
|
+
* Web: Verify Toast Text Contains -text: {param} -options: {param}
|
|
810
|
+
*
|
|
811
|
+
* Verifies that a toast (notification) element appears on the page and contains the expected text.
|
|
812
|
+
* Throws an error (or logs a warning if `assert: false`) if the text is not found.
|
|
813
|
+
*
|
|
814
|
+
* @param page - Playwright Page instance.
|
|
815
|
+
* @param text - The expected substring to match within the toast notification (e.g., "Saved successfully").
|
|
816
|
+
* @param options - Optional JSON string or object:
|
|
817
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for toast visibility. Default: 30000.
|
|
818
|
+
* - pattern: [string] Optional pattern to refine toast element search (e.g., class name or attribute).
|
|
819
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
820
|
+
* - screenshot: [boolean] Capture a screenshot after verification. Default: true.
|
|
821
|
+
* - screenshotText: [string] Description for screenshot attachment.
|
|
822
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* Web: Verify Toast Text Contains -text: "Saved successfully"
|
|
826
|
+
*/
|
|
827
|
+
async function verifyToastTextContains(page, text, options) {
|
|
828
|
+
var _a;
|
|
829
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
830
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
831
|
+
const target = typeof text === "string"
|
|
832
|
+
? await (0, global_1.webLocResolver)("text", text, page, pattern, actionTimeout, "before")
|
|
833
|
+
: text;
|
|
834
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
835
|
+
const actual = await target.textContent();
|
|
836
|
+
if (!(actual === null || actual === void 0 ? void 0 : actual.includes(text))) {
|
|
837
|
+
await (0, commonActions_1.attachLog)(`❌ Expected toast to contain "${text}", but got "${actual}"`, "text/plain");
|
|
838
|
+
if (assert) {
|
|
839
|
+
throw new Error(`❌ Expected toast to contain "${text}", but got "${actual}"`);
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
await ((_a = global_1.logFixture
|
|
843
|
+
.getLogger()) === null || _a === void 0 ? void 0 : _a.warn(`❌ Expected toast to contain "${text}", but got "${actual}"`));
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
else {
|
|
847
|
+
await (0, commonActions_1.attachLog)(`✅ Toast contains expected text: "${text}"`, "text/plain");
|
|
848
|
+
}
|
|
849
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* Web: Verify text to disappear at location -field: {param} -text: {param} -options: {param}
|
|
853
|
+
*
|
|
854
|
+
* Verifies that the specified text disappears from the given field/locator within a timeout.
|
|
855
|
+
*
|
|
856
|
+
* @param page - Playwright Page instance
|
|
857
|
+
* @param field - The selector or Locator where the text should disappear
|
|
858
|
+
* @param textToDisappear - The text to wait for disappearance
|
|
859
|
+
* @param options - Optional string or object:
|
|
860
|
+
* - actionTimeout: [number] Timeout in ms (default: 30000)
|
|
861
|
+
* - partialMatch: [boolean] If true, waits for substring match (default: false)
|
|
862
|
+
* - ignoreCase: [boolean] If true, match is case-insensitive (default: true)
|
|
863
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
864
|
+
* - screenshot: [boolean] Capture screenshot after waiting (default: true)
|
|
865
|
+
* - screenshotText: [string] Description for screenshot
|
|
866
|
+
* - screenshotFullPage: [boolean] Full page screenshot (default: true)
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* await verifyTextToDisappearAtLocation(page, 'h1', 'Loading...', { actionTimeout: 10000, partialMatch: true });
|
|
870
|
+
*/
|
|
871
|
+
async function verifyTextToDisappearAtLocation(page, field, textToDisappear, options) {
|
|
872
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
873
|
+
const { actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), partialMatch = false, ignoreCase = true, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, pattern, } = options_json;
|
|
874
|
+
if (isPlaywrightRunner()) {
|
|
875
|
+
await __allureAny_val.step(`Web: Verify text to disappear at location -field: ${field} -text: ${textToDisappear} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
876
|
+
await doVerifyTextToDisappearAtLocation();
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
else {
|
|
880
|
+
await doVerifyTextToDisappearAtLocation();
|
|
881
|
+
}
|
|
882
|
+
async function doVerifyTextToDisappearAtLocation() {
|
|
883
|
+
if (!page)
|
|
884
|
+
throw new Error("Page not initialized");
|
|
885
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
886
|
+
const target = typeof field === "string"
|
|
887
|
+
? await (0, global_1.webLocResolver)("text", field, page, pattern, actionTimeout)
|
|
888
|
+
: field;
|
|
889
|
+
const start = Date.now();
|
|
890
|
+
let disappeared = false;
|
|
891
|
+
let lastActual = "";
|
|
892
|
+
while (Date.now() - start < actionTimeout) {
|
|
893
|
+
if (!(await target.isVisible().catch(() => false))) {
|
|
894
|
+
disappeared = true;
|
|
895
|
+
break;
|
|
896
|
+
}
|
|
897
|
+
const actualText = ((await target.innerText().catch(() => "")) || "").trim();
|
|
898
|
+
lastActual = actualText;
|
|
899
|
+
let expected = textToDisappear;
|
|
900
|
+
let actual = actualText;
|
|
901
|
+
if (ignoreCase) {
|
|
902
|
+
expected = expected.toLowerCase();
|
|
903
|
+
actual = actual.toLowerCase();
|
|
904
|
+
}
|
|
905
|
+
if (partialMatch ? !actual.includes(expected) : actual !== expected) {
|
|
906
|
+
disappeared = true;
|
|
907
|
+
break;
|
|
908
|
+
}
|
|
909
|
+
await new Promise((res) => setTimeout(res, 300));
|
|
910
|
+
}
|
|
911
|
+
if (!disappeared) {
|
|
912
|
+
const msg = `❌ Text "${textToDisappear}" did not disappear from location "${field}" within ${actionTimeout}ms. Last actual: "${lastActual}"`;
|
|
913
|
+
await (0, commonActions_1.attachLog)(msg, "text/plain");
|
|
914
|
+
if (assert !== false)
|
|
915
|
+
throw new Error(msg);
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
await (0, commonActions_1.attachLog)(`✅ Text "${textToDisappear}" disappeared from location "${field}"`, "text/plain");
|
|
919
|
+
}
|
|
920
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText || `Verified text disappeared at location: ${textToDisappear}`, screenshotFullPage);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
/**
|
|
924
|
+
* Web: Verify field is locked -field: {param} -options: {param}
|
|
925
|
+
* Verifies that the specified field on the page is locked (read-only).
|
|
926
|
+
* Designed for use in Cucumber step definitions.
|
|
927
|
+
*
|
|
928
|
+
* @param page - Playwright Page instance.
|
|
929
|
+
* @param field - The label, text, id, name, or selector of the field.
|
|
930
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
931
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
932
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
933
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
934
|
+
*
|
|
935
|
+
*/
|
|
936
|
+
async function verifyFieldIsLocked(page, field, options) {
|
|
937
|
+
var _a;
|
|
938
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
939
|
+
const { iframe = "", actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, // Default timeout
|
|
940
|
+
pattern, fieldType, screenshot = false, screenshotText = "", screenshotFullPage = true, screenshotField = false, smartIQ_refreshLoc = "", } = options_json || {};
|
|
941
|
+
if (isPlaywrightRunner()) {
|
|
942
|
+
await __allureAny_web.step(`Web: Verify field is locked -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
943
|
+
await doverifyFieldLocked();
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
else {
|
|
947
|
+
await doverifyFieldLocked();
|
|
948
|
+
}
|
|
949
|
+
async function doverifyFieldLocked() {
|
|
950
|
+
const target = typeof field === "string"
|
|
951
|
+
? await (0, global_1.webLocResolver)(fieldType || "input", field, page, pattern, smartIQ_refreshLoc)
|
|
952
|
+
: field;
|
|
953
|
+
if (iframe) {
|
|
954
|
+
await (0, waitActions_1.waitForEnabled)(page.frameLocator(iframe).locator(target), actionTimeout);
|
|
955
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
await (0, waitActions_1.waitForEnabled)(target, actionTimeout);
|
|
959
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
960
|
+
}
|
|
961
|
+
const isFieldScreenshot = screenshotField === true;
|
|
962
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, !isFieldScreenshot, isFieldScreenshot ? target : undefined);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Web: Verify field is mandatory -field: {param} -options: {param}
|
|
967
|
+
* Verifies that the specified field on the page is locked (read-only).
|
|
968
|
+
* Designed for use in Cucumber step definitions.
|
|
969
|
+
*
|
|
970
|
+
* @param page - Playwright Page instance.
|
|
971
|
+
* @param field - The label, text, id, name, or selector of the field.
|
|
972
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
973
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
974
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
975
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
976
|
+
*
|
|
977
|
+
*/
|
|
978
|
+
async function verifyFieldIsMandatory(page, field, options) {
|
|
979
|
+
var _a;
|
|
980
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
981
|
+
const { iframe = "", actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, // Default timeout
|
|
982
|
+
pattern, fieldType, screenshot = false, screenshotText = "", screenshotFullPage = true, screenshotField = false, smartIQ_refreshLoc = "", } = options_json || {};
|
|
983
|
+
if (isPlaywrightRunner()) {
|
|
984
|
+
await __allureAny_web.step(`Web: Verify field is mandatory -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
985
|
+
await doverifyFieldIsMandatory();
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
else {
|
|
989
|
+
await doverifyFieldIsMandatory();
|
|
990
|
+
}
|
|
991
|
+
async function doverifyFieldIsMandatory() {
|
|
992
|
+
const target = typeof field === "string"
|
|
993
|
+
? await (0, global_1.webLocResolver)(fieldType || "input", field, page, pattern, smartIQ_refreshLoc)
|
|
994
|
+
: field;
|
|
995
|
+
if (iframe) {
|
|
996
|
+
await (0, waitActions_1.waitForEnabled)(page.frameLocator(iframe).locator(target), actionTimeout);
|
|
997
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
998
|
+
}
|
|
999
|
+
else {
|
|
1000
|
+
await (0, waitActions_1.waitForEnabled)(target, actionTimeout);
|
|
1001
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
1002
|
+
}
|
|
1003
|
+
const isFieldScreenshot = screenshotField === true;
|
|
1004
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, !isFieldScreenshot, isFieldScreenshot ? target : undefined);
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
/**
|
|
1008
|
+
* Web: Verify field is secured -field: {param} -options: {param}
|
|
1009
|
+
* Verifies that the specified field on the page is secured.
|
|
1010
|
+
* Designed for use in Cucumber step definitions.
|
|
1011
|
+
*
|
|
1012
|
+
* @param page - Playwright Page instance.
|
|
1013
|
+
* @param field - The label, text, id, name, or selector of the field.
|
|
1014
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1015
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1016
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1017
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1018
|
+
*
|
|
1019
|
+
*/
|
|
1020
|
+
async function verifyFieldIsSecured(page, field, options) {
|
|
1021
|
+
var _a;
|
|
1022
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
1023
|
+
const { iframe = "", actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, // Default timeout
|
|
1024
|
+
pattern, fieldType, screenshot = false, screenshotText = "", screenshotFullPage = true, screenshotField = false, smartIQ_refreshLoc = "", } = options_json || {};
|
|
1025
|
+
if (isPlaywrightRunner()) {
|
|
1026
|
+
await __allureAny_web.step(`Web: Verify field is secured -field: ${field} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
1027
|
+
await doverifyFieldIsSecured();
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
else {
|
|
1031
|
+
await doverifyFieldIsSecured();
|
|
1032
|
+
}
|
|
1033
|
+
async function doverifyFieldIsSecured() {
|
|
1034
|
+
const target = typeof field === "string"
|
|
1035
|
+
? await (0, global_1.webLocResolver)(fieldType || "input", field, page, pattern, smartIQ_refreshLoc)
|
|
1036
|
+
: field;
|
|
1037
|
+
if (iframe) {
|
|
1038
|
+
await (0, waitActions_1.waitForEnabled)(page.frameLocator(iframe).locator(target), actionTimeout);
|
|
1039
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
1040
|
+
}
|
|
1041
|
+
else {
|
|
1042
|
+
await (0, waitActions_1.waitForEnabled)(target, actionTimeout);
|
|
1043
|
+
await (0, test_1.expect)(target).toBeVisible({ timeout: actionTimeout });
|
|
1044
|
+
}
|
|
1045
|
+
const isFieldScreenshot = screenshotField === true;
|
|
1046
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, !isFieldScreenshot, isFieldScreenshot ? target : undefined);
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
/**
|
|
1050
|
+
* Web: Verify select field value -field: {param} -value: {param} -options: {param}
|
|
1051
|
+
*
|
|
1052
|
+
* Verifies that the value of a select field matches the expected value.
|
|
1053
|
+
*
|
|
1054
|
+
* @param field - The label, id, name, or selector of the select field to verify.
|
|
1055
|
+
* @param expectedValue - The expected value of the select field.
|
|
1056
|
+
* @param options - Optional JSON string or object:
|
|
1057
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
1058
|
+
* - partialMatch: [boolean] If true, performs substring match. Default: false.
|
|
1059
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1060
|
+
* - ignoreCase: [boolean] Whether the match is case-sensitive. Default: true.
|
|
1061
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1062
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
1063
|
+
* - screenshotText: [string] Screenshot description.
|
|
1064
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1065
|
+
*/
|
|
1066
|
+
async function verifySelectDropdownValue(page, field, expectedValue, options) {
|
|
1067
|
+
var _a;
|
|
1068
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
1069
|
+
const { actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, partialMatch = false, pattern, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
1070
|
+
const resolvedExpectedValue = global_1.vars.replaceVariables(expectedValue);
|
|
1071
|
+
if (isPlaywrightRunner()) {
|
|
1072
|
+
await __allureAny_web.step(`Web: Verify select dropdown value -field: ${field} -value: ${resolvedExpectedValue} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
1073
|
+
await doVerifySelectDropdownValue();
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
else {
|
|
1077
|
+
await doVerifySelectDropdownValue();
|
|
1078
|
+
}
|
|
1079
|
+
async function doVerifySelectDropdownValue() {
|
|
1080
|
+
if (!page)
|
|
1081
|
+
throw new Error("Page not initialized");
|
|
1082
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1083
|
+
const target = typeof field === "string"
|
|
1084
|
+
? await (0, global_1.webLocResolver)("dropdown", field, page, pattern, actionTimeout)
|
|
1085
|
+
: field;
|
|
1086
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
1087
|
+
const actualValue = (await target.getAttribute("value")).trim();
|
|
1088
|
+
const expected = global_1.vars.getValue(resolvedExpectedValue).trim();
|
|
1089
|
+
let match = false;
|
|
1090
|
+
if (ignoreCase) {
|
|
1091
|
+
match = partialMatch
|
|
1092
|
+
? actualValue.includes(expected)
|
|
1093
|
+
: actualValue === expected;
|
|
1094
|
+
}
|
|
1095
|
+
else {
|
|
1096
|
+
match = partialMatch
|
|
1097
|
+
? actualValue.toLowerCase().includes(expected.toLowerCase())
|
|
1098
|
+
: actualValue.toLowerCase() === expected.toLowerCase();
|
|
1099
|
+
}
|
|
1100
|
+
if (match) {
|
|
1101
|
+
await (0, commonActions_1.attachLog)(`✅ Select value matched: "${actualValue}"`, "text/plain");
|
|
1102
|
+
}
|
|
1103
|
+
else {
|
|
1104
|
+
await (0, commonActions_1.attachLog)(`❌ Select value mismatch: expected "${expected}", got "${actualValue}"`, "text/plain");
|
|
1105
|
+
if (assert !== false) {
|
|
1106
|
+
throw new Error(`❌ Select value mismatch for field "${field}"`);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Web: Verify select list does not have given value -field: {param} -value: {param} -options: {param}
|
|
1114
|
+
*
|
|
1115
|
+
* Verifies that a select dropdown does NOT contain the specified value in its options list.
|
|
1116
|
+
*
|
|
1117
|
+
* @param page - Playwright Page instance
|
|
1118
|
+
* @param field - The label, id, name, or selector of the select field to verify.
|
|
1119
|
+
* @param excludedValue - The value that should NOT be present in the dropdown options.
|
|
1120
|
+
* @param options - Optional JSON string or object:
|
|
1121
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
1122
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1123
|
+
* - ignoreCase: [boolean] Whether the match is case-sensitive. Default: true.
|
|
1124
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1125
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
1126
|
+
* - screenshotText: [string] Screenshot description.
|
|
1127
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1128
|
+
*
|
|
1129
|
+
* @example
|
|
1130
|
+
* Web: Verify select list does not have given value -field: "Country" -value: "Antarctica" -options: "{screenshot: true, screenshotText: 'Verified Antarctica not in list'}"
|
|
1131
|
+
*/
|
|
1132
|
+
async function verifySelectListNotHaveGivenValue(page, field, excludedValue, options) {
|
|
1133
|
+
var _a;
|
|
1134
|
+
const options_json = typeof options === "string" ? global_1.vars.parseLooseJson(options) : options || {};
|
|
1135
|
+
const { actionTimeout = ((_a = config === null || config === void 0 ? void 0 : config.testExecution) === null || _a === void 0 ? void 0 : _a.actionTimeout) || Number(global_1.vars.getConfigValue("testExecution.actionTimeout")) || 30000, pattern, ignoreCase = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, } = options_json;
|
|
1136
|
+
const resolvedExcludedValue = global_1.vars.replaceVariables(excludedValue);
|
|
1137
|
+
if (isPlaywrightRunner()) {
|
|
1138
|
+
await __allureAny_web.step(`Web: Verify select list does not have given value -field: ${field} -value: ${resolvedExcludedValue} -options: ${JSON.stringify(options_json)}`, async () => {
|
|
1139
|
+
await doVerifySelectListNotHaveGivenValue();
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
else {
|
|
1143
|
+
await doVerifySelectListNotHaveGivenValue();
|
|
1144
|
+
}
|
|
1145
|
+
async function doVerifySelectListNotHaveGivenValue() {
|
|
1146
|
+
if (!page)
|
|
1147
|
+
throw new Error("Page not initialized");
|
|
1148
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1149
|
+
const target = typeof field === "string"
|
|
1150
|
+
? await (0, global_1.webLocResolver)("dropdown", field, page, pattern, actionTimeout)
|
|
1151
|
+
: field;
|
|
1152
|
+
await target.waitFor({ state: "visible", timeout: actionTimeout });
|
|
1153
|
+
await target.click();
|
|
1154
|
+
await page.waitForTimeout(2000); // Wait for options to render
|
|
1155
|
+
const optionLocator = target.locator('xpath=following::div[@role="option"]');
|
|
1156
|
+
const size = await optionLocator.count();
|
|
1157
|
+
if (size === 0) {
|
|
1158
|
+
throw new Error(`❌ No options found for the select field "${field}".`);
|
|
1159
|
+
}
|
|
1160
|
+
// Collect all option texts and check for the excluded value
|
|
1161
|
+
const optionTexts = [];
|
|
1162
|
+
for (let i = 0; i < size; i++) {
|
|
1163
|
+
optionTexts.push((await optionLocator.nth(i).innerText()).trim());
|
|
1164
|
+
}
|
|
1165
|
+
// Case handling: when ignoreCase=true, compare in lowercase; else compare exact
|
|
1166
|
+
const found = optionTexts.some((optText) => {
|
|
1167
|
+
const current = ignoreCase ? optText.toLowerCase() : optText;
|
|
1168
|
+
const compare = ignoreCase
|
|
1169
|
+
? global_1.vars.replaceVariables(resolvedExcludedValue).trim().toLowerCase()
|
|
1170
|
+
: global_1.vars.replaceVariables(resolvedExcludedValue).trim();
|
|
1171
|
+
return current === compare;
|
|
1172
|
+
});
|
|
1173
|
+
if (found) {
|
|
1174
|
+
const msg = `❌ Select list should NOT contain "${resolvedExcludedValue}", but it was found.`;
|
|
1175
|
+
await (0, commonActions_1.attachLog)(msg, "text/plain");
|
|
1176
|
+
if (assert !== false) {
|
|
1177
|
+
throw new Error(msg);
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
else {
|
|
1181
|
+
await (0, commonActions_1.attachLog)(`✅ Select list does not contain "${resolvedExcludedValue}" as expected.`, "text/plain");
|
|
1182
|
+
}
|
|
1183
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText || `Verified select list does not contain: ${resolvedExcludedValue}`, screenshotFullPage);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* Extracts the most relevant text/value/label for a given Playwright Locator element.
|
|
1188
|
+
* Handles input, textarea, innerText, aria-label, title, and placeholder.
|
|
1189
|
+
* Returns a trimmed string for robust matching.
|
|
1190
|
+
*/
|
|
1191
|
+
async function extractElementText(el) {
|
|
1192
|
+
try {
|
|
1193
|
+
const tag = await el.evaluate(e => e.tagName.toLowerCase());
|
|
1194
|
+
if (tag === 'input' || tag === 'textarea') {
|
|
1195
|
+
const value = await el.inputValue().catch(() => "");
|
|
1196
|
+
const placeholder = await el.getAttribute('placeholder').catch(() => "");
|
|
1197
|
+
const ariaLabel = await el.getAttribute('aria-label').catch(() => "");
|
|
1198
|
+
const title = await el.getAttribute('title').catch(() => "");
|
|
1199
|
+
return (value || placeholder || ariaLabel || title || "").trim();
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
const innerText = await el.innerText().catch(() => "");
|
|
1203
|
+
const ariaLabel = await el.getAttribute('aria-label').catch(() => "");
|
|
1204
|
+
const title = await el.getAttribute('title').catch(() => "");
|
|
1205
|
+
return (innerText || ariaLabel || title || "").trim();
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
catch {
|
|
1209
|
+
return "";
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Web: Verify element is present/visible -field: {param} -options: {param}
|
|
1214
|
+
*
|
|
1215
|
+
* Generic presence/visibility check for any element type (button, input, dropdown, text, etc.)
|
|
1216
|
+
* using PlayQ locator system and fieldType, with support for exact/partial match.
|
|
1217
|
+
*
|
|
1218
|
+
* @param page - Playwright Page instance
|
|
1219
|
+
* @param field - The label, text, id, name, or selector of the element to verify
|
|
1220
|
+
* @param options - Optional JSON string or object:
|
|
1221
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", "text", etc.)
|
|
1222
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
1223
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1224
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1225
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1226
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
1227
|
+
* - screenshotText: [string] Screenshot description.
|
|
1228
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1229
|
+
* - unique: [boolean] If true, require exactly one match. Default: false.
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* await web.verifyElementPresent(page, "My Button", { fieldType: "button" });
|
|
1233
|
+
* await web.verifyElementPresent(page, "Search", { fieldType: "input", partialMatch: true });
|
|
1234
|
+
*/
|
|
1235
|
+
async function verifyElementPresent(page, field, options) {
|
|
1236
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1237
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, unique = false, } = options_json;
|
|
1238
|
+
if (!page)
|
|
1239
|
+
throw new Error("Page not initialized");
|
|
1240
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1241
|
+
const target = typeof field === "string"
|
|
1242
|
+
? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout)
|
|
1243
|
+
: field;
|
|
1244
|
+
// Wait for at least one element to be visible and matching (by text or value)
|
|
1245
|
+
const pollInterval = 200;
|
|
1246
|
+
const maxWait = actionTimeout || 5000;
|
|
1247
|
+
let foundIndexes = [];
|
|
1248
|
+
let elapsed = 0;
|
|
1249
|
+
while (elapsed < maxWait) {
|
|
1250
|
+
foundIndexes = [];
|
|
1251
|
+
const count = await target.count();
|
|
1252
|
+
for (let i = 0; i < count; i++) {
|
|
1253
|
+
const el = target.nth(i);
|
|
1254
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1255
|
+
let text = await extractElementText(el);
|
|
1256
|
+
if ((partialMatch && text.includes(field)) ||
|
|
1257
|
+
(!partialMatch && text === field)) {
|
|
1258
|
+
foundIndexes.push(i);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1262
|
+
if ((unique && foundIndexes.length === 1) || (!unique && foundIndexes.length > 0)) {
|
|
1263
|
+
break;
|
|
1264
|
+
}
|
|
1265
|
+
await new Promise(res => setTimeout(res, pollInterval));
|
|
1266
|
+
elapsed += pollInterval;
|
|
1267
|
+
}
|
|
1268
|
+
let pass = false;
|
|
1269
|
+
if (unique) {
|
|
1270
|
+
pass = foundIndexes.length === 1;
|
|
1271
|
+
}
|
|
1272
|
+
else {
|
|
1273
|
+
pass = foundIndexes.length > 0;
|
|
1274
|
+
}
|
|
1275
|
+
if (pass) {
|
|
1276
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) is present and visible. Matches: ${foundIndexes.length}`, "text/plain");
|
|
1277
|
+
}
|
|
1278
|
+
else {
|
|
1279
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) is not visible. Matches: ${foundIndexes.length}`, "text/plain");
|
|
1280
|
+
if (assert !== false) {
|
|
1281
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) is not visible. Matches: ${foundIndexes.length}`);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1285
|
+
}
|
|
1286
|
+
/**
|
|
1287
|
+
* Web: Verify element is NOT present/visible -field: {param} -options: {param}
|
|
1288
|
+
*
|
|
1289
|
+
* Generic absence/invisibility check for any element type (button, input, dropdown, text, etc.)
|
|
1290
|
+
* using PlayQ locator system and fieldType, with support for exact/partial match.
|
|
1291
|
+
*
|
|
1292
|
+
* @param page - Playwright Page instance
|
|
1293
|
+
* @param field - The label, text, id, name, or selector of the element to verify
|
|
1294
|
+
* @param options - Optional JSON string or object:
|
|
1295
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", "text", etc.)
|
|
1296
|
+
* - actionTimeout: [number] Optional timeout in milliseconds. Default: Configured timeout.
|
|
1297
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1298
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1299
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1300
|
+
* - screenshot: [boolean] Capture screenshot. Default: true.
|
|
1301
|
+
* - screenshotText: [string] Screenshot description.
|
|
1302
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1303
|
+
* - unique: [boolean] If true, require exactly one match. Default: false.
|
|
1304
|
+
*
|
|
1305
|
+
* @example
|
|
1306
|
+
* await web.verifyElementNotPresent(page, "My Button", { fieldType: "button" });
|
|
1307
|
+
* await web.verifyElementNotPresent(page, "Search", { fieldType: "input", partialMatch: true });
|
|
1308
|
+
*/
|
|
1309
|
+
async function verifyElementNotPresent(page, field, options) {
|
|
1310
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1311
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true, unique = false, } = options_json;
|
|
1312
|
+
if (!page)
|
|
1313
|
+
throw new Error("Page not initialized");
|
|
1314
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1315
|
+
const target = typeof field === "string"
|
|
1316
|
+
? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout)
|
|
1317
|
+
: field;
|
|
1318
|
+
// Wait for all matching elements to be absent or invisible (with polling)
|
|
1319
|
+
const pollInterval = 200;
|
|
1320
|
+
const maxWait = actionTimeout || 5000;
|
|
1321
|
+
let foundIndexes = [];
|
|
1322
|
+
let elapsed = 0;
|
|
1323
|
+
let pass = false;
|
|
1324
|
+
while (elapsed < maxWait) {
|
|
1325
|
+
foundIndexes = [];
|
|
1326
|
+
const count = await target.count();
|
|
1327
|
+
for (let i = 0; i < count; i++) {
|
|
1328
|
+
const el = target.nth(i);
|
|
1329
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1330
|
+
let text = await extractElementText(el);
|
|
1331
|
+
if ((partialMatch && text.includes(field)) ||
|
|
1332
|
+
(!partialMatch && text === field)) {
|
|
1333
|
+
foundIndexes.push(i);
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
// Only assign pass here, not redeclare
|
|
1338
|
+
if (unique) {
|
|
1339
|
+
pass = foundIndexes.length === 0;
|
|
1340
|
+
}
|
|
1341
|
+
else {
|
|
1342
|
+
pass = foundIndexes.length === 0;
|
|
1343
|
+
}
|
|
1344
|
+
if (pass)
|
|
1345
|
+
break;
|
|
1346
|
+
await new Promise(res => setTimeout(res, pollInterval));
|
|
1347
|
+
elapsed += pollInterval;
|
|
1348
|
+
}
|
|
1349
|
+
if (pass) {
|
|
1350
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) is NOT present/visible. Matches: 0`, "text/plain");
|
|
1351
|
+
}
|
|
1352
|
+
else {
|
|
1353
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) IS present/visible. Matches: ${foundIndexes.length}`, "text/plain");
|
|
1354
|
+
if (assert !== false) {
|
|
1355
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}", partialMatch: ${partialMatch}) IS present/visible. Matches: ${foundIndexes.length}`);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1359
|
+
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Web: Verify element is enabled -field: {param} -options: {param}
|
|
1362
|
+
*
|
|
1363
|
+
* Verifies that the specified element on the page is enabled (not disabled).
|
|
1364
|
+
*
|
|
1365
|
+
* @param page - Playwright Page instance.
|
|
1366
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1367
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1368
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", etc.)
|
|
1369
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1370
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1371
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1372
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1373
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1374
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1375
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1376
|
+
*
|
|
1377
|
+
* @example
|
|
1378
|
+
* await web.verifyElementEnabled(page, "Submit Button", { fieldType: "button" });
|
|
1379
|
+
*
|
|
1380
|
+
*/
|
|
1381
|
+
async function verifyElementEnabled(page, field, options) {
|
|
1382
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1383
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1384
|
+
if (!page)
|
|
1385
|
+
throw new Error("Page not initialized");
|
|
1386
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1387
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1388
|
+
const count = await target.count();
|
|
1389
|
+
let enabled = false;
|
|
1390
|
+
for (let i = 0; i < count; i++) {
|
|
1391
|
+
const el = target.nth(i);
|
|
1392
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1393
|
+
let text = await extractElementText(el);
|
|
1394
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1395
|
+
enabled = await el.isEnabled();
|
|
1396
|
+
if (enabled)
|
|
1397
|
+
break;
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
if (enabled) {
|
|
1402
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") is enabled.`, "text/plain");
|
|
1403
|
+
}
|
|
1404
|
+
else {
|
|
1405
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") is not enabled.`, "text/plain");
|
|
1406
|
+
if (assert !== false)
|
|
1407
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") is not enabled.`);
|
|
1408
|
+
}
|
|
1409
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Web: Verify element is disabled -field: {param} -options: {param}
|
|
1413
|
+
*
|
|
1414
|
+
* Verifies that the specified element on the page is disabled (not enabled).
|
|
1415
|
+
*
|
|
1416
|
+
* @param page - Playwright Page instance.
|
|
1417
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1418
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1419
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", etc.)
|
|
1420
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1421
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1422
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1423
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1424
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1425
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1426
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1427
|
+
*
|
|
1428
|
+
* @example
|
|
1429
|
+
* await web.verifyElementDisabled(page, "Submit Button", { fieldType: "button" });
|
|
1430
|
+
*
|
|
1431
|
+
*/
|
|
1432
|
+
async function verifyElementDisabled(page, field, options) {
|
|
1433
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1434
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1435
|
+
if (!page)
|
|
1436
|
+
throw new Error("Page not initialized");
|
|
1437
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1438
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1439
|
+
const count = await target.count();
|
|
1440
|
+
let disabled = false;
|
|
1441
|
+
for (let i = 0; i < count; i++) {
|
|
1442
|
+
const el = target.nth(i);
|
|
1443
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1444
|
+
let text = await extractElementText(el);
|
|
1445
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1446
|
+
disabled = !(await el.isEnabled());
|
|
1447
|
+
if (disabled)
|
|
1448
|
+
break;
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (disabled) {
|
|
1453
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") is disabled.`, "text/plain");
|
|
1454
|
+
}
|
|
1455
|
+
else {
|
|
1456
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") is not disabled.`, "text/plain");
|
|
1457
|
+
if (assert !== false)
|
|
1458
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") is not disabled.`);
|
|
1459
|
+
}
|
|
1460
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Web: Verify element is selected -field: {param} -options: {param}
|
|
1464
|
+
*
|
|
1465
|
+
* Verifies that the specified element on the page is selected (e.g., checkbox, radio button, option).
|
|
1466
|
+
*
|
|
1467
|
+
* @param page - Playwright Page instance.
|
|
1468
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1469
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1470
|
+
* - fieldType: [string] Type of element (e.g., "checkbox", "radio", "option", etc.)
|
|
1471
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1472
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1473
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1474
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1475
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1476
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1477
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1478
|
+
*
|
|
1479
|
+
*
|
|
1480
|
+
* @example
|
|
1481
|
+
* await web.verifyElementSelected(page, "Accept Terms", { fieldType: "checkbox" });
|
|
1482
|
+
*
|
|
1483
|
+
*/
|
|
1484
|
+
async function verifyElementSelected(page, field, options) {
|
|
1485
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1486
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1487
|
+
if (!page)
|
|
1488
|
+
throw new Error("Page not initialized");
|
|
1489
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1490
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1491
|
+
const count = await target.count();
|
|
1492
|
+
let selected = false;
|
|
1493
|
+
for (let i = 0; i < count; i++) {
|
|
1494
|
+
const el = target.nth(i);
|
|
1495
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1496
|
+
let text = await extractElementText(el);
|
|
1497
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1498
|
+
// Try aria-selected, checked, or selected attribute
|
|
1499
|
+
const ariaSelected = await el.getAttribute("aria-selected");
|
|
1500
|
+
const checked = await el.getAttribute("checked");
|
|
1501
|
+
const selectedAttr = await el.getAttribute("selected");
|
|
1502
|
+
if (ariaSelected === "true" || checked === "true" || selectedAttr === "true") {
|
|
1503
|
+
selected = true;
|
|
1504
|
+
break;
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
if (selected) {
|
|
1510
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") is selected.`, "text/plain");
|
|
1511
|
+
}
|
|
1512
|
+
else {
|
|
1513
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") is not selected.`, "text/plain");
|
|
1514
|
+
if (assert !== false)
|
|
1515
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") is not selected.`);
|
|
1516
|
+
}
|
|
1517
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1518
|
+
}
|
|
1519
|
+
/**
|
|
1520
|
+
*
|
|
1521
|
+
* Web: Verify element has attribute -field: {param} -attribute: {param} -value: {param} -options: {param}
|
|
1522
|
+
*
|
|
1523
|
+
* Verifies that the specified element on the page has the given attribute with the expected value.
|
|
1524
|
+
*
|
|
1525
|
+
* @param page - Playwright Page instance.
|
|
1526
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1527
|
+
* @param attribute - The attribute name to check (e.g., "href", "src", "alt", etc.).
|
|
1528
|
+
* @param expectedValue - The expected value of the attribute.
|
|
1529
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1530
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", etc.)
|
|
1531
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1532
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1533
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1534
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1535
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1536
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1537
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1538
|
+
*
|
|
1539
|
+
* @example
|
|
1540
|
+
* await web.verifyElementHasAttribute(page, "My Link", "href", "https://example.com", { fieldType: "link" });
|
|
1541
|
+
*
|
|
1542
|
+
*/
|
|
1543
|
+
async function verifyElementHasAttribute(page, field, attribute, expectedValue, options) {
|
|
1544
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1545
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1546
|
+
if (!page)
|
|
1547
|
+
throw new Error("Page not initialized");
|
|
1548
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1549
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1550
|
+
const count = await target.count();
|
|
1551
|
+
let found = false;
|
|
1552
|
+
for (let i = 0; i < count; i++) {
|
|
1553
|
+
const el = target.nth(i);
|
|
1554
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1555
|
+
let text = await extractElementText(el);
|
|
1556
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1557
|
+
const attrVal = await el.getAttribute(attribute);
|
|
1558
|
+
if (attrVal === expectedValue) {
|
|
1559
|
+
found = true;
|
|
1560
|
+
break;
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
}
|
|
1565
|
+
if (found) {
|
|
1566
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") has attribute ${attribute}="${expectedValue}".`, "text/plain");
|
|
1567
|
+
}
|
|
1568
|
+
else {
|
|
1569
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") does not have attribute ${attribute}="${expectedValue}".`, "text/plain");
|
|
1570
|
+
if (assert !== false)
|
|
1571
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") does not have attribute ${attribute}="${expectedValue}".`);
|
|
1572
|
+
}
|
|
1573
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1574
|
+
}
|
|
1575
|
+
/**
|
|
1576
|
+
* Web: Verify element count -field: {param} -expectedCount: {param} -options: {param}
|
|
1577
|
+
*
|
|
1578
|
+
* Verifies that the count of specified elements on the page matches the expected count.
|
|
1579
|
+
*
|
|
1580
|
+
* @param page - Playwright Page instance.
|
|
1581
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1582
|
+
* @param expectedCount - The expected number of elements to be present.
|
|
1583
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1584
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", etc.)
|
|
1585
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1586
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1587
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1588
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1589
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1590
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1591
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1592
|
+
*
|
|
1593
|
+
*
|
|
1594
|
+
* @example
|
|
1595
|
+
* await web.verifyElementCount(page, "Item", 5, { fieldType: "text" });
|
|
1596
|
+
*
|
|
1597
|
+
*
|
|
1598
|
+
*/
|
|
1599
|
+
async function verifyElementCount(page, field, expectedCount, options) {
|
|
1600
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1601
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1602
|
+
if (!page)
|
|
1603
|
+
throw new Error("Page not initialized");
|
|
1604
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1605
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1606
|
+
const count = await target.count();
|
|
1607
|
+
let matchCount = 0;
|
|
1608
|
+
for (let i = 0; i < count; i++) {
|
|
1609
|
+
const el = target.nth(i);
|
|
1610
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1611
|
+
let text = await extractElementText(el);
|
|
1612
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1613
|
+
matchCount++;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
if (matchCount === expectedCount) {
|
|
1618
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") count matches expected: ${expectedCount}.`, "text/plain");
|
|
1619
|
+
}
|
|
1620
|
+
else {
|
|
1621
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") count ${matchCount} does not match expected: ${expectedCount}.`, "text/plain");
|
|
1622
|
+
if (assert !== false)
|
|
1623
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") count ${matchCount} does not match expected: ${expectedCount}.`);
|
|
1624
|
+
}
|
|
1625
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1626
|
+
}
|
|
1627
|
+
/**
|
|
1628
|
+
*
|
|
1629
|
+
|
|
1630
|
+
/**
|
|
1631
|
+
* Web: Verify element order -field: {param} -expectedOrder: {param} -options: {param}
|
|
1632
|
+
*
|
|
1633
|
+
* Verifies that the order of elements of a specified type on the page matches the expected order.
|
|
1634
|
+
*
|
|
1635
|
+
* @param page - Playwright Page instance.
|
|
1636
|
+
* @param field - The locator, label, text, id, name, or selector of the elements to verify (string or Locator).
|
|
1637
|
+
* @param expectedOrder - An array of expected element texts in the correct order.
|
|
1638
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1639
|
+
* - fieldType: [string] The type of elements to verify (e.g., "text", "button", "item", etc.).
|
|
1640
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1641
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1642
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1643
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1644
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1645
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1646
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1647
|
+
*
|
|
1648
|
+
* @example
|
|
1649
|
+
* // Using a string field (label or logical type)
|
|
1650
|
+
* await web.verifyElementOrder(page, "Phase", ["Draft", "Review", "Approved"], { fieldType: "phase", partialMatch: false });
|
|
1651
|
+
*
|
|
1652
|
+
* // Using a Playwright Locator (e.g., all visible rows in a table)
|
|
1653
|
+
* const rows = page.locator('.my-table-row');
|
|
1654
|
+
* await web.verifyElementOrder(page, rows, ["Row 1", "Row 2", "Row 3"]);
|
|
1655
|
+
*/
|
|
1656
|
+
async function verifyElementOrder(page, field, expectedOrder, options) {
|
|
1657
|
+
var _a;
|
|
1658
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1659
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1660
|
+
if (!page)
|
|
1661
|
+
throw new Error("Page not initialized");
|
|
1662
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1663
|
+
const target = typeof field === "string"
|
|
1664
|
+
? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout)
|
|
1665
|
+
: field;
|
|
1666
|
+
const count = await target.count();
|
|
1667
|
+
let actualOrder = [];
|
|
1668
|
+
for (let i = 0; i < count; i++) {
|
|
1669
|
+
const el = target.nth(i);
|
|
1670
|
+
if (await el.isVisible()) {
|
|
1671
|
+
let text = await extractElementText(el);
|
|
1672
|
+
actualOrder.push(text);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1675
|
+
let matches = true;
|
|
1676
|
+
if (partialMatch) {
|
|
1677
|
+
for (let i = 0; i < expectedOrder.length; i++) {
|
|
1678
|
+
if (!((_a = actualOrder[i]) === null || _a === void 0 ? void 0 : _a.includes(expectedOrder[i]))) {
|
|
1679
|
+
matches = false;
|
|
1680
|
+
break;
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
}
|
|
1684
|
+
else {
|
|
1685
|
+
matches = JSON.stringify(actualOrder) === JSON.stringify(expectedOrder);
|
|
1686
|
+
}
|
|
1687
|
+
if (matches) {
|
|
1688
|
+
await (0, commonActions_1.attachLog)(`✅ Element order matches expected.`, "text/plain");
|
|
1689
|
+
}
|
|
1690
|
+
else {
|
|
1691
|
+
await (0, commonActions_1.attachLog)(`❌ Element order does not match expected. Actual: ${JSON.stringify(actualOrder)}, Expected: ${JSON.stringify(expectedOrder)}`, "text/plain");
|
|
1692
|
+
if (assert !== false)
|
|
1693
|
+
throw new Error(`❌ Element order does not match expected.`);
|
|
1694
|
+
}
|
|
1695
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1696
|
+
}
|
|
1697
|
+
/**
|
|
1698
|
+
* Web: Verify element is in viewport -field: {param} -options: {param}
|
|
1699
|
+
*
|
|
1700
|
+
* Verifies that the specified element on the page is within the visible viewport.
|
|
1701
|
+
*
|
|
1702
|
+
* @param page - Playwright Page instance.
|
|
1703
|
+
* @param field - The label, text, id, name, or selector of the element to verify.
|
|
1704
|
+
* @param options - Optional settings for the verification action. Can be a JSON string or an object:
|
|
1705
|
+
* - fieldType: [string] Type of element (e.g., "button", "input", "dropdown", etc.)
|
|
1706
|
+
* - actionTimeout: [number] Timeout in milliseconds to wait for page load. Default: Configured timeout.
|
|
1707
|
+
* - pattern: [string] Optional pattern to refine element search.
|
|
1708
|
+
* - partialMatch: [boolean] If true, allows substring match. Default: false (exact match).
|
|
1709
|
+
* - assert: [boolean] If false, logs the failure but does not throw. Default: true.
|
|
1710
|
+
* - screenshot: [boolean] Capture a screenshot. Default: true.
|
|
1711
|
+
* - screenshotText: [string] Description for the screenshot.
|
|
1712
|
+
* - screenshotFullPage: [boolean] Capture full page screenshot. Default: true.
|
|
1713
|
+
*
|
|
1714
|
+
* @example
|
|
1715
|
+
* await web.verifyElementInViewport(page, "Submit Button", { fieldType: "button" });
|
|
1716
|
+
*
|
|
1717
|
+
*
|
|
1718
|
+
*/
|
|
1719
|
+
async function verifyElementInViewport(page, field, options) {
|
|
1720
|
+
const options_json = typeof options === "string" ? (0, vars_1.parseLooseJson)(options) : options || {};
|
|
1721
|
+
const { fieldType = "", actionTimeout = Number(global_1.vars.getConfigValue("testExecution.actionTimeout")), pattern, partialMatch = false, assert = true, screenshot = true, screenshotText = "", screenshotFullPage = true } = options_json;
|
|
1722
|
+
if (!page)
|
|
1723
|
+
throw new Error("Page not initialized");
|
|
1724
|
+
await (0, waitActions_1.waitForPageToLoad)(page, actionTimeout);
|
|
1725
|
+
const target = typeof field === "string" ? await (0, global_1.webLocResolver)(fieldType, field, page, pattern, actionTimeout) : field;
|
|
1726
|
+
const count = await target.count();
|
|
1727
|
+
let inViewport = false;
|
|
1728
|
+
for (let i = 0; i < count; i++) {
|
|
1729
|
+
const el = target.nth(i);
|
|
1730
|
+
if (await el.isVisible() && typeof field === 'string') {
|
|
1731
|
+
let text = await extractElementText(el);
|
|
1732
|
+
if ((partialMatch && text.includes(field)) || (!partialMatch && text === field)) {
|
|
1733
|
+
inViewport = await el.evaluate((node) => {
|
|
1734
|
+
const rect = node.getBoundingClientRect();
|
|
1735
|
+
return (rect.top >= 0 &&
|
|
1736
|
+
rect.left >= 0 &&
|
|
1737
|
+
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
|
|
1738
|
+
rect.right <= (window.innerWidth || document.documentElement.clientWidth));
|
|
1739
|
+
});
|
|
1740
|
+
if (inViewport)
|
|
1741
|
+
break;
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
if (inViewport) {
|
|
1746
|
+
await (0, commonActions_1.attachLog)(`✅ Element (type: "${fieldType}", field: "${field}") is in viewport.`, "text/plain");
|
|
1747
|
+
}
|
|
1748
|
+
else {
|
|
1749
|
+
await (0, commonActions_1.attachLog)(`❌ Element (type: "${fieldType}", field: "${field}") is not in viewport.`, "text/plain");
|
|
1750
|
+
if (assert !== false)
|
|
1751
|
+
throw new Error(`❌ Element (type: "${fieldType}", field: "${field}") is not in viewport.`);
|
|
1752
|
+
}
|
|
1753
|
+
await (0, screenshotActions_1.processScreenshot)(page, screenshot, screenshotText, screenshotFullPage);
|
|
1754
|
+
}
|