@zohodesk/testinglibrary 0.0.90-n20-experimental → 0.0.91-n20-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.
@@ -0,0 +1,8 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(cd /Users/muthu-19817/git/pipeline_scripts/CLIENTUAT && echo \"=== src/desk_client_app.sh \\(worker + run_uat part\\) ===\" && grep -n -A3 -B1 -E \"WORKERS|run_uat|is_cd_execution|shard\" src/desk_client_app.sh)",
5
+ "Read(//Users/muthu-19817/git/pipeline_scripts/CLIENTUAT/**)"
6
+ ]
7
+ }
8
+ }
package/README.md CHANGED
@@ -17,6 +17,13 @@
17
17
 
18
18
  - npm run report
19
19
 
20
+ ### v4.2.0/v3.4.0 - 22-07-2026
21
+
22
+ #### Feature
23
+ - Error segregation support for failing tests.
24
+ - Failures are classified into `CODE`, `CASE`, `TOOL`, and `ENVIRONMENT` using pattern-based matching on runtime browser logs and test stdout/stderr.
25
+ - Controlled via the `failureSegregation` option in `uat-config` (default: `true`). When enabled, runtime logs are collected on failure and used for classification.
26
+
20
27
  ### v4.1.9/v3.3.5 - 03-07-2026
21
28
 
22
29
  #### Feature
@@ -26,7 +26,7 @@ var _default = exports.default = {
26
26
  }, use, testInfo) => {
27
27
  const {
28
28
  testSetup = {},
29
- uatDirectory,
29
+ reportPath,
30
30
  failureSegregation = true
31
31
  } = (0, _readConfigFile.generateConfigFromFile)();
32
32
  await context.addInitScript(() =>
@@ -43,9 +43,8 @@ var _default = exports.default = {
43
43
  return;
44
44
  }
45
45
 
46
- // Keep runtime logs OUTSIDE reportPath (HTML reporter wipes it on onEnd) and
47
- // outside test-results (Playwright outputDir is cleaned each run).
48
- const logsDir = _path.default.join(uatDirectory, 'runtime-logs');
46
+ // Store runtime logs inside playwright-report so they ship with the report.
47
+ const logsDir = _path.default.join(reportPath, 'runtime-logs');
49
48
  const collector = new _logCollector.LogCollector();
50
49
  collector.attachToContext(context);
51
50
  try {
@@ -93,12 +93,12 @@ function getUserForSelectedEditionAndProfile(preferedEdition, preferredProfile,
93
93
 
94
94
  let testingPortal = null;
95
95
  if (!userdata.hasOwnProperty(edition)) {
96
- throw new Error(`There is no "${edition}" edition configured.`);
96
+ throw new Error(`There is no edition configured with the name "${edition}"`);
97
97
  }
98
98
  if (testDataPortal !== null) {
99
99
  testingPortal = userdata[edition].find(editionData => editionData.orgName === testDataPortal);
100
100
  if (!testingPortal) {
101
- 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.`);
102
102
  }
103
103
  } else {
104
104
  testingPortal = userdata[edition] ? userdata[edition][0] : {};
@@ -109,7 +109,7 @@ function getUserForSelectedEditionAndProfile(preferedEdition, preferredProfile,
109
109
  } = testingPortal;
110
110
  selectedProfile = profiles.find(user => user.profile === profile);
111
111
  if (!selectedProfile) {
112
- 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.`);
113
113
  }
114
114
  return {
115
115
  ...editionData,
@@ -42,9 +42,9 @@ const STDIO_RULES = [{
42
42
  }];
43
43
  function resolveLogsDir() {
44
44
  const {
45
- uatDirectory
45
+ reportPath
46
46
  } = (0, _readConfigFile.generateConfigFromFile)();
47
- return _path.default.join(uatDirectory, 'runtime-logs');
47
+ return _path.default.join(reportPath, 'runtime-logs');
48
48
  }
49
49
  function stdioToText(entries = []) {
50
50
  return entries.map(entry => {
@@ -6,6 +6,4 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.CASE_PATTERNS = void 0;
7
7
  // Case patterns: test-case / assertion failures from Playwright output.
8
8
  // Matched against the failing result's stdout + stderr.
9
- const CASE_PATTERNS = exports.CASE_PATTERNS = [
10
- // Generator
11
- /GeneratorError: Generator/i, /DataGeneratorConfigurationError: Data Generator configuration is missing for the profile/i, /HTTP error! status:/i, /status\s*:\s*DATA_GENERATION_ERROR/i];
9
+ const CASE_PATTERNS = exports.CASE_PATTERNS = [/GeneratorError: Generator/i, /DataGeneratorConfigurationError: Data Generator configuration is missing for the profile/i, /HTTP error! status:/i, /status\s*:\s*DATA_GENERATION_ERROR/i, /There is no beta feature configured with the name/i, /The actors data is missing\./i, /There is no edition configured with the name/i, /There is no portal configured with the name/i, /There is no profile configured with the name/i];
@@ -6,4 +6,4 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.CODE_PATTERNS = void 0;
7
7
  // Code patterns: real application defects surfacing as JS exceptions in the
8
8
  // browser. Matched against a flattened text form of each runtime-log event.
9
- const CODE_PATTERNS = exports.CODE_PATTERNS = [/Cannot read properties of (undefined|null)/i, /\bis not a function\b/i, /\bis not defined\b/i, /\bis not iterable\b/i, /\bis not valid JSON\b/i, /\bis not a valid URL\b/i, /\bFailed to load resource: the server responded with a status of 422\b/i];
9
+ const CODE_PATTERNS = exports.CODE_PATTERNS = [/Cannot read properties of (undefined|null)/i, /\bis not a function\b/i, /\bis not defined\b/i, /\bis not iterable\b/i, /\bis not valid JSON\b/i, /\bis not a valid URL\b/i, /\bFailed to load resource: the server responded with a status of 4\b/i];
@@ -9,11 +9,9 @@ exports.TOOL_PATTERNS = void 0;
9
9
  // stdout + stderr text. Add new patterns here to recognise more tool errors.
10
10
  const TOOL_PATTERNS = exports.TOOL_PATTERNS = [/Error during login/i, /fetch failed/i,
11
11
  // Configuration
12
- /Config File Not Exists\. Please provide a/i, /Exception while getting the uat file from the application/i, /There is no beta feature configured with the name/i, /No config mapping found for stage:/i,
13
- // Edition
14
- /edition configured\./i, /portal configured in/i, /profile configured in/i,
12
+ /Config File Not Exists\. Please provide a/i, /Exception while getting the uat file from the application/i, /No config mapping found for stage:/i,
15
13
  // Actor
16
- /file missing\./i, /Error loading actor configuration from/i, /The actors data is missing\./i, /not found in user pages\./i,
14
+ /file missing\./i, /Error loading actor configuration from/i, /not found in user pages\./i,
17
15
  // Module
18
16
  /does not exist\. We have not triggered the execution for this module/i,
19
17
  // Auth
@@ -65,7 +65,7 @@ function failingDetailWithStdio({
65
65
  beforeEach(() => {
66
66
  tempDir = _fs.default.mkdtempSync(_path.default.join(_os.default.tmpdir(), 'failure-tag-'));
67
67
  _readConfigFile.generateConfigFromFile.mockReturnValue({
68
- uatDirectory: tempDir
68
+ reportPath: tempDir
69
69
  });
70
70
  });
71
71
  afterEach(() => {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@zohodesk/testinglibrary",
3
- "version": "0.0.90-n20-experimental",
3
+ "version": "0.0.91-n20-experimental",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@zohodesk/testinglibrary",
9
- "version": "0.0.90-n20-experimental",
9
+ "version": "0.0.91-n20-experimental",
10
10
  "hasInstallScript": true,
11
11
  "license": "ISC",
12
12
  "dependencies": {
@@ -5518,9 +5518,9 @@
5518
5518
  }
5519
5519
  },
5520
5520
  "node_modules/baseline-browser-mapping": {
5521
- "version": "2.10.43",
5522
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz",
5523
- "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==",
5521
+ "version": "2.10.44",
5522
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.44.tgz",
5523
+ "integrity": "sha512-T3ghW+sl/ZJ8w1v/yQx3qvJ9040DWoLBz8JT/CILbAKcFyG9b2MRe75v6W5uXjv6uH1lumK2Kv46y2zSkcej0Q==",
5524
5524
  "license": "Apache-2.0",
5525
5525
  "bin": {
5526
5526
  "baseline-browser-mapping": "dist/cli.cjs"
@@ -6996,9 +6996,9 @@
6996
6996
  }
6997
6997
  },
6998
6998
  "node_modules/electron-to-chromium": {
6999
- "version": "1.5.392",
7000
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.392.tgz",
7001
- "integrity": "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g==",
6999
+ "version": "1.5.393",
7000
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz",
7001
+ "integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==",
7002
7002
  "license": "ISC"
7003
7003
  },
7004
7004
  "node_modules/emittery": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/testinglibrary",
3
- "version": "0.0.90-n20-experimental",
3
+ "version": "0.0.91-n20-experimental",
4
4
  "main": "./build/index.js",
5
5
  "scripts": {
6
6
  "postinstall": "node bin/postinstall.js",
@@ -274,4 +274,4 @@ header {
274
274
  font-size: 1rem;
275
275
  padding: 0 0.5rem;
276
276
  }
277
- </style></head><body><main class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><section id="metadata-container"><div id="timestamp">Started: 2026-07-17 12:56:20</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 (34)</div><div class="summary-passed ">34 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></section><details id="suite-1" class="suite-container" open=""><summary class="suite-info"><div class="suite-path">/Users/muthu-19817/git/testing-framework/src/test/core/playwright/helpers/__tests__/failureTagClassifier.test.js</div><div class="suite-time">0.64s</div></summary><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">leaves retry-passed (flaky) outcomes untagged</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">classifyFailureTags</div><div class="test-title">tags environment when a document abort is present</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags environment for a network/cert failure</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">classifyFailureTags</div><div class="test-title">tags code when an app undefined-property error is present</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">defaults to code (not environment) for a non-document xhr abort</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">classifyFailureTags</div><div class="test-title">tags case when stderr reports DATA_GENERATION_ERROR</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags tool for a known tool pattern in base64 stdout</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags case when stderr matches a case pattern</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">classifyFailureTags</div><div class="test-title">emits only the highest-priority tag (CODE) when CODE and ENVIRONMENT both match</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">classifyFailureTags</div><div class="test-title">defaults to code (not tool) for benign stdout/stderr</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">does not throw for malformed stdio chunk entries</div><div class="test-status">passed</div><div class="test-duration">0.003s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">defaults to code when a failure matches no pattern</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">classifyFailureTags</div><div class="test-title">leaves a passing spec untagged (no default code)</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">records the matching pattern for environment failures</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">classifyFailureDetails</div><div class="test-title">records the matching pattern for code failures from events</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">defaults to code with no matches when events carry no recognised pattern</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">classifyFailureDetails</div><div class="test-title">records tool pattern from stdio</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">records case pattern from stdio without implying code</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">resolves to CASE when a stdio case match outranks a runtime-log code match</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">classifyFailureDetails</div><div class="test-title">keeps case as the tag and does not add code when no runtime log is 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">classifyFailureDetails</div><div class="test-title">records every CODE pattern hit from the runtime log</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">keeps only winning CODE matches when CODE and ENVIRONMENT both match</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">classifyFailureDetails</div><div class="test-title">dedupes identical winning-category matches</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">dedupes annotated dual-match JSONL lines before classifying from disk</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">annotateRuntimeLogEvents</div><div class="test-title">adds pattern CODE on matching events and leaves unmatched events unchanged</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">annotateRuntimeLogEvents</div><div class="test-title">emits one line per matched category when an event hits CODE and ENVIRONMENT</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">failure tag metadata attachment</div><div class="test-title">builds a small JSON attachment when tags are present</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">failure tag metadata attachment</div><div class="test-title">returns null when no tags are present</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">failure tag metadata attachment</div><div class="test-title">replaces an existing metadata attachment</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">mergeFailureTags</div><div class="test-title">places suffixed failure tags first, then existing tags</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">mergeFailureTags</div><div class="test-title">formats all failure tags with suffix</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">mergeFailureTags</div><div class="test-title">does not duplicate an already-present failure tag</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">mergeFailureTags</div><div class="test-title">formats case and code failure tags with suffix</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">regex safety</div><div class="test-title">resets stateful regex for tool pattern checks</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div></div></details></main></body></html>
277
+ </style></head><body><main class="jesthtml-content"><header><h1 id="title">Unit Report</h1></header><section id="metadata-container"><div id="timestamp">Started: 2026-07-20 16:41:35</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 (34)</div><div class="summary-passed ">34 passed</div><div class="summary-failed summary-empty">0 failed</div><div class="summary-pending summary-empty">0 pending</div></div></div></section><details id="suite-1" class="suite-container" open=""><summary class="suite-info"><div class="suite-path">/Users/muthu-19817/git/testing-framework/src/test/core/playwright/helpers/__tests__/failureTagClassifier.test.js</div><div class="suite-time">0.537s</div></summary><div class="suite-tests"><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">leaves retry-passed (flaky) outcomes untagged</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags environment when a document abort is present</div><div class="test-status">passed</div><div class="test-duration">0.004s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags environment for a network/cert failure</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">classifyFailureTags</div><div class="test-title">tags code when an app undefined-property error is present</div><div class="test-status">passed</div><div class="test-duration">0.002s</div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">defaults to code (not environment) for a non-document xhr abort</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">classifyFailureTags</div><div class="test-title">tags case when stderr reports DATA_GENERATION_ERROR</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">tags tool for a known tool pattern in base64 stdout</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">classifyFailureTags</div><div class="test-title">tags case when stderr matches a case pattern</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">emits only the highest-priority tag (CODE) when CODE and ENVIRONMENT both match</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">classifyFailureTags</div><div class="test-title">defaults to code (not tool) for benign stdout/stderr</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureTags</div><div class="test-title">does not throw for malformed stdio chunk entries</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">classifyFailureTags</div><div class="test-title">defaults to code when a failure matches no pattern</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">classifyFailureTags</div><div class="test-title">leaves a passing spec untagged (no default code)</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">records the matching pattern for environment failures</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">classifyFailureDetails</div><div class="test-title">records the matching pattern for code failures from events</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">defaults to code with no matches when events carry no recognised pattern</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">classifyFailureDetails</div><div class="test-title">records tool pattern from stdio</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">classifyFailureDetails</div><div class="test-title">records case pattern from stdio without implying code</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">classifyFailureDetails</div><div class="test-title">resolves to CASE when a stdio case match outranks a runtime-log code match</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">classifyFailureDetails</div><div class="test-title">keeps case as the tag and does not add code when no runtime log is present</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">records every CODE pattern hit from the runtime log</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">classifyFailureDetails</div><div class="test-title">keeps only winning CODE matches when CODE and ENVIRONMENT both match</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">classifyFailureDetails</div><div class="test-title">dedupes identical winning-category matches</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">classifyFailureDetails</div><div class="test-title">dedupes annotated dual-match JSONL lines before classifying from disk</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">annotateRuntimeLogEvents</div><div class="test-title">adds pattern CODE on matching events and leaves unmatched events unchanged</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">annotateRuntimeLogEvents</div><div class="test-title">emits one line per matched category when an event hits CODE and ENVIRONMENT</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">failure tag metadata attachment</div><div class="test-title">builds a small JSON attachment when 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">failure tag metadata attachment</div><div class="test-title">returns null when no tags are present</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">failure tag metadata attachment</div><div class="test-title">replaces an existing metadata attachment</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">mergeFailureTags</div><div class="test-title">places suffixed failure tags first, then existing tags</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">mergeFailureTags</div><div class="test-title">formats all failure tags with suffix</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">mergeFailureTags</div><div class="test-title">does not duplicate an already-present failure tag</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">mergeFailureTags</div><div class="test-title">formats case and code failure tags with suffix</div><div class="test-status">passed</div><div class="test-duration"> </div></div></div><div class="test-result passed"><div class="test-info"><div class="test-suitename">regex safety</div><div class="test-title">resets stateful regex for tool pattern checks</div><div class="test-status">passed</div><div class="test-duration">0.001s</div></div></div></div></details></main></body></html>