Skip to content

Add Allure upload support#49

Draft
satvik007 wants to merge 1 commit intomainfrom
feat/allure-upload-pr
Draft

Add Allure upload support#49
satvik007 wants to merge 1 commit intomainfrom
feat/allure-upload-pr

Conversation

@satvik007
Copy link
Collaborator

No description provided.

@claude
Copy link

claude bot commented Feb 9, 2026

Claude finished @satvik007's task in 10m 37s —— View job


Review: Add Allure upload support

  • Read review instructions
  • Gather context and understand changes
  • Launch specialized review subagents (code quality, security, performance, test coverage)
  • Aggregate findings, deduplicate, and post review

CI status: Passing

This PR adds well-structured Allure upload support that follows existing codebase patterns. The Zod schema validation, attachment handling, TMS marker extraction, test fixture organization, and integration test parameterization are all solid work.

I've posted 4 inline review comments on the following issues:

# Severity Location Issue
1 Medium allureParser.ts:134-148 unknown status mapped to passed — could mask real failures; unreachable default branch
2 Medium allureParser.ts:75 No directory validation before readdirSync — poor error UX for invalid paths
3 Low allureParser.ts:170-185 skipStdout/skipStderr mapped to Allure's message/trace — semantic mismatch worth documenting
4 Low allure-parsing.spec.ts:8-13 Missing test coverage for skipStdout/skipStderr on-success behavior (parity gap with JUnit/Playwright tests)

Two additional issues were already flagged by another reviewer and not duplicated: path traversal via attachment sources (line 116) and TMS link marker regex uppercase-only restriction (line 217).

@gemini-code-assist
Copy link

Summary of Changes

Hello @satvik007, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the qas-cli tool by integrating full support for uploading Allure test results. This new capability allows users to seamlessly push their Allure 2 JSON reports, including test case details, statuses, attachments, and TMS links, to QA Sphere. The changes involve adding a new CLI command, implementing a robust Allure parser, and updating the project's internal structure and test suite to accommodate this new report format.

Highlights

  • Allure Upload Support: Introduced a new allure-upload command to the CLI, enabling users to upload Allure test results to QA Sphere.
  • Allure Parser Implementation: Developed a dedicated parser (allureParser.ts) capable of processing Allure 2 JSON results, handling status mapping, folder derivation from labels, attachment resolution, and extracting test case markers from TMS links.
  • Updated CLI Command Structure: Modified src/commands/main.ts and src/commands/resultUpload.ts to integrate the new Allure command, including specific handling for directory-based inputs for Allure results.
  • Comprehensive Test Coverage: Added extensive unit tests for the new Allure parser (allure-parsing.spec.ts) and updated integration tests (result-upload.spec.ts) to ensure the end-to-end upload flow works correctly for Allure results.
  • Documentation and Configuration Updates: Updated CLAUDE.md to reflect the new Allure support and added .prettierignore entries for new fixture files.
Changelog
  • .prettierignore
    • Added src/tests/fixtures/allure/parser/malformed-result.json to prevent reformatting of intentionally malformed JSON.
    • Added AGENTS.md to ignore list.
  • AGENTS.md
    • New file created, acting as a symlink to CLAUDE.md.
  • CLAUDE.md
    • Added a note explaining that AGENTS.md is a symlink to this file.
    • Updated the project overview to include "Allure" as a supported test automation result type.
    • Modified descriptions for CLI entry points and the core upload pipeline to reflect the addition of the allure-upload command and Allure parser.
    • Included "allure-parsing.spec.ts" in the list of test files.
  • package-lock.json
    • Updated package version from 0.4.4 to 0.4.5.
  • src/commands/main.ts
    • Registered a new allure-upload command using ResultUploadCommandModule.
  • src/commands/resultUpload.ts
    • Extended commandTypeDisplayStrings and commandTypeFileExtensions to include allure-upload.
    • Modified the describe getter to provide specific descriptions for Allure uploads (handling directories vs. files).
    • Updated example paths to dynamically generate based on command type, specifically for Allure results directories.
    • Added a new helper function getExamplePath to determine the correct example path for file or directory inputs.
  • src/tests/allure-parsing.spec.ts
    • New file containing unit tests for allureParser.ts.
    • Tests cover parsing results directory, folder derivation from labels, duration calculation, status mapping, message building, attachment resolution, marker extraction from TMS links, parameterized results, and handling of empty/malformed files.
  • src/tests/fixtures/allure/empty-tsuite/tc-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/attachment.txt
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/tc-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/tc-3-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/tc-4-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/tc-5-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/matching-tcases/tc-6-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/attachment.txt
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/tc-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/tc-3-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/tc-4-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/tc-5-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-attachments/tc-6-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-tcases/tc-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-tcases/tc-3-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-tcases/tc-4-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-tcases/tc-5-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/missing-tcases/tc-999-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/broken-feature-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/failed-parent-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/failure-log.txt
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/ignored-attachment.png
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/invalid-schema-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/legacy-testsuite.xml
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/malformed-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/param-1-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/param-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/passed-suite-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/sample-container.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/skipped-package-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/tms-name-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/tms-url-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/parser/unknown-empty-labels-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/without-markers/no-marker-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/without-markers/tc-10-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/fixtures/allure/without-markers/tc-2-result.json
    • New fixture file for Allure parsing tests.
  • src/tests/result-upload.spec.ts
    • Modified fileTypes array to include 'Allure' with inputType: 'directory'.
    • Updated getFixturePath to handle both file and directory inputs for test fixtures.
    • Adjusted various test commands to use the new getFixturePath helper.
  • src/utils/result-upload/ResultUploadCommandHandler.ts
    • Expanded UploadCommandType to include 'allure-upload'.
    • Added a comment to the Parser type definition clarifying handling of file vs. directory data.
    • Mapped allure-upload to the new parseAllureResults function in commandTypeParsers.
    • Modified the file reading loop to conditionally handle Allure results as directories (passing the directory path directly to the parser) and other types as file content.
  • src/utils/result-upload/allureParser.ts
    • New file containing the parseAllureResults function.
    • Defines Zod schemas for Allure result structure (status, status details, attachments, labels, links, parameters).
    • Implements logic to read and parse Allure JSON files from a specified directory.
    • Includes helper functions for: mapAllureStatus (converts Allure statuses to QA Sphere ResultStatus), deriveFolder (extracts folder information from Allure labels), calculateDuration (computes test duration), buildMessage (constructs a message from status details), applyMarkerFromLinks (extracts and applies test case markers from TMS links), and getMarkerFromLinks (helper to find TMS markers from Allure links).
Activity
  • The pull request was created by satvik007.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for uploading Allure test results. However, a high-severity path traversal vulnerability was identified in the Allure result parser. This vulnerability allows an attacker to read and exfiltrate arbitrary files from the system, particularly in CI/CD environments, due to the parser failing to validate attachment source paths. Additionally, the new Allure parser (allureParser.ts) has areas for improvement, including refactoring the main parsing function to use asynchronous I/O for better robustness and clarity, and a correction to a regular expression for more flexible test case marker detection.

attachments: [],
}) - 1

const attachmentSources = (parsed.attachments ?? []).map((attachment) => attachment.source)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

A high-severity path traversal vulnerability exists in the parseAllureResults function. The attachment.source paths are extracted directly from Allure result JSON files without validation. These paths are then used with path.join to combine with the base directory and read files from the filesystem. This allows an attacker to provide malicious paths (e.g., ../../../../etc/passwd) in the source field, potentially leading to the reading and exfiltration of arbitrary files from the system, especially in CI/CD environments. The provided code suggestion adds validation to prevent this.

const attachmentSources = (parsed.attachments ?? []).map((attachment) => {
			const source = attachment.source
			const resolvedPath = path.join(attachmentBaseDirectory, source)
			if (!resolvedPath.startsWith(path.resolve(attachmentBaseDirectory))) {
				throw new Error(`Invalid attachment source: ${source}`)
			}
			return source
		})

}

if (link.name) {
const match = link.name.match(/\b([A-Z]+)-(\d+)\b/)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The regex for extracting a test case marker from a link name is too restrictive. It only allows uppercase letters for the project code and doesn't enforce a minimum number of digits for the sequence number. This is inconsistent with how markers are detected elsewhere in the codebase (e.g., in ResultUploadCommandHandler.ts), which could lead to valid markers not being recognized.

This updated regex allows for alphanumeric project codes (case-insensitive) and requires at least three digits for the sequence number, aligning it with other parts of the application.

			const match = link.name.match(/\b([A-Z0-9]{1,5})-(\d{3,})\b/i)

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

This PR adds well-structured Allure upload support that follows existing codebase patterns. The Zod schema validation, attachment handling, TMS marker extraction, test fixtures, and integration test parameterization are all solid. CI passes.

Issues flagged (4 inline comments):

# Severity File Issue
1 Medium allureParser.ts:134-148 unknown status mapped to passed — could mask real failures; dead default branch
2 Medium allureParser.ts:75 No directory validation before readdirSync — poor error UX for invalid paths
3 Low allureParser.ts:170-185 skipStdout/skipStderr mapped to Allure's message/trace — semantic mismatch worth documenting
4 Low allure-parsing.spec.ts:8-13 Missing test coverage for skipStdout/skipStderr on-success behavior

Already flagged by another reviewer (not duplicated):

  • Path traversal via attachment sources (line 116) — pre-existing pattern across all parsers
  • TMS link marker regex uppercase-only restriction (line 217)

Comment on lines +134 to +148
const mapAllureStatus = (status: z.infer<typeof allureStatusSchema>): ResultStatus => {
switch (status) {
case 'passed':
return 'passed'
case 'failed':
return 'failed'
case 'broken':
return 'blocked'
case 'skipped':
return 'skipped'
case 'unknown':
return 'passed'
default:
return 'passed'
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Questionable status mapping: Allure's unknown status means the framework could not determine the test outcome. Mapping it to passed could silently mask real test failures. Consider mapping unknown to blocked or skipped instead.

Additionally, the default branch on line 147 is unreachable dead code — the Zod enum already constrains input to the five explicitly handled cases, so this branch can never execute. Removing it would make the exhaustiveness clear.

Suggested change
const mapAllureStatus = (status: z.infer<typeof allureStatusSchema>): ResultStatus => {
switch (status) {
case 'passed':
return 'passed'
case 'failed':
return 'failed'
case 'broken':
return 'blocked'
case 'skipped':
return 'skipped'
case 'unknown':
return 'passed'
default:
return 'passed'
}
const mapAllureStatus = (status: z.infer<typeof allureStatusSchema>): ResultStatus => {
switch (status) {
case 'passed':
return 'passed'
case 'failed':
return 'failed'
case 'broken':
return 'blocked'
case 'skipped':
return 'skipped'
case 'unknown':
return 'blocked'
}
}

attachmentBaseDirectory: string,
options: ParserOptions
): Promise<TestCaseResult[]> => {
const entries = readdirSync(resultsDirectory, { withFileTypes: true })
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No directory validation before readdirSync: Unlike the JUnit/Playwright parsers which receive pre-read file content, the Allure parser handles its own I/O. If a user passes a file path or non-existent path, the error will be a raw Node.js ENOENT/ENOTDIR with no user-friendly context.

Consider adding a check before this call:

const stat = statSync(resultsDirectory, { throwIfNoEntry: false })
if (!stat?.isDirectory()) {
    throw new Error(`Allure results path is not a directory: "${resultsDirectory}"`)
}

Comment on lines +170 to +185
const buildMessage = (
statusDetails: z.infer<typeof allureStatusDetailsSchema>,
status: ResultStatus,
options: ParserOptions
) => {
let message = ''

const includeStdout = !(status === 'passed' && options.skipStdout === 'on-success')
const includeStderr = !(status === 'passed' && options.skipStderr === 'on-success')

if (includeStdout && statusDetails?.message) {
message += `<pre><code>${escapeHtml(statusDetails.message)}</code></pre>`
}
if (includeStderr && statusDetails?.trace) {
message += `<pre><code>${escapeHtml(statusDetails.trace)}</code></pre>`
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semantic mismatch with skip options: skipStdout controls whether statusDetails.message is included, and skipStderr controls statusDetails.trace. However, Allure's message is an assertion/error message (not stdout) and trace is a stack trace (not stderr). A user setting --skip-report-stdout on-success would expect actual stdout to be suppressed, not the error summary.

This is a pragmatic mapping (the existing parsers have a similar loose correspondence), but it's worth at minimum a code comment documenting this semantic difference. Consider adding:

// Allure doesn't have stdout/stderr; we map message → stdout and trace → stderr
// for consistency with the skip options used by JUnit and Playwright parsers.

Comment on lines +8 to +13
describe('Allure results parsing', () => {
beforeAll(async () => {
testcases = await parseAllureResults(allureParserBasePath, allureParserBasePath, {
skipStdout: 'never',
skipStderr: 'never',
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test coverage for skipStdout/skipStderr on-success behavior: Every test here uses skipStdout: 'never' and skipStderr: 'never'. The buildMessage function has branching logic for on-success that is never exercised. The JUnit and Playwright parser tests each have dedicated tests for this behavior.

Suggested additions:

  • Test that message is omitted for passed tests when skipStdout is on-success
  • Test that trace is omitted for passed tests when skipStderr is on-success
  • Test that both are still included for failed tests with on-success options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant