@zohodesk/testinglibrary 0.4.93-n18-experimental → 0.4.95-n18-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.
package/.gitlab-ci.yml CHANGED
@@ -188,4 +188,19 @@ uat-data_generator:
188
188
  paths:
189
189
  - examples/uat/playwright-report
190
190
 
191
+ uat-search_indexing:
192
+ stage: uat
193
+ script:
194
+ - cd examples
195
+ - npm install $(npm pack ../../testing-framework | tail -1)
196
+ - output=$(npm run uat-search_indexing)
197
+ - echo "$output"
198
+ - node ../ValidateUATReport.js examples
199
+
200
+ artifacts:
201
+ when: always
202
+ paths:
203
+ - examples/uat/playwright-report
204
+
205
+
191
206
 
package/README.md CHANGED
@@ -19,8 +19,18 @@
19
19
 
20
20
  ## Version History
21
21
 
22
- #### Feature
23
- - To store the login session in NFS, we have provided the teardown option in the configuration
22
+ ### Unpublished release
23
+
24
+ ### Feature
25
+
26
+ - New step `a search entity using {string}` provided for search indexing, This step will use run time data generation response as input for the indexing
27
+
28
+ ### v3.2.9 - 26-09-2025
29
+
30
+ ### Enhancement
31
+
32
+ - Authentication deatils for data generation can be configured in org level
33
+ - reference link : https://learn.zoho.in/portal/zohocorp/knowledge/manual/client-uat/article/data-generation#_Tocpd3n7yt9ngeg
24
34
 
25
35
  ### v3.2.8 - 18-09-2025
26
36
 
@@ -10,10 +10,10 @@ Given('generate a {string} entity {string} with generator {string}', async ({ pa
10
10
  Given('generate a {string} entity {string} with API {string}', async ({ page, context, i18N, cacheLayer, executionContext}, module, entityName, operationId, dataTable) => {
11
11
  await generateAndCacheTestData(executionContext, "API", operationId, dataTable, cacheLayer, entityName);
12
12
  });
13
- Given('generate a {string} entity {string} with generator {string} using {string} profile', async ({ page, context, i18N, cacheLayer, executionContext}, module, entityName, generatorName, profile, dataTable) => {
14
- await generateAndCacheTestData(executionContext, "template", generatorName, dataTable, cacheLayer, entityName, profile);
13
+ Given('generate a {string} entity {string} with generator {string} using {string} profile', async ({ $tags, page, context, i18N, cacheLayer, executionContext}, module, entityName, generatorName, profile, dataTable) => {
14
+ await generateAndCacheTestData(executionContext, "template", generatorName, dataTable, cacheLayer, entityName, profile,$tags);
15
15
  });
16
16
 
17
- Given('generate a {string} entity {string} with API {string} using {string} profile', async ({ page, context, i18N, cacheLayer, executionContext}, module, entityName, operationId, profile, dataTable) => {
18
- await generateAndCacheTestData(executionContext, "API", operationId, dataTable, cacheLayer, entityName, profile);
17
+ Given('generate a {string} entity {string} with API {string} using {string} profile', async ({ $tags,page, context, i18N, cacheLayer, executionContext}, module, entityName, operationId, profile, dataTable) => {
18
+ await generateAndCacheTestData(executionContext, "API", operationId, dataTable, cacheLayer, entityName, profile, $tags);
19
19
  });
@@ -1,15 +1,17 @@
1
1
  import { test } from '@zohodesk/testinglibrary';
2
2
  import DataGenerator from '@zohodesk/testinglibrary/DataGenerator';
3
+ import {extractTagInfo, getUserForSelectedEditionAndProfile} from '@zohodesk/testinglibrary/helpers'
3
4
 
4
5
  const dataGenerator = new DataGenerator();
5
6
 
6
- export async function generateAndCacheTestData(executionContext, type, identifier, dataTable, cacheLayer, entityName, profile = null) {
7
+ export async function generateAndCacheTestData(executionContext, type, identifier, dataTable, cacheLayer, entityName, profile = null, tags = null) {
7
8
  let actorInfo;
8
9
  const testInfo = test.info();
9
10
  const scenarioName = testInfo.title.split('/').pop() || 'Unknown Scenario';
10
11
 
11
12
  if (profile) {
12
- actorInfo = await dataGenerator.getDataGenUserExecutionContext(executionContext.actorInfo.edition, profile);
13
+ const { portalInfo, betaFeature } = extractTagInfo(tags);
14
+ actorInfo = await getUserForSelectedEditionAndProfile(executionContext.actorInfo.edition, profile ,betaFeature, portalInfo)
13
15
  } else {
14
16
  actorInfo = executionContext.actorInfo;
15
17
  }
@@ -30,11 +30,22 @@ async function entityIdReConstructor(payload) {
30
30
  if (typeof payload !== 'object' || payload === null) {
31
31
  throw new Error('Invalid payload. It must be a non-null object.');
32
32
  }
33
- if (!payload.arguments || typeof payload.arguments.entityId !== 'string') {
34
- throw new Error('Invalid payload.arguments.entityId. It must be a non-empty string.');
33
+
34
+ if (!payload.arguments || (!payload.arguments.entityId)) {
35
+ throw new Error('Invalid payload.arguments.entityId. It must be a non-empty string or array of strings.');
36
+ }
37
+
38
+ const entityId = payload.arguments.entityId;
39
+
40
+ // If it's already an array, validate and clean it
41
+ if (Array.isArray(entityId)) {
42
+ payload.arguments.entityId = entityId.map(id => id.trim());
43
+ }
44
+ // If it's a string, split and convert to array
45
+ else if (typeof entityId === 'string') {
46
+ payload.arguments.entityId = entityId.split(',').map(id => id.trim());
35
47
  }
36
48
 
37
- payload.arguments.entityId = payload.arguments.entityId.split(',').map(id => id.trim());
38
49
  return payload;
39
50
  }
40
51
 
@@ -1,8 +1,14 @@
1
1
  import {createBdd } from '@zohodesk/testinglibrary';
2
2
  import { executeRpcRequest , entityIdReConstructor } from '../helpers/rpcRequestHelper';
3
+ import jp from 'jsonpath';
3
4
 
4
5
  const { Given } = createBdd();
5
6
 
7
+
8
+ // Given a search entity
9
+ // | moduleName | entityId | entityName | searchString |
10
+ // | contact | 122000006785675, 122000007141665, 122000006636472 | QA Team | testinguat |
11
+
6
12
  Given('a search entity', async ({page}, dataTable)=>{
7
13
  const data = dataTable.hashes();
8
14
 
@@ -22,5 +28,50 @@ Given('a search entity', async ({page}, dataTable)=>{
22
28
 
23
29
  await executeRpcRequest(page, payload);
24
30
  }
25
-
26
31
  });
32
+
33
+ // Given data generation step
34
+ // Given a search entity using "C1"
35
+ // | moduleName | searchString | searchEntity (response of the previous data generation step) |
36
+ // | contact | testinguat | $.id |
37
+ // | contact | testinguat | $.ids |
38
+ // | contact | testinguat |
39
+
40
+ Given('a search entity using {string}', async ({page,cacheLayer}, reference,dataTable)=>{
41
+ const data = dataTable.hashes();
42
+
43
+ const row = data[0];
44
+ if (!row || !row.moduleName || !row.searchString) {
45
+ throw new Error('Invalid or missing data in dataTable');
46
+ }
47
+
48
+ const { moduleName, searchEntity, searchString } = row;
49
+
50
+ const searchObj = cacheLayer.get(reference);
51
+ let entityIdValue;
52
+
53
+ if (typeof searchObj === 'string') {
54
+ entityIdValue = searchObj;
55
+ } else {
56
+ const jsonPath = searchEntity?.startsWith?.('$') ? searchEntity : `$.${searchEntity}`;
57
+ const result = jp.query(searchObj, jsonPath);
58
+
59
+ if (!result || result.length === 0) {
60
+ throw new Error(`JSONPath query '${jsonPath}' returned no results from cache object for reference: ${reference}`);
61
+ }
62
+
63
+ entityIdValue = result.length === 1 ? result[0] : result;
64
+ }
65
+
66
+ const payload = {
67
+ className: 'applicationDriver.rpc.desk.integrations.search.SearchFakeDataPopulator',
68
+ methodName: 'populateSearchData',
69
+ arguments: {
70
+ module: moduleName,
71
+ searchString: searchString,
72
+ entityId: entityIdValue
73
+ }
74
+ };
75
+ await entityIdReConstructor(payload);
76
+ await executeRpcRequest(page, payload);
77
+ });
@@ -47,15 +47,6 @@ class DataGenerator {
47
47
  throw error;
48
48
  }
49
49
  }
50
- async getDataGenUserExecutionContext(edition, profile) {
51
- try {
52
- const dataGenUserDetails = await (0, _helpers.getUserForSelectedEditionAndProfile)(edition, profile);
53
- return dataGenUserDetails;
54
- } catch (error) {
55
- console.error('Error occurred while fetching data generation user details: ', error);
56
- throw error;
57
- }
58
- }
59
50
  }
60
51
  async function _getGenerator(testInfo, generatorName) {
61
52
  let generator = null;
@@ -10,6 +10,12 @@ Object.defineProperty(exports, "accountLogin", {
10
10
  return _accountLogin.default;
11
11
  }
12
12
  });
13
+ Object.defineProperty(exports, "extractTagInfo", {
14
+ enumerable: true,
15
+ get: function () {
16
+ return _customFixturesHelper.extractTagInfo;
17
+ }
18
+ });
13
19
  Object.defineProperty(exports, "getDefaultActor", {
14
20
  enumerable: true,
15
21
  get: function () {
@@ -73,4 +79,5 @@ Object.defineProperty(exports, "verifyIfCookieFileExists", {
73
79
  var _accountLogin = _interopRequireDefault(require("./accountLogin"));
74
80
  var _checkAuthCookies = require("./checkAuthCookies");
75
81
  var _getUsers = require("./getUsers");
82
+ var _customFixturesHelper = require("../customFixturesHelper");
76
83
  var _loginSteps = _interopRequireDefault(require("./loginSteps"));
@@ -19,7 +19,6 @@ var _ConfigurationHelper = require("./configuration/ConfigurationHelper");
19
19
  let cachedConfig = null;
20
20
  function getDefaultConfig() {
21
21
  return {
22
- isTearDown: true,
23
22
  uatDirectory: _path.default.join(process.cwd(), 'uat'),
24
23
  headless: false,
25
24
  browsers: ['Chrome'],
@@ -9,36 +9,47 @@ var _test = require("@playwright/test");
9
9
  var _path = _interopRequireDefault(require("path"));
10
10
  var _readConfigFile = require("../readConfigFile");
11
11
  var _configUtils = require("./config-utils");
12
- var _ProjectConfiguration = require("./ProjectConfiguration");
13
12
  const uatConfig = (0, _readConfigFile.generateConfigFromFile)();
14
13
  const {
15
- bddMode,
16
14
  browsers,
17
15
  isSmokeTest,
18
- isTearDown,
16
+ trace,
17
+ video,
19
18
  isAuthMode,
20
19
  openReportOn,
21
20
  reportPath,
21
+ bddMode,
22
22
  expectTimeout,
23
23
  testTimeout,
24
24
  authFilePath,
25
25
  viewport,
26
+ featureFilesFolder,
27
+ stepDefinitionsFolder,
28
+ testIdAttribute,
26
29
  globalTimeout,
27
- customReporter,
28
- trace,
29
- video,
30
- testIdAttribute
30
+ customReporter
31
31
  } = uatConfig;
32
32
  const projects = (0, _configUtils.getProjects)({
33
33
  browsers,
34
34
  isAuthMode,
35
35
  isSmokeTest,
36
- isTearDown,
37
36
  authFilePath,
38
37
  expectTimeout,
39
38
  testTimeout,
40
39
  viewport
41
40
  });
41
+ const testDir = (0, _configUtils.getTestDir)(bddMode, {
42
+ featureFilesFolder: (0, _configUtils.getPathsForFeatureFiles)(process.cwd()),
43
+ stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
44
+ outputDir: _path.default.join(process.cwd(), 'uat', '.features-gen'),
45
+ uatPath: _path.default.join(process.cwd(), 'uat')
46
+ });
47
+ const use = {
48
+ trace,
49
+ video,
50
+ viewport,
51
+ testIdAttribute
52
+ };
42
53
  let reporter = [['html', {
43
54
  outputFolder: reportPath,
44
55
  open: openReportOn
@@ -55,22 +66,29 @@ if (customReporter) {
55
66
  * @returns {import('@playwright/test').PlaywrightTestConfig}
56
67
  */
57
68
 
58
- const use = {
59
- trace,
60
- video,
61
- viewport,
62
- testIdAttribute
63
- };
64
- const testDir = (0, _configUtils.getTestDir)(bddMode, {
65
- featureFilesFolder: (0, _configUtils.getPathsForFeatureFiles)(process.cwd()),
66
- stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
67
- outputDir: _path.default.join(process.cwd(), 'uat', '.features-gen'),
68
- uatPath: _path.default.join(process.cwd(), 'uat')
69
- });
70
69
  function getPlaywrightConfig() {
71
- const smokeTestProject = isSmokeTest ? (0, _ProjectConfiguration.smokeTestConfig)() : [];
72
- const setupProject = isAuthMode ? (0, _ProjectConfiguration.setupConfig)() : [];
73
- const cleanupProject = isTearDown ? (0, _ProjectConfiguration.cleanupConfig)() : [];
70
+ const commonConfig = {
71
+ storageState: isAuthMode ? (0, _readConfigFile.getAuthFilePath)(_path.default.resolve(process.cwd(), authFilePath)) : {}
72
+ };
73
+ const dependencies = isAuthMode ? ['setup'] : [];
74
+ const smokeTestProject = isSmokeTest ? smokeTestConfig() : [];
75
+ function smokeTestConfig() {
76
+ const smokeTestDir = (0, _configUtils.getTestDir)(bddMode, {
77
+ featureFilesFolder: _path.default.join(process.cwd(), 'uat', 'smokeTest', '**', '*.feature'),
78
+ stepDefinitionsFolder: _path.default.join(process.cwd(), 'uat', '**', 'steps', '*.spec.js'),
79
+ outputDir: _path.default.join(process.cwd(), 'uat', '.features-smoke-gen'),
80
+ uatPath: _path.default.join(process.cwd(), 'uat', 'smokeTest')
81
+ });
82
+ return [{
83
+ name: 'smokeTest',
84
+ testDir: smokeTestDir,
85
+ use: {
86
+ ...commonConfig
87
+ },
88
+ dependencies: dependencies,
89
+ retries: 0
90
+ }];
91
+ }
74
92
  const playwrightConfig = {
75
93
  testDir,
76
94
  globalTimeout: globalTimeout || 3600000,
@@ -82,7 +100,16 @@ function getPlaywrightConfig() {
82
100
  timeout: expectTimeout
83
101
  },
84
102
  use,
85
- projects: [...setupProject, ...smokeTestProject, ...projects, ...cleanupProject],
103
+ projects: isAuthMode ? [{
104
+ name: 'setup',
105
+ testMatch: /.*\.setup\.js/,
106
+ testDir: _path.default.join(process.cwd(), 'uat'),
107
+ teardown: 'cleanup'
108
+ }, ...smokeTestProject, {
109
+ name: 'cleanup',
110
+ testMatch: /.*\.teardown\.js/,
111
+ testDir: _path.default.join(process.cwd(), 'uat')
112
+ }, ...projects] : [...projects, ...smokeTestProject],
86
113
  ...uatConfig
87
114
  };
88
115
  return playwrightConfig;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ delete require.cache[require.resolve('../core/playwright/runner/Runner')];
4
+ function test() {
5
+ const inputString = "@hc";
6
+ const selectedTag = ["@hc_1234"].reverse().find(tag => tag.startsWith(inputString));
7
+ let tagInput = null;
8
+ if (selectedTag) {
9
+ tagInput = selectedTag.split(`${inputString}_`).pop().toLowerCase();
10
+ }
11
+ console.log(tagInput);
12
+ }
13
+ test();