@muuktest/amikoo-reporter 1.0.3 → 1.1.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../controlHub/utils.ts"],"names":[],"mappings":"AAUA,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAU9D;AAGD,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B/C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../controlHub/utils.ts"],"names":[],"mappings":"AAeA,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAmBjI;AASD,wBAAsB,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAYlF;AAQD,wBAAsB,aAAa,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAU9F;AAUD,wBAAgB,QAAQ,CACtB,KAAK,EAAE,GAAG,EAAE,EACZ,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,GACpB,GAAG,GAAG,SAAS,CAWjB;AAQD,wBAAsB,aAAa,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,CAU9D;AAQD,wBAAgB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B/C;AAOD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAEzD;AAOD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,GAAG;;;;;;;;EAe9C"}
package/dist/utils.js CHANGED
@@ -3,11 +3,88 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getExecutionNumber = getExecutionNumber;
7
+ exports.getTestsInfo = getTestsInfo;
8
+ exports.buildTestData = buildTestData;
9
+ exports.findTest = findTest;
6
10
  exports.getSuiteNames = getSuiteNames;
7
11
  exports.checkForUpdates = checkForUpdates;
12
+ exports.stripAnsi = stripAnsi;
13
+ exports.extractErrorDetails = extractErrorDetails;
8
14
  const https_1 = __importDefault(require("https"));
9
15
  const path_1 = __importDefault(require("path"));
10
16
  const fs_1 = __importDefault(require("fs"));
17
+ const apiUtils_1 = require("./apiUtils");
18
+ // Module-level constant for ANSI escape code regex (avoids recompilation on each call)
19
+ const ANSI_REGEX = /[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-ntqry=><~]))/g;
20
+ // getExecutionNumber
21
+ // Fetches the execution number and organization ID from the API
22
+ // Parameters:
23
+ // accessToken: string - The access token for API authentication
24
+ // Returns: Promise<{ executionNumber: number; organizationId: string } | null>
25
+ async function getExecutionNumber(accessToken) {
26
+ let result = null;
27
+ const response = await apiUtils_1.api.get('/execution/execution_number', accessToken);
28
+ if (response.success && response.data) {
29
+ console.log(`✔ Retrieved execution number: ${response.data.executionNumber}`);
30
+ result = {
31
+ executionNumber: response.data.executionNumber,
32
+ organizationId: response.data.organizationId
33
+ };
34
+ }
35
+ else {
36
+ console.error('\n✖ Failed to retrieve execution number');
37
+ console.error(` ${response.error}`);
38
+ console.error(' Could not communicate with Amikoo backend.');
39
+ console.error(' Test execution data will not be reported.\n');
40
+ }
41
+ return result;
42
+ }
43
+ // getTestsInfo
44
+ // Fetches test information from API based on suite files
45
+ // Parameters:
46
+ // suite: any - Playwright suite object
47
+ // accessToken: string - The access token for API authentication
48
+ // Returns: Promise<any[]> - Array of test objects from API
49
+ async function getTestsInfo(suite, accessToken) {
50
+ let result = [];
51
+ const testData = await buildTestData(suite);
52
+ const response = await apiUtils_1.api.post('/tests/get_by_file_and_name', accessToken, { testData });
53
+ if (response.success && response.data) {
54
+ result = response.data;
55
+ }
56
+ console.log(`✔ Found ${response?.data?.length || 0} matching tests in Amikoo`);
57
+ return result;
58
+ }
59
+ // buildTestData
60
+ // Builds an array of test data objects from Playwright suite for API lookup
61
+ // Parameters:
62
+ // suite: any - Playwright suite object containing allTests()
63
+ // Returns: Promise<Array<{ file: string; name: string }>> - Array of test data with file and name
64
+ async function buildTestData(suite) {
65
+ const testData = [];
66
+ for (const test of suite.allTests()) {
67
+ const file = path_1.default.basename(test.location.file);
68
+ const name = await getSuiteNames(test);
69
+ testData.push({ file, name });
70
+ }
71
+ return testData;
72
+ }
73
+ // findTest
74
+ // Finds a test from the API results array matching file path and fullTitlePath
75
+ // Parameters:
76
+ // tests: any[] - Array of test objects from API (paths already normalized by backend)
77
+ // fullFilePath: string - The full test file path, already normalized with forward slashes
78
+ // fullTitlePath: string - The full test title path (e.g., "Login > tests")
79
+ // Returns: object | undefined - The matching test object with hash, filePath, branch, fullTitlePath
80
+ function findTest(tests, fullFilePath, fullTitlePath) {
81
+ let result = undefined;
82
+ if (tests && tests.length > 0) {
83
+ // Find the test where both fullTitlePath matches and execution file path ends with API's filePath
84
+ result = tests.find(test => test.fullTitlePath === fullTitlePath && fullFilePath.endsWith(test.filePath));
85
+ }
86
+ return result;
87
+ }
11
88
  // getSuiteNames
12
89
  // Builds the full test title path by traversing parent suites
13
90
  // Parameters:
@@ -23,6 +100,11 @@ async function getSuiteNames(test) {
23
100
  }
24
101
  return [...suites, test.title].join(' > ');
25
102
  }
103
+ // checkForUpdates
104
+ // Checks npm registry for newer versions of @muuktest/amikoo-reporter and logs update notice
105
+ // Compares major and minor version numbers only (ignores patch versions)
106
+ // Parameters: none
107
+ // Returns: Promise<void> - resolves silently regardless of success/failure
26
108
  function checkForUpdates() {
27
109
  const pkgPath = path_1.default.resolve(__dirname, '..', 'package.json');
28
110
  const currentVersion = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8')).version;
@@ -57,4 +139,54 @@ function checkForUpdates() {
57
139
  }
58
140
  });
59
141
  }
142
+ // stripAnsi
143
+ // Removes ANSI escape codes (colors, formatting) from a string
144
+ // Parameters:
145
+ // str: string | undefined - Input string that may contain ANSI codes
146
+ // Returns: string - Clean string without ANSI escape sequences
147
+ function stripAnsi(str) {
148
+ return str?.replace(ANSI_REGEX, '') || '';
149
+ }
150
+ // extractErrorDetails
151
+ // Extracts and formats error details from a test result, including the deepest failed step
152
+ // Parameters:
153
+ // result: any - Playwright test result object containing error and steps
154
+ // Returns: object | null - Error details with message and failed step info, or null if no error
155
+ function extractErrorDetails(result) {
156
+ const error = result.error;
157
+ if (!error)
158
+ return null;
159
+ const failedStep = findDeepestFailedStep(result.steps ?? []);
160
+ return {
161
+ message: stripAnsi(error.message),
162
+ failedStep: failedStep ? {
163
+ title: failedStep.title,
164
+ location: failedStep.location,
165
+ error: stripAnsi(failedStep.error?.message),
166
+ stack: stripAnsi(failedStep.error?.stack),
167
+ } : null,
168
+ };
169
+ }
170
+ // findDeepestFailedStep
171
+ // Traverses step hierarchy using BFS to find the deepest step that has an error
172
+ // Parameters:
173
+ // steps: TestStep[] - Array of top-level test steps to search
174
+ // maxDepth: number - Maximum depth to traverse (default: 20, prevents infinite loops)
175
+ // Returns: TestStep | null - The deepest step with an error, or null if none found
176
+ function findDeepestFailedStep(steps, maxDepth = 20) {
177
+ const queue = steps.map(step => ({ step, depth: 0 }));
178
+ let failedStep = null;
179
+ while (queue.length > 0) {
180
+ const { step, depth } = queue.shift();
181
+ if (depth > maxDepth)
182
+ break;
183
+ if (step.error) {
184
+ failedStep = step;
185
+ }
186
+ if (step.steps?.length) {
187
+ queue.unshift(...step.steps.map(s => ({ step: s, depth: depth + 1 })));
188
+ }
189
+ }
190
+ return failedStep;
191
+ }
60
192
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../controlHub/utils.ts"],"names":[],"mappings":";;;;;AAUA,sCAUC;AAGD,0CA+BC;AAtDD,kDAA0B;AAC1B,gDAAwB;AACxB,4CAAoB;AAGpB,gBAAgB;AAChB,8DAA8D;AAC9D,cAAc;AACd,8DAA8D;AAC9D,yFAAyF;AAClF,KAAK,UAAU,aAAa,CAAC,IAAS;IAC3C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAEzB,OAAO,MAAM,EAAE,CAAC;QACd,IAAI,MAAM,CAAC,KAAK,KAAK,UAAU,IAAI,MAAM,CAAC,KAAK;YAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC9E,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAGD,SAAgB,eAAe;IAC7B,MAAM,OAAO,GAAG,cAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,YAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAE5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAEnE,MAAM,GAAG,GAAG,eAAK,CAAC,GAAG,CAAC,+DAA+D,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE;gBAChH,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACtD,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACjB,IAAI,CAAC;wBACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;wBACxC,IAAI,CAAC,MAAM,EAAE,CAAC;4BAAC,OAAO,EAAE,CAAC;4BAAC,OAAO;wBAAC,CAAC;wBACnC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBAE3D,IAAI,QAAQ,GAAG,QAAQ,IAAI,CAAC,QAAQ,KAAK,QAAQ,IAAI,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;4BAC1E,OAAO,CAAC,GAAG,CAAC,gEAAgE,cAAc,MAAM,MAAM,EAAE,CAAC,CAAC;4BAC1G,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAC;wBACnF,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC,CAAC,yBAAyB,CAAC,CAAC;oBACrC,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACjC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../controlHub/utils.ts"],"names":[],"mappings":"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"}
@@ -36,11 +36,11 @@ async function processVideos(videos, organizationId, executionNumber, token) {
36
36
  uploadUrls = response.success ? response.data : null;
37
37
  }
38
38
  else {
39
- console.log('No videos found to process');
39
+ console.log('No videos found to process');
40
40
  }
41
41
  }
42
42
  else {
43
- console.log('Missing required parameters for video processing');
43
+ console.log('Missing required parameters for video processing');
44
44
  }
45
45
  return { videos: processed, uploadUrls };
46
46
  }
@@ -59,14 +59,14 @@ async function uploadVideoToS3(filePath, uploadUrl) {
59
59
  });
60
60
  success = response.ok;
61
61
  if (!success) {
62
- console.log('Upload failed with status:', response.status);
62
+ console.log(` ✖ Upload failed with status: ${response.status}`);
63
63
  }
64
64
  /* } catch (error) {
65
65
  console.log('Error uploading video:', error);
66
66
  }*/
67
67
  }
68
68
  else {
69
- console.log('Video file not found:', filePath);
69
+ console.log(` ✖ Video file not found: ${filePath}`);
70
70
  }
71
71
  return success;
72
72
  }
@@ -75,7 +75,7 @@ async function uploadVideoToS3(filePath, uploadUrl) {
75
75
  */
76
76
  async function uploadVideosToS3(videos, uploadUrls) {
77
77
  const results = [];
78
- console.log(`Starting upload of ${videos.length} videos to S3`);
78
+ console.log(`📹 Uploading ${videos.length} video(s) to S3...`);
79
79
  if (videos.length && uploadUrls?.length) {
80
80
  // Create a map for quick lookup by S3 filename
81
81
  const urlMap = new Map(uploadUrls.map(u => [u.fileName, u.uploadUrl]));
@@ -87,17 +87,17 @@ async function uploadVideosToS3(videos, uploadUrls) {
87
87
  return { fileName: video.s3FileName, success };
88
88
  }
89
89
  else {
90
- console.log('No upload URL found for:', video.s3FileName);
90
+ console.log(` ✖ No upload URL found for: ${video.s3FileName}`);
91
91
  return { fileName: video.s3FileName, success: false, error: 'No upload URL' };
92
92
  }
93
93
  });
94
94
  const uploadResults = await Promise.all(uploadPromises);
95
95
  results.push(...uploadResults);
96
96
  const successCount = results.filter(r => r.success).length;
97
- console.log(`Uploaded ${successCount}/${results.length} videos to S3`);
97
+ console.log(`✔ Uploaded ${successCount}/${results.length} video(s) to S3`);
98
98
  }
99
99
  else {
100
- console.log('No videos or upload URLs provided');
100
+ console.log('No videos or upload URLs provided');
101
101
  }
102
102
  return results;
103
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"videoUtils.js","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"videoUtils.js","sourceRoot":"","sources":["../controlHub/videoUtils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { AmikooArtifact } from './amikooArtifacts';
2
+ export declare function buildZipForTest(zipPath: string, specFile: string, artifacts: AmikooArtifact[], repoRoot: string): Promise<void>;
3
+ //# sourceMappingURL=zipUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zipUtils.d.ts","sourceRoot":"","sources":["../controlHub/zipUtils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AASnD,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,cAAc,EAAE,EAC3B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildZipForTest = buildZipForTest;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const archiver_1 = __importDefault(require("archiver"));
10
+ const SOURCE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs', '.mts', '.cts'];
11
+ async function buildZipForTest(zipPath, specFile, artifacts, repoRoot) {
12
+ return new Promise((resolve, reject) => {
13
+ const output = fs_1.default.createWriteStream(zipPath);
14
+ const archive = (0, archiver_1.default)('zip', { zlib: { level: 9 } });
15
+ output.on('close', () => resolve());
16
+ archive.on('error', reject);
17
+ archive.pipe(output);
18
+ for (const art of artifacts) {
19
+ if (!fs_1.default.existsSync(art.localPath))
20
+ continue;
21
+ archive.file(art.localPath, { name: `failure-data/${art.attachmentName}` });
22
+ }
23
+ if (specFile && fs_1.default.existsSync(specFile)) {
24
+ const tsconfigPaths = loadTsconfigPaths(repoRoot);
25
+ const testFiles = collectTestFiles(specFile, repoRoot, tsconfigPaths);
26
+ for (const absPath of testFiles) {
27
+ const relPath = path_1.default.relative(repoRoot, absPath).split(path_1.default.sep).join('/');
28
+ archive.file(absPath, { name: `test-files/${relPath}` });
29
+ }
30
+ }
31
+ else if (specFile) {
32
+ console.warn(`[amikoo-upload] spec file not found on disk: ${specFile}`);
33
+ }
34
+ archive.finalize();
35
+ });
36
+ }
37
+ function collectTestFiles(specFile, repoRoot, tsconfigPaths) {
38
+ const visited = new Set();
39
+ const queue = [path_1.default.resolve(specFile)];
40
+ while (queue.length) {
41
+ const current = queue.shift();
42
+ if (visited.has(current))
43
+ continue;
44
+ if (!isInsideRepo(current, repoRoot))
45
+ continue;
46
+ if (!fs_1.default.existsSync(current))
47
+ continue;
48
+ visited.add(current);
49
+ let source;
50
+ try {
51
+ source = fs_1.default.readFileSync(current, 'utf8');
52
+ }
53
+ catch {
54
+ continue;
55
+ }
56
+ for (const specifier of extractImportSpecifiers(source)) {
57
+ const resolved = resolveSpecifier(specifier, current, repoRoot, tsconfigPaths);
58
+ if (resolved && !visited.has(resolved)) {
59
+ queue.push(resolved);
60
+ }
61
+ }
62
+ }
63
+ return Array.from(visited);
64
+ }
65
+ function extractImportSpecifiers(source) {
66
+ const specifiers = [];
67
+ const patterns = [
68
+ /(?:^|\s)import\s+(?:[^'"`;]+?\s+from\s+)?['"]([^'"]+)['"]/g,
69
+ /(?:^|[^.\w])import\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
70
+ /(?:^|[^.\w])require\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
71
+ ];
72
+ for (const re of patterns) {
73
+ let m;
74
+ while ((m = re.exec(source)) !== null) {
75
+ specifiers.push(m[1]);
76
+ }
77
+ }
78
+ return specifiers;
79
+ }
80
+ function resolveSpecifier(specifier, fromFile, repoRoot, tsconfigPaths) {
81
+ if (specifier.startsWith('@playwright/') || specifier.startsWith('@muuktest/')) {
82
+ return null;
83
+ }
84
+ if (specifier.startsWith('./') || specifier.startsWith('../')) {
85
+ return resolveFile(path_1.default.resolve(path_1.default.dirname(fromFile), specifier), repoRoot);
86
+ }
87
+ if (tsconfigPaths) {
88
+ const aliased = resolveWithTsconfigPaths(specifier, tsconfigPaths, repoRoot);
89
+ if (aliased)
90
+ return aliased;
91
+ }
92
+ return null;
93
+ }
94
+ function resolveFile(candidatePath, repoRoot) {
95
+ if (!isInsideRepo(candidatePath, repoRoot))
96
+ return null;
97
+ if (fs_1.default.existsSync(candidatePath) && fs_1.default.statSync(candidatePath).isFile()) {
98
+ return candidatePath;
99
+ }
100
+ for (const ext of SOURCE_EXTENSIONS) {
101
+ const withExt = candidatePath + ext;
102
+ if (fs_1.default.existsSync(withExt) && fs_1.default.statSync(withExt).isFile())
103
+ return withExt;
104
+ }
105
+ if (fs_1.default.existsSync(candidatePath) && fs_1.default.statSync(candidatePath).isDirectory()) {
106
+ for (const ext of SOURCE_EXTENSIONS) {
107
+ const indexFile = path_1.default.join(candidatePath, 'index' + ext);
108
+ if (fs_1.default.existsSync(indexFile))
109
+ return indexFile;
110
+ }
111
+ }
112
+ return null;
113
+ }
114
+ function isInsideRepo(absPath, repoRoot) {
115
+ const normalized = path_1.default.resolve(absPath);
116
+ const root = path_1.default.resolve(repoRoot);
117
+ if (!normalized.startsWith(root + path_1.default.sep) && normalized !== root)
118
+ return false;
119
+ return !normalized.split(path_1.default.sep).includes('node_modules');
120
+ }
121
+ function resolveWithTsconfigPaths(specifier, tsconfig, repoRoot) {
122
+ for (const [pattern, targets] of Object.entries(tsconfig.paths)) {
123
+ const match = matchAliasPattern(pattern, specifier);
124
+ if (match === null)
125
+ continue;
126
+ for (const target of targets) {
127
+ const candidate = path_1.default.resolve(tsconfig.baseUrl, target.replace('*', match));
128
+ const resolved = resolveFile(candidate, repoRoot);
129
+ if (resolved)
130
+ return resolved;
131
+ }
132
+ }
133
+ return null;
134
+ }
135
+ function matchAliasPattern(pattern, specifier) {
136
+ if (pattern.endsWith('/*')) {
137
+ const prefix = pattern.slice(0, -1);
138
+ if (specifier.startsWith(prefix))
139
+ return specifier.slice(prefix.length);
140
+ return null;
141
+ }
142
+ return pattern === specifier ? '' : null;
143
+ }
144
+ function loadTsconfigPaths(repoRoot) {
145
+ const tsconfigPath = path_1.default.join(repoRoot, 'tsconfig.json');
146
+ if (!fs_1.default.existsSync(tsconfigPath))
147
+ return null;
148
+ try {
149
+ const raw = fs_1.default.readFileSync(tsconfigPath, 'utf8');
150
+ const stripped = raw.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:])\/\/.*$/gm, '$1');
151
+ const parsed = JSON.parse(stripped);
152
+ const baseUrl = parsed?.compilerOptions?.baseUrl;
153
+ const paths = parsed?.compilerOptions?.paths;
154
+ if (!paths)
155
+ return null;
156
+ return {
157
+ baseUrl: path_1.default.resolve(repoRoot, baseUrl || '.'),
158
+ paths,
159
+ };
160
+ }
161
+ catch {
162
+ return null;
163
+ }
164
+ }
165
+ //# sourceMappingURL=zipUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zipUtils.js","sourceRoot":"","sources":["../controlHub/zipUtils.ts"],"names":[],"mappings":"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"}
package/install.js CHANGED
@@ -8,6 +8,7 @@ const packageRoot = __dirname;
8
8
 
9
9
  const REPORTER_MODULE = '@muuktest/amikoo-reporter';
10
10
  const REPORTER_ENTRY = `['${REPORTER_MODULE}']`;
11
+ const AMIKOO_PLAYWRIGHT_PACKAGE = '@muuktest/amikoo-playwright/reporter';
11
12
 
12
13
  // ---------------------------------------------------------------------------
13
14
  // Helpers
@@ -32,6 +33,15 @@ function isCommented(content, pos) {
32
33
  return isLineComment(content, pos) || isInsideBlockComment(content, pos);
33
34
  }
34
35
 
36
+ function hasActiveOccurrence(content, needle) {
37
+ let idx = 0;
38
+ while ((idx = content.indexOf(needle, idx)) !== -1) {
39
+ if (!isCommented(content, idx)) return true;
40
+ idx += needle.length;
41
+ }
42
+ return false;
43
+ }
44
+
35
45
  /**
36
46
  * Find the first uncommented `reporter` property (e.g. `reporter:` or `reporter :`)
37
47
  */
@@ -245,6 +255,86 @@ function tryNoReporter(content) {
245
255
  return addReporterProperty(content);
246
256
  }
247
257
 
258
+ // ---------------------------------------------------------------------------
259
+ // Reporter order enforcement – ensure Amikoo reporter precedes ControlHub
260
+ // ---------------------------------------------------------------------------
261
+
262
+ function parseTopLevelEntries(content, from, to) {
263
+ const entries = [];
264
+ let entryStart = -1;
265
+ let depth = 0;
266
+ let inString = false;
267
+ let stringChar = '';
268
+ for (let i = from; i < to; i++) {
269
+ const ch = content[i];
270
+ if (inString) {
271
+ if (ch === '\\') { i++; continue; }
272
+ if (ch === stringChar) inString = false;
273
+ continue;
274
+ }
275
+ if (ch === "'" || ch === '"' || ch === '`') {
276
+ if (entryStart === -1 && depth === 0) entryStart = i;
277
+ inString = true;
278
+ stringChar = ch;
279
+ continue;
280
+ }
281
+ if (ch === '[' || ch === '{' || ch === '(') {
282
+ if (entryStart === -1 && depth === 0) entryStart = i;
283
+ depth++;
284
+ } else if (ch === ']' || ch === '}' || ch === ')') {
285
+ depth--;
286
+ } else if (ch === ',' && depth === 0) {
287
+ if (entryStart !== -1) {
288
+ entries.push({ start: entryStart, end: i });
289
+ entryStart = -1;
290
+ }
291
+ } else if (!/\s/.test(ch) && entryStart === -1 && depth === 0) {
292
+ entryStart = i;
293
+ }
294
+ }
295
+ if (entryStart !== -1) {
296
+ let endPos = to;
297
+ while (endPos > entryStart && /\s/.test(content[endPos - 1])) endPos--;
298
+ entries.push({ start: entryStart, end: endPos });
299
+ }
300
+ return entries;
301
+ }
302
+
303
+ function ensureReporterOrder(content) {
304
+ if (!hasActiveOccurrence(content, REPORTER_MODULE)) return content;
305
+ if (!hasActiveOccurrence(content, AMIKOO_PLAYWRIGHT_PACKAGE)) return content;
306
+
307
+ const regex = /reporter\s*:\s*\[/g;
308
+ let m;
309
+ let arrayOpen = -1;
310
+ while ((m = regex.exec(content)) !== null) {
311
+ if (!isCommented(content, m.index)) {
312
+ arrayOpen = m.index + m[0].length - 1;
313
+ break;
314
+ }
315
+ }
316
+ if (arrayOpen === -1) return content;
317
+
318
+ const arrayClose = findMatchingBracket(content, arrayOpen);
319
+ if (arrayClose === -1) return content;
320
+
321
+ const entries = parseTopLevelEntries(content, arrayOpen + 1, arrayClose);
322
+ const amikooIdx = entries.findIndex(e => content.slice(e.start, e.end).includes(AMIKOO_PLAYWRIGHT_PACKAGE));
323
+ const controlhubIdx = entries.findIndex(e => content.slice(e.start, e.end).includes(REPORTER_MODULE));
324
+ if (amikooIdx === -1 || controlhubIdx === -1) return content;
325
+ if (amikooIdx < controlhubIdx) return content;
326
+
327
+ const amikoo = entries[amikooIdx];
328
+ const controlhub = entries[controlhubIdx];
329
+ return (
330
+ content.slice(0, controlhub.start) +
331
+ content.slice(amikoo.start, amikoo.end) +
332
+ content.slice(controlhub.end, amikoo.start) +
333
+ content.slice(controlhub.start, controlhub.end) +
334
+ content.slice(amikoo.end)
335
+ );
336
+ }
337
+
248
338
  // ---------------------------------------------------------------------------
249
339
  // Fallback – insert before the last closing of the config object
250
340
  // ---------------------------------------------------------------------------
@@ -384,33 +474,39 @@ function configurePlaywright() {
384
474
  const ext = path.extname(configPath);
385
475
  console.log(` Found playwright.config${ext}`);
386
476
 
387
- let content = fs.readFileSync(configPath, 'utf8');
477
+ const original = fs.readFileSync(configPath, 'utf8');
388
478
 
389
- // Already configured?
390
- if (content.includes(REPORTER_MODULE)) {
391
- console.log(' amikoo-reporter already configured. Skipping.\n');
392
- // Still ensure video is on
393
- const withVideo = ensureVideoOn(content);
394
- if (withVideo !== content) {
395
- fs.writeFileSync(configPath, withVideo, 'utf8');
396
- console.log(" Ensured video: 'on' in playwright config.\n");
397
- }
398
- return;
479
+ // Already configured (uncommented)?
480
+ const alreadyConfigured = hasActiveOccurrence(original, REPORTER_MODULE);
481
+
482
+ let modified;
483
+ if (alreadyConfigured) {
484
+ modified = original;
485
+ } else {
486
+ modified =
487
+ tryArrayAppend(original) ||
488
+ tryStringToArray(original) ||
489
+ tryCommentedReporter(original) ||
490
+ tryNoReporter(original) ||
491
+ tryFallback(original);
399
492
  }
400
493
 
401
- // Try strategies in order
402
- const modified =
403
- tryArrayAppend(content) ||
404
- tryStringToArray(content) ||
405
- tryCommentedReporter(content) ||
406
- tryNoReporter(content) ||
407
- tryFallback(content);
494
+ // Enforce Amikoo-before-ControlHub order when both are present.
495
+ const reordered = ensureReporterOrder(modified);
408
496
 
409
- // Ensure video: 'on' in use block
410
- const withVideo = ensureVideoOn(modified);
497
+ // Ensure video: 'on' in use block.
498
+ const withVideo = ensureVideoOn(reordered);
411
499
 
412
- fs.writeFileSync(configPath, withVideo, 'utf8');
413
- console.log(' amikoo-reporter added to playwright config.\n');
500
+ if (withVideo !== original) {
501
+ fs.writeFileSync(configPath, withVideo, 'utf8');
502
+ if (alreadyConfigured) {
503
+ console.log(' amikoo-reporter already configured. Adjusted config where needed.\n');
504
+ } else {
505
+ console.log(' amikoo-reporter added to playwright config.\n');
506
+ }
507
+ } else {
508
+ console.log(' amikoo-reporter already configured. No changes needed.\n');
509
+ }
414
510
  }
415
511
 
416
512
  // ---------------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@muuktest/amikoo-reporter",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "Playwright reporter for Amikoo - automatically installs and configures test reporting to Amikoo AI",
5
5
  "main": "dist/controlHubReporter.js",
6
6
  "types": "dist/controlHubReporter.d.ts",
@@ -43,10 +43,12 @@
43
43
  "@playwright/test": "^1.0.0"
44
44
  },
45
45
  "devDependencies": {
46
+ "@types/archiver": "^6.0.3",
46
47
  "@types/node": "^25.3.5",
47
48
  "typescript": "^6.0.2"
48
49
  },
49
50
  "dependencies": {
51
+ "archiver": "^7.0.1",
50
52
  "dotenv": "^17.3.1"
51
53
  }
52
54
  }