@zohodesk/testinglibrary 0.1.9-exp-actors → 0.1.12-experimental

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.
Files changed (241) hide show
  1. package/.babelrc +4 -2
  2. package/.claude/settings.local.json +14 -0
  3. package/.gitlab-ci.yml +206 -0
  4. package/README.md +264 -1
  5. package/build/common/data-generator/steps/DataGenerator.spec.js +19 -0
  6. package/build/common/data-generator/steps/DataGeneratorStepsHelper.js +21 -0
  7. package/build/common/multi-actor/steps/multiActorHandling.spec.js +26 -0
  8. package/build/common/searchFake/helpers/rpcRequestHelper.js +52 -0
  9. package/build/common/searchFake/steps/searchFake.spec.js +85 -0
  10. package/build/core/dataGenerator/DataGenerator.js +161 -0
  11. package/build/core/dataGenerator/DataGeneratorError.js +60 -0
  12. package/build/core/dataGenerator/DataGeneratorHelper.js +121 -0
  13. package/build/core/dataGenerator/authenticator/Authenticator.js +37 -0
  14. package/build/core/dataGenerator/authenticator/CookieAuthenticator.js +48 -0
  15. package/build/core/dataGenerator/authenticator/JWTauthenticator.js +59 -0
  16. package/build/core/dataGenerator/authenticator/OAuthAuthenticator.js +26 -0
  17. package/build/core/dataGenerator/authenticator/OrgOAuthAuthenticator.js +26 -0
  18. package/build/core/dataGenerator/authenticator/cookieAuthConfig.js +11 -0
  19. package/build/core/jest/preprocessor/jsPreprocessor.js +2 -7
  20. package/build/core/jest/setup/index.js +1 -7
  21. package/build/core/playwright/builtInFixtures/actorContext.js +78 -0
  22. package/build/core/playwright/builtInFixtures/caseTimeout.js +20 -0
  23. package/build/core/playwright/builtInFixtures/context.js +34 -16
  24. package/build/core/playwright/builtInFixtures/executionContext.js +17 -0
  25. package/build/core/playwright/builtInFixtures/i18N.js +8 -0
  26. package/build/core/playwright/builtInFixtures/index.js +7 -1
  27. package/build/core/playwright/builtInFixtures/page.js +22 -84
  28. package/build/core/playwright/clear-caches.js +17 -5
  29. package/build/core/playwright/codegen.js +4 -21
  30. package/build/core/playwright/configuration/Configuration.js +25 -0
  31. package/build/core/playwright/configuration/ConfigurationHelper.js +45 -0
  32. package/build/core/playwright/configuration/UserArgs.js +12 -0
  33. package/build/core/playwright/constants/configConstants.js +17 -0
  34. package/build/core/playwright/constants/failureTagConstants.js +17 -0
  35. package/build/core/playwright/constants/fileMutexConfig.js +9 -0
  36. package/build/core/playwright/constants/reporterConstants.js +20 -0
  37. package/build/core/playwright/constants/retryConstants.js +8 -0
  38. package/build/core/playwright/custom-commands.js +1 -1
  39. package/build/core/playwright/env-initializer.js +26 -7
  40. package/build/core/playwright/fixtures.js +24 -0
  41. package/build/core/playwright/helpers/additionalProfiles.js +25 -0
  42. package/build/core/playwright/helpers/auth/accountLogin.js +4 -1
  43. package/build/core/playwright/helpers/auth/checkAuthCookies.js +20 -19
  44. package/build/core/playwright/helpers/auth/getUsers.js +57 -49
  45. package/build/core/playwright/helpers/auth/index.js +14 -1
  46. package/build/core/playwright/helpers/auth/loginDefaultStepsHelper.js +62 -0
  47. package/build/core/playwright/helpers/auth/loginSteps.js +40 -22
  48. package/build/core/playwright/helpers/browserTimeoutFactor.js +16 -0
  49. package/build/core/playwright/helpers/caseTimeoutResolver.js +37 -0
  50. package/build/core/playwright/helpers/checkAuthDirectory.js +27 -0
  51. package/build/core/playwright/helpers/configFileNameProvider.js +21 -7
  52. package/build/core/playwright/helpers/configPathResolver.js +38 -0
  53. package/build/core/playwright/helpers/contextFailureHandler.js +81 -0
  54. package/build/core/playwright/helpers/customFixturesHelper.js +58 -0
  55. package/build/core/playwright/helpers/failureTagClassifier.js +197 -0
  56. package/build/core/playwright/helpers/fileMutex.js +71 -0
  57. package/build/core/playwright/helpers/logCollector.js +147 -0
  58. package/build/core/playwright/helpers/parseUserArgs.js +2 -3
  59. package/build/core/playwright/helpers/runtimeLogAnnotator.js +140 -0
  60. package/build/core/playwright/helpers/runtimeLogPath.js +61 -0
  61. package/build/core/playwright/helpers/runtimeLogReader.js +54 -0
  62. package/build/core/playwright/helpers/thirdPartyLib.js +13 -0
  63. package/build/core/playwright/index.js +8 -88
  64. package/build/core/playwright/patterns/casePatterns.js +9 -0
  65. package/build/core/playwright/patterns/codePatterns.js +9 -0
  66. package/build/core/playwright/patterns/environmentPatterns.js +15 -0
  67. package/build/core/playwright/patterns/index.js +33 -0
  68. package/build/core/playwright/patterns/logCollectorIgnorePatterns.js +15 -0
  69. package/build/core/playwright/patterns/toolPatterns.js +26 -0
  70. package/build/core/playwright/readConfigFile.js +49 -16
  71. package/build/core/playwright/reporter/PlaywrightReporter.js +58 -0
  72. package/build/core/playwright/reporter/Reporter.js +65 -0
  73. package/build/core/playwright/reporter/ShardReporter.js +58 -0
  74. package/build/core/playwright/reporter/UnitReporter.js +27 -0
  75. package/build/core/playwright/reporter/helpers/mergeAbortedTests.js +78 -0
  76. package/build/core/playwright/runner/Runner.js +22 -0
  77. package/build/core/playwright/runner/RunnerHelper.js +43 -0
  78. package/build/core/playwright/runner/RunnerTypes.js +17 -0
  79. package/build/core/playwright/runner/SpawnRunner.js +93 -0
  80. package/build/core/playwright/setup/Project.js +35 -0
  81. package/build/core/playwright/setup/ProjectConfiguration.js +66 -0
  82. package/build/core/playwright/setup/config-creator.js +58 -40
  83. package/build/core/playwright/setup/config-utils.js +68 -37
  84. package/build/core/playwright/setup/custom-reporter.js +137 -14
  85. package/build/core/playwright/setup/merge-config.js +32 -0
  86. package/build/core/playwright/setup/qc-custom-reporter.js +342 -0
  87. package/build/core/playwright/spawnInheritChild.js +71 -0
  88. package/build/core/playwright/tagProcessor.js +69 -0
  89. package/build/core/playwright/test-runner.js +44 -97
  90. package/build/core/playwright/types.js +4 -1
  91. package/build/core/playwright/validateFeature.js +28 -0
  92. package/build/decorators.d.ts +1 -1
  93. package/build/decorators.js +1 -1
  94. package/build/index.d.ts +2 -22
  95. package/build/index.js +12 -2
  96. package/build/lib/cli.js +42 -7
  97. package/build/setup-folder-structure/helper.js +2 -0
  98. package/build/setup-folder-structure/samples/accountLogin-sample.js +19 -0
  99. package/build/setup-folder-structure/samples/actors-index.js +2 -0
  100. package/build/setup-folder-structure/samples/auth-setup-sample.js +10 -66
  101. package/build/setup-folder-structure/samples/editions-index.js +3 -0
  102. package/build/setup-folder-structure/samples/free-sample.json +25 -0
  103. package/build/setup-folder-structure/samples/settings.json +7 -0
  104. package/build/setup-folder-structure/samples/testSetup-sample.js +14 -0
  105. package/build/setup-folder-structure/samples/uat-config-sample.js +7 -2
  106. package/build/setup-folder-structure/setupProject.js +23 -5
  107. package/build/test/core/dataGenerator/__tests__/DataGenerator.test.js +311 -0
  108. package/build/test/core/dataGenerator/__tests__/DataGeneratorHelper.test.js +204 -0
  109. package/build/test/core/dataGenerator/__tests__/DataGeneratorResolution.test.js +126 -0
  110. package/build/test/core/dataGenerator/authenticator/__tests__/Authenticator.test.js +88 -0
  111. package/build/test/core/dataGenerator/authenticator/__tests__/JWTauthenticator.test.js +136 -0
  112. package/build/test/core/dataGenerator/authenticator/__tests__/OAuthAuthenticator.test.js +39 -0
  113. package/build/test/core/dataGenerator/authenticator/__tests__/OrgOAuthAuthenticator.test.js +39 -0
  114. package/build/test/core/playwright/__tests__/spawnInheritChild.test.js +148 -0
  115. package/build/test/core/playwright/__tests__/tagProcessor.test.js +94 -0
  116. package/build/test/core/playwright/__tests__/validateFeature.test.js +72 -0
  117. package/build/test/core/playwright/buildInFixtures/__tests__/caseTimeout.test.js +96 -0
  118. package/build/test/core/playwright/buildInFixtures/__tests__/executionContext.test.js +27 -0
  119. package/build/test/core/playwright/configuration/__tests__/Configuration.test.js +53 -0
  120. package/build/test/core/playwright/helpers/__tests__/additionalProfiles.test.js +45 -0
  121. package/build/test/core/playwright/helpers/__tests__/configFileNameProvider.test.js +75 -0
  122. package/build/test/core/playwright/helpers/__tests__/configPathResolver.test.js +55 -0
  123. package/build/test/core/playwright/helpers/__tests__/customFixturesHelper.test.js +51 -0
  124. package/build/test/core/playwright/helpers/__tests__/failureTagClassifier.test.js +604 -0
  125. package/build/test/core/playwright/helpers/__tests__/fileMutex.test.js +79 -0
  126. package/build/test/core/playwright/helpers/__tests__/getUsers_ListOfActors.test.js +83 -0
  127. package/build/test/core/playwright/helpers/__tests__/logCollector.test.js +163 -0
  128. package/build/test/core/playwright/helpers/__tests__/runtimeLogReader.test.js +112 -0
  129. package/build/test/core/playwright/helpers/auth/__tests__/checkAuthCookies.test.js +92 -0
  130. package/build/test/core/playwright/runner/__tests__/RunnerHelper.test.js +19 -0
  131. package/build/test/core/playwright/runner/__tests__/SpawnRunner.test.js +30 -0
  132. package/build/utils/cliArgsToObject.js +3 -0
  133. package/build/utils/commonUtils.js +20 -0
  134. package/build/utils/fileUtils.js +43 -1
  135. package/build/utils/logger.js +1 -30
  136. package/changelog.md +23 -0
  137. package/docs/CODE-REVIEW-AGENT.md +399 -0
  138. package/docs/code-review-instructions.md +157 -0
  139. package/jest.config.js +29 -11
  140. package/npm-shrinkwrap.json +14994 -4793
  141. package/package.json +39 -28
  142. package/playwright.config.js +13 -57
  143. package/unit_reports/unit-report.html +277 -0
  144. package/build/bdd-framework/cli/commands/env.js +0 -42
  145. package/build/bdd-framework/cli/commands/export.js +0 -47
  146. package/build/bdd-framework/cli/commands/test.js +0 -64
  147. package/build/bdd-framework/cli/index.js +0 -11
  148. package/build/bdd-framework/cli/options.js +0 -19
  149. package/build/bdd-framework/cli/worker.js +0 -13
  150. package/build/bdd-framework/config/configDir.js +0 -35
  151. package/build/bdd-framework/config/enrichReporterData.js +0 -23
  152. package/build/bdd-framework/config/env.js +0 -50
  153. package/build/bdd-framework/config/index.js +0 -94
  154. package/build/bdd-framework/config/lang.js +0 -14
  155. package/build/bdd-framework/cucumber/buildStepDefinition.js +0 -43
  156. package/build/bdd-framework/cucumber/createTestStep.js +0 -43
  157. package/build/bdd-framework/cucumber/formatter/EventDataCollector.js +0 -126
  158. package/build/bdd-framework/cucumber/formatter/GherkinDocumentParser.js +0 -72
  159. package/build/bdd-framework/cucumber/formatter/PickleParser.js +0 -25
  160. package/build/bdd-framework/cucumber/formatter/durationHelpers.js +0 -13
  161. package/build/bdd-framework/cucumber/formatter/getColorFns.js +0 -57
  162. package/build/bdd-framework/cucumber/formatter/index.js +0 -16
  163. package/build/bdd-framework/cucumber/formatter/locationHelpers.js +0 -16
  164. package/build/bdd-framework/cucumber/loadConfig.js +0 -17
  165. package/build/bdd-framework/cucumber/loadFeatures.js +0 -70
  166. package/build/bdd-framework/cucumber/loadSnippetBuilder.js +0 -20
  167. package/build/bdd-framework/cucumber/loadSteps.js +0 -47
  168. package/build/bdd-framework/cucumber/resolveFeaturePaths.js +0 -62
  169. package/build/bdd-framework/cucumber/stepArguments.js +0 -21
  170. package/build/bdd-framework/cucumber/types.js +0 -5
  171. package/build/bdd-framework/cucumber/valueChecker.js +0 -23
  172. package/build/bdd-framework/decorators.js +0 -18
  173. package/build/bdd-framework/gen/fixtures.js +0 -48
  174. package/build/bdd-framework/gen/formatter.js +0 -123
  175. package/build/bdd-framework/gen/i18n.js +0 -39
  176. package/build/bdd-framework/gen/index.js +0 -185
  177. package/build/bdd-framework/gen/testFile.js +0 -465
  178. package/build/bdd-framework/gen/testMeta.js +0 -60
  179. package/build/bdd-framework/gen/testNode.js +0 -60
  180. package/build/bdd-framework/gen/testPoms.js +0 -133
  181. package/build/bdd-framework/hooks/scenario.js +0 -130
  182. package/build/bdd-framework/hooks/worker.js +0 -89
  183. package/build/bdd-framework/index.js +0 -52
  184. package/build/bdd-framework/playwright/fixtureParameterNames.js +0 -93
  185. package/build/bdd-framework/playwright/getLocationInFile.js +0 -79
  186. package/build/bdd-framework/playwright/loadConfig.js +0 -42
  187. package/build/bdd-framework/playwright/loadUtils.js +0 -33
  188. package/build/bdd-framework/playwright/testTypeImpl.js +0 -61
  189. package/build/bdd-framework/playwright/transform.js +0 -88
  190. package/build/bdd-framework/playwright/types.js +0 -5
  191. package/build/bdd-framework/playwright/utils.js +0 -34
  192. package/build/bdd-framework/reporter/cucumber/base.js +0 -57
  193. package/build/bdd-framework/reporter/cucumber/custom.js +0 -73
  194. package/build/bdd-framework/reporter/cucumber/helper.js +0 -12
  195. package/build/bdd-framework/reporter/cucumber/html.js +0 -35
  196. package/build/bdd-framework/reporter/cucumber/index.js +0 -74
  197. package/build/bdd-framework/reporter/cucumber/json.js +0 -312
  198. package/build/bdd-framework/reporter/cucumber/junit.js +0 -205
  199. package/build/bdd-framework/reporter/cucumber/message.js +0 -20
  200. package/build/bdd-framework/reporter/cucumber/messagesBuilder/AttachmentMapper.js +0 -64
  201. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Builder.js +0 -196
  202. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocument.js +0 -43
  203. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocumentClone.js +0 -52
  204. package/build/bdd-framework/reporter/cucumber/messagesBuilder/GherkinDocuments.js +0 -105
  205. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Hook.js +0 -70
  206. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Meta.js +0 -45
  207. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Pickles.js +0 -27
  208. package/build/bdd-framework/reporter/cucumber/messagesBuilder/Projects.js +0 -38
  209. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCase.js +0 -128
  210. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRun.js +0 -126
  211. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestCaseRunHooks.js +0 -102
  212. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepAttachments.js +0 -50
  213. package/build/bdd-framework/reporter/cucumber/messagesBuilder/TestStepRun.js +0 -88
  214. package/build/bdd-framework/reporter/cucumber/messagesBuilder/index.js +0 -30
  215. package/build/bdd-framework/reporter/cucumber/messagesBuilder/pwUtils.js +0 -51
  216. package/build/bdd-framework/reporter/cucumber/messagesBuilder/timing.js +0 -35
  217. package/build/bdd-framework/reporter/cucumber/messagesBuilder/types.js +0 -5
  218. package/build/bdd-framework/run/StepInvoker.js +0 -68
  219. package/build/bdd-framework/run/bddDataAttachment.js +0 -46
  220. package/build/bdd-framework/run/bddFixtures.js +0 -191
  221. package/build/bdd-framework/run/bddWorld.js +0 -79
  222. package/build/bdd-framework/run/bddWorldInternal.js +0 -15
  223. package/build/bdd-framework/snippets/index.js +0 -132
  224. package/build/bdd-framework/snippets/snippetSyntax.js +0 -43
  225. package/build/bdd-framework/snippets/snippetSyntaxDecorators.js +0 -26
  226. package/build/bdd-framework/snippets/snippetSyntaxTs.js +0 -18
  227. package/build/bdd-framework/stepDefinitions/createBdd.js +0 -66
  228. package/build/bdd-framework/stepDefinitions/decorators/class.js +0 -68
  229. package/build/bdd-framework/stepDefinitions/decorators/steps.js +0 -99
  230. package/build/bdd-framework/stepDefinitions/defineStep.js +0 -62
  231. package/build/bdd-framework/stepDefinitions/stepConfig.js +0 -24
  232. package/build/bdd-framework/utils/AutofillMap.js +0 -20
  233. package/build/bdd-framework/utils/exit.js +0 -62
  234. package/build/bdd-framework/utils/index.js +0 -93
  235. package/build/bdd-framework/utils/jsStringWrap.js +0 -44
  236. package/build/bdd-framework/utils/logger.js +0 -30
  237. package/build/bdd-framework/utils/stripAnsiEscapes.js +0 -20
  238. package/build/core/playwright/report-generator.js +0 -42
  239. package/build/core/playwright/tag-processor.js +0 -68
  240. package/build/setup-folder-structure/samples/authUsers-sample.json +0 -9
  241. package/build/setup-folder-structure/samples/env-config-sample.json +0 -21
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _test = require("@playwright/test");
5
+ var _playwrightBdd = require("playwright-bdd");
6
+ var _readConfigFile = require("./readConfigFile");
7
+ var _builtInFixtures = _interopRequireDefault(require("./builtInFixtures"));
8
+ var _getUserFixtures = _interopRequireDefault(require("./helpers/getUserFixtures"));
9
+ const {
10
+ bddMode
11
+ } = (0, _readConfigFile.generateConfigFromFile)();
12
+ let base = bddMode ? _playwrightBdd.test : _test.test;
13
+ const buildInFixtures = (0, _builtInFixtures.default)(bddMode);
14
+ const buildInFixturesTest = base.extend({
15
+ ...buildInFixtures
16
+ });
17
+ const userFixtures = (0, _getUserFixtures.default)();
18
+ const userFixturesTest = base.extend({
19
+ ...userFixtures
20
+ });
21
+ const test = (0, _test.mergeTests)(buildInFixturesTest, userFixturesTest);
22
+ module.exports = {
23
+ test
24
+ };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.additionProfiles = additionProfiles;
7
+ var _getUsers = require("./auth/getUsers");
8
+ var _customFixturesHelper = require("./customFixturesHelper");
9
+ function additionProfiles(tags) {
10
+ const {
11
+ editionInfo,
12
+ betaFeature,
13
+ portalInfo
14
+ } = (0, _customFixturesHelper.extractTagInfo)(tags);
15
+ const additionalProfileTags = tags.filter(tag => tag.startsWith('@additional_profile_'));
16
+ let additionalProfileActors = {};
17
+ if (additionalProfileTags.length > 0) {
18
+ additionalProfileTags.forEach(tag => {
19
+ const additionalProfile = tag.replace('@additional_profile_', '');
20
+ const actorDetails = (0, _getUsers.getUserForSelectedEditionAndProfile)(editionInfo, additionalProfile, betaFeature, portalInfo);
21
+ additionalProfileActors[additionalProfile] = actorDetails;
22
+ });
23
+ }
24
+ return additionalProfileActors;
25
+ }
@@ -13,6 +13,9 @@ async function accountLogin(page, useremail, password) {
13
13
  await page.locator('#nextbtn').click();
14
14
  const domainUrlOrigin = (0, _getUrlOrigin.default)(process.env.domain);
15
15
  await page.waitForNavigation();
16
- await Promise.race([page.waitForURL(`${domainUrlOrigin}/**`), page.waitForURL('**/announcement/**')]);
16
+ if (!page.url().includes(domainUrlOrigin)) {
17
+ await page.goto(domainUrlOrigin);
18
+ }
19
+ await page.waitForURL(`${domainUrlOrigin}/**`);
17
20
  }
18
21
  var _default = exports.default = accountLogin;
@@ -6,15 +6,16 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.getAuthFileDirectory = getAuthFileDirectory;
8
8
  exports.loadCookiesIfPresent = loadCookiesIfPresent;
9
+ exports.storeFilteredStorageState = storeFilteredStorageState;
9
10
  exports.verifyIfCookieFileExists = verifyIfCookieFileExists;
10
11
  var _path = _interopRequireDefault(require("path"));
11
12
  var _fs = require("fs");
12
13
  var _readConfigFile = require("../../readConfigFile");
14
+ var _fileUtils = require("../../../../utils/fileUtils");
15
+ var _logger = require("../../../../utils/logger");
13
16
  /* eslint-disable no-console */
14
17
 
15
- const authContent = {
16
- cookies: []
17
- };
18
+ const authCookieNameKeys = ['iamadt', 'iambdt'];
18
19
  function getAuthFileDirectory() {
19
20
  const {
20
21
  uatDirectory
@@ -22,29 +23,29 @@ function getAuthFileDirectory() {
22
23
  return _path.default.resolve(_path.default.join(uatDirectory, 'playwright', '.auth'));
23
24
  }
24
25
  function verifyIfCookieFileExists(authFile) {
25
- const authDirectory = getAuthFileDirectory();
26
- if (!(0, _fs.existsSync)(authDirectory)) {
27
- console.log('Creating auth directory for the first time setup...');
28
- (0, _fs.mkdirSync)(authDirectory, {
29
- recursive: true
30
- });
31
- }
32
- if (!(0, _fs.existsSync)(authFile)) {
33
- console.log('creating auth file..');
34
- (0, _fs.writeFileSync)(authFile, JSON.stringify(authContent, null, 2));
35
- }
26
+ return (0, _fs.existsSync)(authFile);
36
27
  }
37
28
  function convertCookiesToParse(cookies, authFilePath) {
38
29
  try {
39
30
  return JSON.parse(cookies);
40
31
  } catch (err) {
32
+ _logger.Logger.error(err);
41
33
  throw new Error(` Error while parsing cookies ${err} \n${_path.default.resolve(process.cwd(), authFilePath)} File is Empty`);
42
- // process.exit()
43
34
  }
44
35
  }
45
36
  async function loadCookiesIfPresent(page, authFile) {
46
- verifyIfCookieFileExists(authFile);
47
- const cookies = (0, _fs.readFileSync)(authFile);
48
- const parsedCookies = convertCookiesToParse(cookies, authFile);
49
- await page.context().addCookies(parsedCookies.cookies === undefined ? [] : parsedCookies.cookies);
37
+ if (verifyIfCookieFileExists(authFile)) {
38
+ const fileContent = (0, _fs.readFileSync)(authFile);
39
+ const stroageState = convertCookiesToParse(fileContent, authFile);
40
+ if (stroageState.cookies) {
41
+ await page.context().addCookies(stroageState.cookies);
42
+ }
43
+ }
44
+ }
45
+ async function storeFilteredStorageState(page, authFile) {
46
+ const storageState = await page.context().storageState();
47
+ const filteredCookies = storageState.cookies.filter(cookie => authCookieNameKeys.some(key => cookie.name.includes(key)));
48
+ (0, _fileUtils.writeFileContents)(authFile, JSON.stringify({
49
+ cookies: filteredCookies
50
+ }, null, 2));
50
51
  }
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.getDefaultActor = getDefaultActor;
8
+ exports.getDefaultActorConf = getDefaultActorConf;
8
9
  exports.getListOfActors = getListOfActors;
9
10
  exports.getRunMode = getRunMode;
10
11
  exports.getUserForSelectedEditionAndProfile = getUserForSelectedEditionAndProfile;
@@ -12,7 +13,9 @@ exports.isCI = isCI;
12
13
  exports.isDevelopmentSetup = isDevelopmentSetup;
13
14
  var _path = _interopRequireDefault(require("path"));
14
15
  var _fs = require("fs");
15
- var _readConfigFile = require("../../readConfigFile");
16
+ var _configPathResolver = require("../configPathResolver");
17
+ var _ConfigurationHelper = require("./../../configuration/ConfigurationHelper");
18
+ var _configConstants = _interopRequireDefault(require("../../constants/configConstants"));
16
19
  /* eslint-disable global-require */
17
20
  function getRunMode() {
18
21
  let {
@@ -28,70 +31,74 @@ function isDevelopmentSetup() {
28
31
  const mode = getRunMode();
29
32
  return mode === 'DEV' || mode === 'dev';
30
33
  }
31
- function getDefaultActor() {
32
- const {
33
- uatDirectory
34
- } = (0, _readConfigFile.generateConfigFromFile)();
35
- const defaultSettingFile = `conf/${getRunMode()}/settings.json`;
36
- const filePath = _path.default.join(uatDirectory, defaultSettingFile);
37
- if (!(0, _fs.existsSync)(filePath)) {
38
- throw new Error(`${defaultSettingFile} is missing.`);
34
+ function getDefaultActorConf() {
35
+ const stage = (0, _ConfigurationHelper.getRunStage)();
36
+ const stagePath = (0, _configPathResolver.getConfigPath)(stage);
37
+ const modeSettingsFile = `${stagePath}/${getRunMode()}/${_configConstants.default.SETTINGS_FILE}`;
38
+ const filePath = _path.default.join(_path.default.resolve(process.cwd(), modeSettingsFile));
39
+ try {
40
+ if (!(0, _fs.existsSync)(filePath)) {
41
+ const defaultSettingsFile = _path.default.join(_path.default.resolve(process.cwd(), `${stagePath}/${_configConstants.default.DEFAULT_CONFIG_DIR}/${_configConstants.default.SETTINGS_FILE}`));
42
+ return require(defaultSettingsFile);
43
+ }
44
+ return require(filePath);
45
+ } catch (error) {
46
+ throw new Error(`${filePath} file missing.`);
39
47
  }
40
- return require(filePath);
41
48
  }
42
- function getListOfActors() {
49
+ function getDefaultActor() {
43
50
  const {
44
- uatDirectory
45
- } = (0, _readConfigFile.generateConfigFromFile)();
51
+ edition,
52
+ profile
53
+ } = getDefaultActorConf();
54
+ return getUserForSelectedEditionAndProfile(edition, profile);
55
+ }
56
+ function getListOfActors(betaFeature) {
46
57
  const mode = getRunMode();
47
- const configFile = `conf/${mode}/actors/index`;
48
- const filePath = _path.default.join(uatDirectory, configFile);
49
- if (!(0, _fs.existsSync)(filePath + '.js')) {
50
- throw new Error(`${configFile}.js is missing.`);
58
+ const stage = (0, _ConfigurationHelper.getRunStage)();
59
+ const stagePath = (0, _configPathResolver.getConfigPath)(stage);
60
+ let configFile = _path.default.join(_path.default.resolve(process.cwd(), `${stagePath}/${mode}/${_configConstants.default.ACTOR_DIR}/${_configConstants.default.INDEX_FILE}`));
61
+ let betaReference = mode;
62
+ if (!(0, _fs.existsSync)(configFile)) {
63
+ configFile = _path.default.join(_path.default.resolve(process.cwd(), `${stagePath}/${_configConstants.default.DEFAULT_CONFIG_DIR}/${_configConstants.default.ACTOR_DIR}/${_configConstants.default.INDEX_FILE}`));
64
+ betaReference = "default";
65
+ }
66
+ if (betaFeature) {
67
+ configFile = _path.default.join(_path.default.resolve(process.cwd(), `${stagePath}/${betaReference}/${_configConstants.default.ACTOR_DIR}/${_configConstants.default.BETA_DIR}/${betaFeature}/${_configConstants.default.INDEX_FILE}`));
68
+ if (!(0, _fs.existsSync)(configFile)) {
69
+ throw new Error(`There is no beta feature configured with the name "${betaFeature}"`);
70
+ }
71
+ }
72
+ try {
73
+ return require(configFile);
74
+ } catch (error) {
75
+ throw new Error(`Error loading actor configuration from ${configFile}`);
51
76
  }
52
- return require(filePath);
53
77
  }
54
78
  function getUserForSelectedEditionAndProfile(preferedEdition, preferredProfile, betaFeature, testDataPortal = null) {
79
+ const actorsData = getListOfActors(betaFeature);
80
+ if (!actorsData || !actorsData.editions) {
81
+ throw new Error("The actors data is missing.");
82
+ }
55
83
  const {
56
- editions: userdata,
57
- beta: betaPortals
58
- } = getListOfActors();
59
- const primaryUser = getDefaultActor();
60
- const edition = preferedEdition || primaryUser.edition;
61
- const profile = preferredProfile || primaryUser.profile;
84
+ editions: userdata
85
+ } = actorsData;
86
+ const defaultConf = getDefaultActorConf();
87
+ const edition = preferedEdition || defaultConf.edition;
88
+ const profile = preferredProfile || defaultConf.profile;
62
89
  let selectedProfile = {};
63
- if (betaFeature && betaFeature !== null) {
64
- if (!betaPortals.hasOwnProperty(betaFeature)) {
65
- throw new Error(`There is no "${betaFeature}" beta feature configured.`);
66
- }
67
- const betaEdition = betaPortals[betaFeature].find(portal => portal.edition === edition);
68
- if (!betaEdition) {
69
- throw new Error(`There is no "${edition}" edition configured in "${betaFeature}" beta feature.`);
70
- }
71
- const {
72
- profiles: betaProfiles,
73
- ...betaEditionData
74
- } = betaEdition;
75
- selectedProfile = betaProfiles.find(user => user.profile === profile);
76
- if (!selectedProfile) {
77
- throw new Error(`There is no "${profile}" configured in edition of "${edition}" in "${betaFeature}" beta features.`);
78
- }
79
- return {
80
- ...betaEditionData,
81
- ...selectedProfile
82
- };
83
- }
84
90
 
85
91
  // TODO: We are returning the first data from array. We need to check the possiblity of having multiple users for same profile and possibly round robin
86
92
  // For this we need to get the data from ci environment.
93
+
87
94
  let testingPortal = null;
88
95
  if (!userdata.hasOwnProperty(edition)) {
89
- throw new Error(`There is no "${edition}" edition configured.`);
96
+ throw new Error(`There is no edition configured with the name "${edition}"`);
90
97
  }
91
98
  if (testDataPortal !== null) {
92
99
  testingPortal = userdata[edition].find(editionData => editionData.orgName === testDataPortal);
93
100
  if (!testingPortal) {
94
- throw new Error(`There is no "${testDataPortal}" portal configured in "${edition}" edition.`);
101
+ throw new Error(`There is no portal configured with the name "${testDataPortal}" in the "${edition}" edition.`);
95
102
  }
96
103
  } else {
97
104
  testingPortal = userdata[edition] ? userdata[edition][0] : {};
@@ -102,10 +109,11 @@ function getUserForSelectedEditionAndProfile(preferedEdition, preferredProfile,
102
109
  } = testingPortal;
103
110
  selectedProfile = profiles.find(user => user.profile === profile);
104
111
  if (!selectedProfile) {
105
- throw new Error(`There is no "${profile}" profile configured in "${edition}" edition.`);
112
+ throw new Error(`There is no profile configured with the name "${profile}" in the "${edition}" edition.`);
106
113
  }
107
114
  return {
108
115
  ...editionData,
109
- ...selectedProfile
116
+ ...selectedProfile,
117
+ 'beta': betaFeature
110
118
  };
111
119
  }
@@ -16,6 +16,12 @@ Object.defineProperty(exports, "getDefaultActor", {
16
16
  return _getUsers.getDefaultActor;
17
17
  }
18
18
  });
19
+ Object.defineProperty(exports, "getDefaultActorConf", {
20
+ enumerable: true,
21
+ get: function () {
22
+ return _getUsers.getDefaultActorConf;
23
+ }
24
+ });
19
25
  Object.defineProperty(exports, "getListOfActors", {
20
26
  enumerable: true,
21
27
  get: function () {
@@ -28,6 +34,12 @@ Object.defineProperty(exports, "getRunMode", {
28
34
  return _getUsers.getRunMode;
29
35
  }
30
36
  });
37
+ Object.defineProperty(exports, "getRunStage", {
38
+ enumerable: true,
39
+ get: function () {
40
+ return _ConfigurationHelper.getRunStage;
41
+ }
42
+ });
31
43
  Object.defineProperty(exports, "getUserForSelectedEditionAndProfile", {
32
44
  enumerable: true,
33
45
  get: function () {
@@ -67,4 +79,5 @@ Object.defineProperty(exports, "verifyIfCookieFileExists", {
67
79
  var _accountLogin = _interopRequireDefault(require("./accountLogin"));
68
80
  var _checkAuthCookies = require("./checkAuthCookies");
69
81
  var _getUsers = require("./getUsers");
70
- var _loginSteps = _interopRequireDefault(require("./loginSteps"));
82
+ var _loginSteps = _interopRequireDefault(require("./loginSteps"));
83
+ var _ConfigurationHelper = require("../../configuration/ConfigurationHelper");
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.executeDefaultLoginSteps = executeDefaultLoginSteps;
7
+ exports.getAuthenticationPrefix = getAuthenticationPrefix;
8
+ exports.loginSteps = loginSteps;
9
+ exports.performDefaultPageSteps = performDefaultPageSteps;
10
+ exports.verifyPageIsLoaded = verifyPageIsLoaded;
11
+ var _auth = require("../auth");
12
+ var _readConfigFile = require("../../readConfigFile");
13
+ var _logger = require("../../../../utils/logger");
14
+ let {
15
+ testSetup,
16
+ isAuthMode
17
+ } = (0, _readConfigFile.generateConfigFromFile)();
18
+ async function loginSteps(pageDetail) {
19
+ const {
20
+ page
21
+ } = pageDetail;
22
+ if (testSetup.loginSteps && typeof testSetup.loginSteps === 'function') {
23
+ return await testSetup.loginSteps(pageDetail);
24
+ } else {
25
+ await page.goto(process.env.domain);
26
+ }
27
+ }
28
+ async function performDefaultPageSteps(testInfo) {
29
+ if (testSetup.page && typeof testSetup.page === 'function') {
30
+ await testSetup.page(testInfo);
31
+ }
32
+ }
33
+ async function verifyPageIsLoaded(testInfo) {
34
+ if (testSetup.validateLogin && typeof testSetup.validateLogin === 'function') {
35
+ return await testSetup.validateLogin(testInfo);
36
+ }
37
+ return true;
38
+ }
39
+ async function getAuthenticationPrefix(testDetails) {
40
+ if (testSetup.getAuthenticationPrefix && typeof testSetup.getAuthenticationPrefix === 'function') {
41
+ return await testSetup.getAuthenticationPrefix(testDetails);
42
+ }
43
+ return process.env.authFilePrefix;
44
+ }
45
+ async function executeDefaultLoginSteps(context, testInfo, testDetails, testPortalDetails) {
46
+ if (!isAuthMode) {
47
+ return;
48
+ }
49
+ try {
50
+ const projectName = testInfo.project.name;
51
+ testDetails.authFilePrefix = await getAuthenticationPrefix(testDetails);
52
+ if (testPortalDetails && projectName !== 'setup' && projectName !== 'cleanup') {
53
+ await context.clearCookies();
54
+ await (0, _auth.performLoginSteps)(testDetails, async testInfo => {
55
+ return await verifyPageIsLoaded(testInfo);
56
+ }, loginSteps);
57
+ process.env.actorInfo = JSON.stringify(testPortalDetails);
58
+ }
59
+ } catch (error) {
60
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, 'Error while executing the default login steps:', error);
61
+ }
62
+ }
@@ -6,31 +6,49 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.default = void 0;
8
8
  var _path = _interopRequireDefault(require("path"));
9
- var _accountLogin = _interopRequireDefault(require("./accountLogin"));
9
+ var _fileMutex = _interopRequireDefault(require("../fileMutex"));
10
+ var _fileMutexConfig = require("../../constants/fileMutexConfig");
10
11
  var _checkAuthCookies = require("./checkAuthCookies");
12
+ var _checkAuthDirectory = require("../checkAuthDirectory");
11
13
  /* eslint-disable no-console */
12
14
 
13
- async function performLoginSteps({
14
- page,
15
- authFilePrefix,
16
- useremail,
17
- password
18
- }, isLoggedIn) {
19
- const authFile = _path.default.resolve(_path.default.join((0, _checkAuthCookies.getAuthFileDirectory)(), `${authFilePrefix}-cookies.json`));
20
- await (0, _checkAuthCookies.loadCookiesIfPresent)(page, authFile);
21
- await page.goto(process.env.domain);
22
- await page.waitForNavigation();
23
- const loginStatus = await isLoggedIn(page);
24
- if (!loginStatus) {
25
- await (0, _accountLogin.default)(page, useremail, password);
26
- await page.goto(process.env.domain);
27
-
28
- // await page.waitForLoadState();
29
-
30
- await isLoggedIn(page);
31
- await page.context().storageState({
32
- path: authFile
33
- });
15
+ async function performLoginSteps(testInfo, isLoggedIn, loginSteps) {
16
+ let {
17
+ page,
18
+ authFilePrefix,
19
+ email
20
+ } = testInfo;
21
+ let authFileName;
22
+ if (authFilePrefix) {
23
+ authFileName = `${authFilePrefix}-${email}`;
24
+ process.env.authFilePrefix = authFilePrefix;
25
+ } else {
26
+ authFileName = `${email}`;
27
+ }
28
+ const authFile = _path.default.resolve(_path.default.join((0, _checkAuthCookies.getAuthFileDirectory)(), `${authFileName}-cookies.json`));
29
+ const lockFileName = `${authFileName}`.replace(/[@.]/g, '_');
30
+ const fileMutex = new _fileMutex.default((0, _checkAuthDirectory.getLockDirectoryPath)(), lockFileName, _fileMutexConfig.fileDeletionTimeoutConfig);
31
+ let loginUsingCookie = false;
32
+ try {
33
+ if ((0, _checkAuthCookies.verifyIfCookieFileExists)(authFile)) {
34
+ console.log(`${authFileName} Cookie file exists. Loading cookies, worker index - ${process.env.TEST_WORKER_INDEX}`);
35
+ loginUsingCookie = true;
36
+ } else {
37
+ await fileMutex.acquire();
38
+ }
39
+ await (0, _checkAuthCookies.loadCookiesIfPresent)(page, authFile);
40
+ const isAlreadyLoggedIn = await isLoggedIn(testInfo);
41
+ if (!isAlreadyLoggedIn) {
42
+ await loginSteps(testInfo);
43
+ await isLoggedIn(testInfo);
44
+ await (0, _checkAuthCookies.storeFilteredStorageState)(page, authFile);
45
+ }
46
+ } catch (error) {
47
+ console.error(`Error during login for ${authFileName}:`, error);
48
+ } finally {
49
+ if (!loginUsingCookie) {
50
+ await fileMutex.release();
51
+ }
34
52
  }
35
53
  }
36
54
  var _default = exports.default = performLoginSteps;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getBrowserTimeoutFactor = getBrowserTimeoutFactor;
7
+ var _browserTypes = require("../constants/browserTypes");
8
+ function getBrowserTimeoutFactor(projectName) {
9
+ if (projectName === _browserTypes.BROWSER_PROJECT_MAPPING.FIREFOX) {
10
+ return 2;
11
+ }
12
+ if (projectName === _browserTypes.BROWSER_PROJECT_MAPPING.SAFARI) {
13
+ return 4;
14
+ }
15
+ return 1;
16
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TIMEOUT_TAG_PATTERN = void 0;
7
+ exports.findTimeoutTags = findTimeoutTags;
8
+ exports.parseTimeoutSeconds = parseTimeoutSeconds;
9
+ exports.resolveCaseTimeoutMs = resolveCaseTimeoutMs;
10
+ var _logger = require("../../../utils/logger");
11
+ var _browserTimeoutFactor = require("./browserTimeoutFactor");
12
+ const TIMEOUT_TAG_PATTERN = exports.TIMEOUT_TAG_PATTERN = /^@timeout_(\d+)$/;
13
+ function findTimeoutTags(tags) {
14
+ if (!Array.isArray(tags)) {
15
+ return [];
16
+ }
17
+ return tags.filter(tag => typeof tag === 'string' && TIMEOUT_TAG_PATTERN.test(tag));
18
+ }
19
+ function parseTimeoutSeconds(tag) {
20
+ const match = tag.match(TIMEOUT_TAG_PATTERN);
21
+ return match ? Number(match[1]) : null;
22
+ }
23
+ function resolveCaseTimeoutMs(tags, projectName) {
24
+ const matched = findTimeoutTags(tags);
25
+ if (matched.length === 0) {
26
+ return null;
27
+ }
28
+ if (matched.length > 1) {
29
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, `Multiple @timeout_* tags found (${matched.join(', ')}). Using the first one: ${matched[0]}`);
30
+ }
31
+ const seconds = parseTimeoutSeconds(matched[0]);
32
+ if (seconds === 0) {
33
+ return 0;
34
+ }
35
+ const factor = (0, _browserTimeoutFactor.getBrowserTimeoutFactor)(projectName);
36
+ return seconds * 1000 * factor;
37
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.createAuthDirectoryIfNotExist = createAuthDirectoryIfNotExist;
8
+ exports.getLockDirectoryPath = getLockDirectoryPath;
9
+ var _fs = require("fs");
10
+ var _path = _interopRequireDefault(require("path"));
11
+ var _checkAuthCookies = require("./auth/checkAuthCookies");
12
+ var _readConfigFile = require("../readConfigFile");
13
+ function createAuthDirectoryIfNotExist() {
14
+ const authDirectory = (0, _checkAuthCookies.getAuthFileDirectory)();
15
+ if (!(0, _fs.existsSync)(authDirectory)) {
16
+ console.log('Creating auth directory for the first time setup...');
17
+ (0, _fs.mkdirSync)(authDirectory, {
18
+ recursive: true
19
+ });
20
+ }
21
+ }
22
+ function getLockDirectoryPath() {
23
+ const {
24
+ uatDirectory
25
+ } = (0, _readConfigFile.generateConfigFromFile)();
26
+ return _path.default.resolve(_path.default.join(uatDirectory, 'playwright', '.lock'));
27
+ }
@@ -9,16 +9,30 @@ exports.getReportFileName = getReportFileName;
9
9
  exports.getUATFileName = getUATFileName;
10
10
  var _path = _interopRequireDefault(require("path"));
11
11
  var _fs = _interopRequireDefault(require("fs"));
12
- function getUATFileName() {
13
- return 'uat.config.js';
12
+ var _auth = require("./auth");
13
+ var _ConfigurationHelper = require("./../configuration/ConfigurationHelper");
14
+ var _configPathResolver = require("./configPathResolver");
15
+ var _configConstants = _interopRequireDefault(require("../constants/configConstants"));
16
+ function getUATFileName(stage, mode) {
17
+ stage = stage || (0, _ConfigurationHelper.getRunStage)();
18
+ mode = mode || (0, _auth.getRunMode)();
19
+ const stagePath = (0, _configPathResolver.getConfigPath)(stage);
20
+ const uatConfFilePath = _path.default.resolve(process.cwd(), `${stagePath}/${mode}/${_configConstants.default.UAT_CONFIG_FILE}`);
21
+ if (_fs.default.existsSync(uatConfFilePath)) {
22
+ return uatConfFilePath;
23
+ }
24
+ ;
25
+ return _path.default.resolve(process.cwd(), `${stagePath}/${_configConstants.default.DEFAULT_CONFIG_DIR}/${_configConstants.default.UAT_CONFIG_FILE}`);
14
26
  }
15
- function getEnvConfigFilePath(mode) {
16
- const confFilePath = _path.default.resolve(process.cwd(), `uat/conf/${mode}/settings.json`);
27
+ function getEnvConfigFilePath(stage, mode) {
28
+ const stagePath = (0, _configPathResolver.getConfigPath)(stage);
29
+ const confFilePath = `${stagePath}/${mode}/${_configConstants.default.SETTINGS_FILE}`;
30
+ // TODO: Actors Mode as config
17
31
  if (_fs.default.existsSync(confFilePath)) {
18
- return `uat/conf/${mode}/settings.json`;
32
+ return confFilePath;
19
33
  }
20
- return `uat/env-config.json`;
34
+ return `${stagePath}/${_configConstants.default.DEFAULT_CONFIG_DIR}/${_configConstants.default.SETTINGS_FILE}`;
21
35
  }
22
36
  function getReportFileName() {
23
- return `test-summary.json`;
37
+ return `${_configConstants.default.TEST_SUMMARY_FILE}`;
24
38
  }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getConfigPath = getConfigPath;
8
+ var _fs = _interopRequireDefault(require("fs"));
9
+ var _path = _interopRequireDefault(require("path"));
10
+ var _propertiesReader = _interopRequireDefault(require("properties-reader"));
11
+ var _logger = require("../../../utils/logger");
12
+ var _configConstants = _interopRequireDefault(require("../constants/configConstants"));
13
+ //This function reads a properties file and returns the entire properties
14
+
15
+ function readPropertiesFile(relativeFilePath) {
16
+ const filePath = _path.default.resolve(process.cwd(), relativeFilePath);
17
+ let properties;
18
+ if (_fs.default.existsSync(filePath)) {
19
+ properties = (0, _propertiesReader.default)(filePath);
20
+ } else {
21
+ // we have to remove this logic after adding all the projects with proper config files
22
+ _logger.Logger.log(_logger.Logger.INFO_TYPE, `Properties file ${filePath} not found. Using default configurations.`);
23
+ properties = (0, _propertiesReader.default)();
24
+ properties.set('uat', 'uat/conf');
25
+ }
26
+ return properties;
27
+ }
28
+
29
+ // This function return the value for the passed arguments key
30
+
31
+ function getConfigPath(stage) {
32
+ const props = readPropertiesFile(_configConstants.default.STAGE_CONFIG_MAP_FILE);
33
+ const configPath = props.get(stage);
34
+ if (!configPath) {
35
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, `No config mapping found for stage: "${stage}"`);
36
+ }
37
+ return configPath;
38
+ }