@zohodesk/testinglibrary 3.2.6 → 3.2.8

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/.gitlab-ci.yml CHANGED
@@ -160,4 +160,16 @@ uat-smoketest:
160
160
  paths:
161
161
  - examples/uat/playwright-report
162
162
 
163
-
163
+ uat-multiactor:
164
+ stage: uat
165
+ script:
166
+ - cd examples
167
+ - npm install $(npm pack ../../testing-framework | tail -1)
168
+ - output=$(npm run uat-multiactor)
169
+ - echo "$output"
170
+ - node ../ValidateUATReport.js examples
171
+
172
+ artifacts:
173
+ when: always
174
+ paths:
175
+ - examples/uat/playwright-report
package/README.md CHANGED
@@ -19,6 +19,19 @@
19
19
 
20
20
  ## Version History
21
21
 
22
+ ### v3.2.8 - 18-09-2025
23
+
24
+ ### Bug fix
25
+
26
+ - Default profile switching handled in Multi actor – Improved handling of default profile switching to ensure smoother execution flow.
27
+
28
+ - QC Report tags issue fixed – Resolved an issue where QC Report tags were not displaying correctly in reports.
29
+
30
+ ### v3.2.7 - 10-09-2025
31
+
32
+ ### Bug fix
33
+ - Fixed a bug where the default profile page was not being handled properly in `this`.
34
+
22
35
  ### v3.2.6 - 05-09-2025
23
36
 
24
37
  #### Feature
@@ -1,15 +1,20 @@
1
1
  import { createBdd } from '@zohodesk/testinglibrary';
2
2
  const { BeforeScenario, Given } = createBdd();
3
3
 
4
- BeforeScenario(async function({ actorCtx }) {
4
+ BeforeScenario(async function({ page, context, browser, cacheLayer, executionContext, actorContext }) {
5
5
  // This will run before each scenario and set all the fixtures into this context
6
+ this.page = page;
7
+ this.context = context;
8
+ this.browser = browser;
9
+ this.cacheLayer = cacheLayer;
10
+ this.executionContext = executionContext;
6
11
  this.setActor = async (role) => {
7
- const userPage = actorCtx.actorsObj[role];
12
+ const userPage = actorContext.actorsObj[role];
8
13
  if (userPage) {
9
14
  this.page = userPage.page;
10
15
  this.context = userPage.context;
11
16
  this.browser = userPage.browser;
12
- this.executionContext = userPage.actorInfo;
17
+ this.executionContext = userPage.executionContext;
13
18
  } else {
14
19
  throw new Error(`Actor "${role}" not found in user pages.`);
15
20
  }
@@ -5,16 +5,25 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _logger = require("../../../utils/logger");
8
- var _customFixturesHelper = require("../helpers/customFixturesHelper");
8
+ var _additionalProfiles = require("../helpers/additionalProfiles");
9
9
  var _loginDefaultStepsHelper = require("../helpers/auth/loginDefaultStepsHelper");
10
- class additionalActorContext {
10
+ class ActorContext {
11
11
  constructor() {
12
12
  this.actorsObj = {};
13
13
  }
14
- async setupAdditionalActors(browser, $tags, testInfo) {
14
+ async setup(browser, $tags, testInfo, context, page, executionContext) {
15
15
  try {
16
- const actorInfoMap = (0, _customFixturesHelper.getCustomAccountDetails)($tags);
17
- const additionalActors = actorInfoMap.additional;
16
+ const {
17
+ profile
18
+ } = executionContext.actorInfo;
19
+ this.actorsObj[profile] = {
20
+ role: profile,
21
+ browser,
22
+ context,
23
+ page,
24
+ executionContext
25
+ };
26
+ const additionalActors = (0, _additionalProfiles.additionProfiles)($tags);
18
27
  await Promise.all(Object.entries(additionalActors).map(async ([role, actorInfo]) => {
19
28
  let context = await browser.newContext();
20
29
  let page = await context.newPage();
@@ -30,7 +39,9 @@ class additionalActorContext {
30
39
  browser,
31
40
  context,
32
41
  page,
33
- actorInfo
42
+ executionContext: {
43
+ actorInfo
44
+ }
34
45
  };
35
46
  }));
36
47
  } catch (error) {
@@ -49,12 +60,15 @@ class additionalActorContext {
49
60
  }
50
61
  }
51
62
  var _default = exports.default = {
52
- actorCtx: async ({
63
+ actorContext: async ({
64
+ page,
65
+ context,
66
+ executionContext,
53
67
  $tags,
54
68
  browser
55
69
  }, use, testInfo) => {
56
- const ctxObject = new additionalActorContext();
57
- await ctxObject.setupAdditionalActors(browser, $tags, testInfo);
70
+ const ctxObject = new ActorContext();
71
+ await ctxObject.setup(browser, $tags, testInfo, context, page, executionContext);
58
72
  await use(ctxObject);
59
73
  await ctxObject.cleanup();
60
74
  }
@@ -9,8 +9,9 @@ var _default = exports.default = {
9
9
  executionContext: async ({
10
10
  $tags
11
11
  }, use) => {
12
- const allActorsObj = (0, _customFixturesHelper.getCustomAccountDetails)($tags);
13
- const currentActor = allActorsObj.main;
14
- await use(currentActor);
12
+ const actorInfo = (0, _customFixturesHelper.getCustomAccountDetails)($tags);
13
+ await use({
14
+ actorInfo
15
+ });
15
16
  }
16
17
  };
@@ -12,14 +12,14 @@ var _addTags = _interopRequireDefault(require("./addTags"));
12
12
  var _i18N = _interopRequireDefault(require("./i18N"));
13
13
  var _unauthenticatedPage = _interopRequireDefault(require("./unauthenticatedPage"));
14
14
  var _executionContext = _interopRequireDefault(require("./executionContext"));
15
- var _actorCtx = _interopRequireDefault(require("./actorCtx"));
15
+ var _actorContext = _interopRequireDefault(require("./actorContext"));
16
16
  function extractTagsFromTitle(text) {
17
17
  return text.match(/@\w+/g) || [];
18
18
  }
19
19
  function getBuiltInFixtures(bddMode) {
20
20
  let builtInFixtures = {
21
21
  ..._page.default,
22
- ..._actorCtx.default,
22
+ ..._actorContext.default,
23
23
  ..._context.default,
24
24
  ..._cacheLayer.default,
25
25
  ..._i18N.default,
@@ -13,7 +13,7 @@ var _default = exports.default = {
13
13
  page,
14
14
  executionContext
15
15
  }, use, testInfo) => {
16
- let testPortalDetails = executionContext;
16
+ let testPortalDetails = executionContext.actorInfo;
17
17
  let testDetails = {
18
18
  page,
19
19
  $tags,
@@ -5,10 +5,16 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.additionProfiles = additionProfiles;
7
7
  var _getUsers = require("./auth/getUsers");
8
- function additionProfiles(tags, editionInfo, betaFeature, portalInfo) {
8
+ var _customFixturesHelper = require("./customFixturesHelper");
9
+ function additionProfiles(tags) {
10
+ const {
11
+ editionInfo,
12
+ betaFeature,
13
+ portalInfo
14
+ } = (0, _customFixturesHelper.extractTagInfo)(tags);
9
15
  const additionalProfileTags = tags.filter(tag => tag.startsWith('@additional_profile_'));
10
16
  let additionalProfileActors = {};
11
- if (additionalProfileTags.length > 0 && editionInfo) {
17
+ if (additionalProfileTags.length > 0) {
12
18
  additionalProfileTags.forEach(tag => {
13
19
  const additionalProfile = tag.replace('@additional_profile_', '');
14
20
  const actorDetails = (0, _getUsers.getUserForSelectedEditionAndProfile)(editionInfo, additionalProfile, betaFeature, portalInfo);
@@ -9,6 +9,7 @@ exports.performDefaultPageSteps = performDefaultPageSteps;
9
9
  exports.verifyPageIsLoaded = verifyPageIsLoaded;
10
10
  var _auth = require("../auth");
11
11
  var _readConfigFile = require("../../readConfigFile");
12
+ var _logger = require("../../../../utils/logger");
12
13
  let {
13
14
  testSetup,
14
15
  isAuthMode
@@ -48,6 +49,6 @@ async function executeDefaultLoginSteps(context, testInfo, testDetails, testPort
48
49
  process.env.actorInfo = JSON.stringify(testPortalDetails);
49
50
  }
50
51
  } catch (error) {
51
- Logger.log(Logger.FAILURE_TYPE, 'Error while executing the default login steps:', error);
52
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, 'Error while executing the default login steps:', error);
52
53
  }
53
54
  }
@@ -3,9 +3,9 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.extractTagInfo = extractTagInfo;
6
7
  exports.getCustomAccountDetails = getCustomAccountDetails;
7
8
  var _auth = require("../helpers/auth");
8
- var _additionalProfiles = require("../helpers/additionalProfiles");
9
9
  var _logger = require("../../../utils/logger");
10
10
  /* eslint-disable global-require */
11
11
 
@@ -17,27 +17,42 @@ function getTagInputFromSelectedTags(tags, inputString) {
17
17
  }
18
18
  return tagInput;
19
19
  }
20
+ function extractTagInfo(tags) {
21
+ const tagsTobeFiltered = ['@profile', '@edition', '@beta', '@portal'];
22
+ const filteredTags = tags.filter(tag => tagsTobeFiltered.some(prefix => tag.startsWith(prefix)));
23
+ if (!filteredTags.length) {
24
+ return {
25
+ portalInfo: null,
26
+ betaFeature: null,
27
+ profileInfo: null,
28
+ editionInfo: null
29
+ };
30
+ }
31
+ const portalInfo = getTagInputFromSelectedTags(filteredTags, '@portal');
32
+ const betaFeature = getTagInputFromSelectedTags(filteredTags, '@beta');
33
+ const profileInfo = getTagInputFromSelectedTags(filteredTags, '@profile');
34
+ const editionInfo = getTagInputFromSelectedTags(filteredTags, '@edition');
35
+ return {
36
+ portalInfo,
37
+ betaFeature,
38
+ profileInfo,
39
+ editionInfo
40
+ };
41
+ }
20
42
  function getCustomAccountDetails(tags) {
21
43
  try {
22
- const tagsTobeFiltered = ['@profile', '@edition', '@beta', '@portal', '@additional_profile'];
23
- const filteredTags = tags.filter(tag => tagsTobeFiltered.some(prefix => tag.startsWith(prefix)));
24
- if (filteredTags && filteredTags.length > 0) {
25
- const portalInfo = getTagInputFromSelectedTags(filteredTags, '@portal');
26
- const betaFeature = getTagInputFromSelectedTags(filteredTags, '@beta');
27
- const profileInfo = getTagInputFromSelectedTags(filteredTags, '@profile');
28
- const editionInfo = getTagInputFromSelectedTags(filteredTags, '@edition');
29
- const mainActor = (0, _auth.getUserForSelectedEditionAndProfile)(editionInfo, profileInfo, betaFeature, portalInfo);
30
- const additionalActors = (0, _additionalProfiles.additionProfiles)(tags, editionInfo, betaFeature, portalInfo);
31
- return {
32
- main: mainActor,
33
- additional: additionalActors
34
- };
44
+ const {
45
+ portalInfo,
46
+ betaFeature,
47
+ profileInfo,
48
+ editionInfo
49
+ } = extractTagInfo(tags);
50
+ if (portalInfo || betaFeature || profileInfo || editionInfo) {
51
+ const user = (0, _auth.getUserForSelectedEditionAndProfile)(editionInfo, profileInfo, betaFeature, portalInfo);
52
+ return user;
35
53
  }
36
- return {
37
- main: (0, _auth.getDefaultActor)(),
38
- additional: {}
39
- };
54
+ return (0, _auth.getDefaultActor)();
40
55
  } catch (err) {
41
- _logger.Logger.log(_logger.Logger.FAILURE_TYPE, 'Error while getting custom account details:', err);
56
+ _logger.Logger.log(_logger.Logger.FAILURE_TYPE, 'Error while getting accounts details:', err);
42
57
  }
43
58
  }
@@ -102,6 +102,7 @@ const createSpecEntry = (rootDir, test, testResultsById) => ({
102
102
  ...(test.location && {
103
103
  snippet: formSnippet(test.location)
104
104
  }),
105
+ tags: test.tags,
105
106
  tests: [extractTestDetails(test, testResultsById)]
106
107
  });
107
108
  const extractTestDetails = (test, testResultsById) => {
@@ -112,7 +113,6 @@ const extractTestDetails = (test, testResultsById) => {
112
113
  expectedStatus: test.expectedStatus,
113
114
  timeout: test.timeout,
114
115
  retries: test.retries,
115
- tags: test.tags,
116
116
  results: testResultsById.get(key) ?? [],
117
117
  status: test.outcome()
118
118
  };
@@ -14,16 +14,14 @@ describe('executionContext', () => {
14
14
  profile: 'admin',
15
15
  email: 'xxx.x+uat@zohotest.com'
16
16
  };
17
- const mockActorInfo = {
18
- main: mockMainActorInfo,
19
- additional: {}
20
- };
21
- _customFixturesHelper.getCustomAccountDetails.mockReturnValue(mockActorInfo);
17
+ _customFixturesHelper.getCustomAccountDetails.mockReturnValue(mockMainActorInfo);
22
18
  const use = jest.fn();
23
19
  await _executionContext.default.executionContext({
24
20
  $tags: mockTags
25
21
  }, use);
26
22
  expect(_customFixturesHelper.getCustomAccountDetails).toHaveBeenCalledWith(mockTags);
27
- expect(use).toHaveBeenCalledWith(mockMainActorInfo);
23
+ expect(use).toHaveBeenCalledWith({
24
+ actorInfo: mockMainActorInfo
25
+ });
28
26
  });
29
27
  });
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ var _additionalProfiles = require("../../../../../core/playwright/helpers/additionalProfiles");
4
+ jest.mock('../../../../../core/playwright/helpers/auth/getUsers', () => ({
5
+ getUserForSelectedEditionAndProfile: jest.fn((edition, profile, betaFeature, portalInfo) => {
6
+ return {
7
+ email: 'manager.m@zohotest.com',
8
+ id: '1',
9
+ edition: edition || 'enterprise',
10
+ orgName: 'orgName',
11
+ profile: profile || 'admin',
12
+ betaFeature: betaFeature || null,
13
+ portalInfo: portalInfo || null
14
+ };
15
+ })
16
+ }));
17
+ const defaultTags = ['@profile_admin', '@edition_enterprise'];
18
+ const editionTags = ['@profile_admin', '@edition_enterprise', '@additional_profile_manager', '@additional_profile_agent'];
19
+ const editionAndPortalTags = ['@profile_admin', '@edition_enterprise', '@beta_parentchild', '@portal_clientuat2', '@additional_profile_manager'];
20
+ describe('additionalProfiles', () => {
21
+ beforeEach(() => {
22
+ jest.clearAllMocks();
23
+ });
24
+ test('should return empty object when no additional profile tags are present', () => {
25
+ const result = (0, _additionalProfiles.additionProfiles)(defaultTags);
26
+ expect(result).toEqual({});
27
+ });
28
+ test('should return additional profile actors when additional profile tags and editionInfo are present', () => {
29
+ const result = (0, _additionalProfiles.additionProfiles)(editionTags);
30
+ expect(Object.keys(result)).toEqual(['manager', 'agent']);
31
+ expect(result.manager).toHaveProperty('email');
32
+ expect(result.agent).toHaveProperty('email');
33
+ expect(result.manager.profile).toBe('manager');
34
+ expect(result.manager.betaFeature).toBe(null);
35
+ expect(result.agent.portalInfo).toBe(null);
36
+ });
37
+ test('should return additional profile actors when all actor details are present', () => {
38
+ const result = (0, _additionalProfiles.additionProfiles)(editionAndPortalTags);
39
+ expect(Object.keys(result)).toEqual(['manager']);
40
+ expect(result.manager).toHaveProperty('email');
41
+ expect(result.manager.profile).toBe('manager');
42
+ expect(result.manager.betaFeature).toBe("parentchild");
43
+ expect(result.manager.portalInfo).toBe("clientuat2");
44
+ });
45
+ });
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+
3
+ var _customFixturesHelper = require("../../../../../core/playwright/helpers/customFixturesHelper");
4
+ var _logger = require("../../../../../utils/logger");
5
+ var _getUsers = require("../../../../../core/playwright/helpers/auth/getUsers");
6
+ jest.mock('../../../../../core/playwright/helpers/auth/getUsers', () => ({
7
+ getUserForSelectedEditionAndProfile: jest.fn((edition, profile, betaFeature, portalInfo) => ({
8
+ email: 'manager.m@zohotest.com',
9
+ id: '1',
10
+ edition: edition || 'enterprise',
11
+ orgName: 'orgName',
12
+ profile: profile || 'admin',
13
+ betaFeature: betaFeature || null,
14
+ portalInfo: portalInfo || null
15
+ })),
16
+ getDefaultActor: jest.fn(() => ({
17
+ edition: 'enterprise',
18
+ profile: 'admin'
19
+ }))
20
+ }));
21
+ jest.mock('../../../../../utils/logger', () => ({
22
+ Logger: {
23
+ log: jest.fn(),
24
+ FAILURE_TYPE: 'FAILURE'
25
+ }
26
+ }));
27
+ const mockTags = ['@profile_admin', '@edition_enterprise', '@beta_feature', '@portal_clientuat'];
28
+ describe('getCustomAccountDetails', () => {
29
+ beforeEach(() => {
30
+ jest.clearAllMocks();
31
+ });
32
+ test('returns selected user when any tag info is present', () => {
33
+ const result = (0, _customFixturesHelper.getCustomAccountDetails)(mockTags);
34
+ expect(_getUsers.getUserForSelectedEditionAndProfile).toHaveBeenCalledWith('enterprise', 'admin', 'feature', 'clientuat');
35
+ expect(result).toHaveProperty('email', 'manager.m@zohotest.com');
36
+ });
37
+ test('logs and returns undefined if getCustomAccountDetails function throws', () => {
38
+ const error = new Error('failed to get user');
39
+ _getUsers.getUserForSelectedEditionAndProfile.mockImplementation(() => {
40
+ throw error;
41
+ });
42
+ const result = (0, _customFixturesHelper.getCustomAccountDetails)(mockTags);
43
+ expect(_logger.Logger.log).toHaveBeenCalledWith(_logger.Logger.FAILURE_TYPE, 'Error while getting accounts details:', error);
44
+ expect(result).toBeUndefined();
45
+ });
46
+ test('returns default actor when no tag info is not provided', () => {
47
+ const result = (0, _customFixturesHelper.getCustomAccountDetails)([]);
48
+ expect(_getUsers.getDefaultActor).toHaveBeenCalledTimes(1);
49
+ expect(result).toEqual((0, _getUsers.getDefaultActor)());
50
+ });
51
+ });
@@ -4,35 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.Logger = void 0;
7
- // const SUCCESS_TYPE = 'success';
8
- // const FAILURE_TYPE = 'failure';
9
- // const INFO_TYPE = 'info';
10
-
11
- // function logger() {
12
- // this.colors = {
13
- // 'success': ['\x1b[36m', '\x1b[0m'],
14
- // 'failure': ['\x1b[31m', '\x1b[0m'],
15
- // 'info': ['\x1b[33m', '\x1b[0m']
16
- // }
17
- // this.consoleLogger = console;
18
- // return {
19
- // SUCCESS_TYPE,
20
- // FAILURE_TYPE,
21
- // INFO_TYPE,
22
- // error: () => { },
23
- // info: () => { },
24
- // log: (type, message) => {
25
- // const color = this.colors[type];
26
- // console.log(type, color)
27
- // this.consoleLogger.log(`${color[0]}${message}${color[1]}`)
28
- // }
29
- // }
30
- // }
31
-
32
- // module.exports = {
33
- // Logger: logger()
34
- // }
35
-
36
7
  class LoggerImpl {
37
8
  constructor() {
38
9
  this.SUCCESS_TYPE = 'success';
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@zohodesk/testinglibrary",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@zohodesk/testinglibrary",
9
- "version": "3.2.6",
9
+ "version": "3.2.8",
10
10
  "hasInstallScript": true,
11
11
  "license": "ISC",
12
12
  "dependencies": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/testinglibrary",
3
- "version": "3.2.6",
3
+ "version": "3.2.8",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {
@@ -257,4 +257,4 @@ header {
257
257
  font-size: 1rem;
258
258
  padding: 0 0.5rem;
259
259
  }
260
- </style></head><body><div class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><div id="metadata-container"><div id="timestamp">Started: 2025-09-03 08:57:31</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed ">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (1)</div><div class="summary-passed ">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><input id="collapsible-0" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-0"><div class="suite-info"><div class="suite-path">/Users/muthu-19817/git/testing-framework/src/test/core/playwright/buildInFixtures/__tests__/executionContext.test.js</div><div class="suite-time">0.851s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">executionContext</div><div class="test-title">should pass actorInfo with details from getCustomAccountDetails to use</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div></div></div></div></body></html>
260
+ </style></head><body><div class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><div id="metadata-container"><div id="timestamp">Started: 2025-09-16 17:51:54</div><div id="summary"><div id="suite-summary"><div class="summary-total">Suites (1)</div><div class="summary-passed ">1 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div><div id="test-summary"><div class="summary-total">Tests (3)</div><div class="summary-passed ">3 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></div><div id="suite-1" class="suite-container"><input id="collapsible-0" type="checkbox" class="toggle" checked="checked"/><label for="collapsible-0"><div class="suite-info"><div class="suite-path">/Users/muthu-19817/git/testing-framework/src/test/core/playwright/helpers/__tests__/additionalProfiles.test.js</div><div class="suite-time">0.63s</div></div></label><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">additionalProfiles</div><div class="test-title">should return empty object when no additional profile tags are present</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">additionalProfiles</div><div class="test-title">should return additional profile actors when additional profile tags and editionInfo are present</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">additionalProfiles</div><div class="test-title">should return additional profile actors when all actor details are present</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div></div></div></div></body></html>