Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ jobs:
- name: Install dependencies
run: npm install

- name: Run linter
run: npm run lint
- name: Run checks
run: npm run check

- name: Run tests
run: npm test
Expand Down
10 changes: 3 additions & 7 deletions .github/workflows/npm.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
name: Publish to npm

on:
workflow_dispatch:
pull_request:
types: [closed]
branches:
- main
release:
types: [published]

permissions:
contents: write
Expand All @@ -14,7 +11,6 @@ permissions:
jobs:
publish:
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'pull_request' && github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'publish'))

steps:
- name: Checkout repository
Expand Down Expand Up @@ -57,7 +53,7 @@ jobs:
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Notify success
if: steps.compare.outputs.publish == 'true' && success()
run: |
Expand Down
3 changes: 2 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
npm run check
npm run typecheck
npx lint-staged
10 changes: 9 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,13 @@
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": true
"useTabs": true,
"overrides": [
{
"files": ["*.md", "*.json"],
"options": {
"useTabs": false
}
}
]
}
106 changes: 65 additions & 41 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ The CLI requires the following variables to be defined:
- `QAS_URL` - Base URL of your QA Sphere instance (e.g., https://qas.eu2.qasphere.com)

These variables could be defined:

- as environment variables
- in .env of a current working directory
- in a special `.qaspherecli` configuration file in your project directory (or any parent directory)

Example: .qaspherecli

```sh
# .qaspherecli
QAS_TOKEN=your_token
Expand All @@ -57,7 +59,6 @@ QAS_URL=https://qas.eu1.qasphere.com
# QAS_URL=https://qas.eu1.qasphere.com
```


## Commands: `junit-upload`, `playwright-json-upload`

The `junit-upload` and `playwright-json-upload` commands upload test results from JUnit XML and Playwright JSON reports to QA Sphere respectively. Both commands can either create a new test run within a QA Sphere project or upload results to an existing run, and they share the same set of options.
Expand Down Expand Up @@ -97,59 +98,74 @@ Ensure the required environment variables are defined before running these comma
**Note:** The following examples use `junit-upload`, but you can replace it with `playwright-json-upload` and adjust the file extension from `.xml` to `.json` to upload Playwright JSON reports instead.

1. Create a new test run with default name template (`Automated test run - {MMM} {DD}, {YYYY}, {hh}:{mm}:{ss} {AMPM}`) and upload results:
```bash
qasphere junit-upload ./test-results.xml
```

```bash
qasphere junit-upload ./test-results.xml
```

2. Upload to an existing test run:
```bash
qasphere junit-upload -r https://qas.eu1.qasphere.com/project/P1/run/23 ./test-results.xml
```

```bash
qasphere junit-upload -r https://qas.eu1.qasphere.com/project/P1/run/23 ./test-results.xml
```

3. Create a new test run with name template without any placeholders and upload results:
```bash
qasphere junit-upload --run-name "v1.4.4-rc5" ./test-results.xml
```

```bash
qasphere junit-upload --run-name "v1.4.4-rc5" ./test-results.xml
```

4. Create a new test run with name template using environment variables and date placeholders and upload results:
```bash
qasphere junit-upload --run-name "CI Build {env:BUILD_NUMBER} - {YYYY}-{MM}-{DD}" ./test-results.xml
```
If `BUILD_NUMBER` environment variable is set to `v1.4.4-rc5` and today's date is January 1, 2025, the run would be named "CI Build v1.4.4-rc5 - 2025-01-01".

```bash
qasphere junit-upload --run-name "CI Build {env:BUILD_NUMBER} - {YYYY}-{MM}-{DD}" ./test-results.xml
```

If `BUILD_NUMBER` environment variable is set to `v1.4.4-rc5` and today's date is January 1, 2025, the run would be named "CI Build v1.4.4-rc5 - 2025-01-01".

5. Create a new test run with name template using date/time placeholders and upload results:
```bash
qasphere junit-upload --run-name "Nightly Tests {YYYY}/{MM}/{DD} {HH}:{mm}" ./test-results.xml
```
If the current time is 10:34 PM on January 1, 2025, the run would be named "Nightly Tests 2025/01/01 22:34".

```bash
qasphere junit-upload --run-name "Nightly Tests {YYYY}/{MM}/{DD} {HH}:{mm}" ./test-results.xml
```

If the current time is 10:34 PM on January 1, 2025, the run would be named "Nightly Tests 2025/01/01 22:34".

6. Upload results with attachments:
```bash
qasphere junit-upload --attachments ./test1.xml
```

```bash
qasphere junit-upload --attachments ./test1.xml
```

7. Force upload even with missing test cases or attachments:
```bash
qasphere junit-upload --force ./test-results.xml
```

```bash
qasphere junit-upload --force ./test-results.xml
```

8. Suppress unmatched test messages (useful during gradual test case linking):
```bash
qasphere junit-upload --ignore-unmatched ./test-results.xml
```
This will show only a summary like "Skipped 5 unmatched tests" instead of individual error messages for each unmatched test.

```bash
qasphere junit-upload --ignore-unmatched ./test-results.xml
```

This will show only a summary like "Skipped 5 unmatched tests" instead of individual error messages for each unmatched test.

9. Skip stdout/stderr for passed tests to reduce result payload size:
```bash
qasphere junit-upload --skip-report-stdout on-success ./test-results.xml
```
This will exclude stdout from passed tests while still including it for failed, blocked, or skipped tests.

```bash
qasphere junit-upload --skip-report-stdout on-success ./test-results.xml
```

This will exclude stdout from passed tests while still including it for failed, blocked, or skipped tests.

Skip both stdout and stderr for passed tests:
```bash
qasphere junit-upload --skip-report-stdout on-success --skip-report-stderr on-success ./test-results.xml
```
This is useful when you have verbose logging in tests but only want to see output for failures.

```bash
qasphere junit-upload --skip-report-stdout on-success --skip-report-stderr on-success ./test-results.xml
```

This is useful when you have verbose logging in tests but only want to see output for failures.

## Test Report Requirements

Expand All @@ -163,6 +179,7 @@ Test case names in JUnit XML reports must include a QA Sphere test case marker i
- **SEQUENCE** - Test case sequence number (minimum 3 digits, zero-padded if needed)

**Examples:**

- `PRJ-002: Login with valid credentials`
- `Login with invalid credentials: PRJ-1312`

Expand All @@ -177,11 +194,18 @@ Playwright JSON reports support two methods for referencing test cases (checked
- `description`: Full QA Sphere test case URL

```typescript
test('user login', {
annotation: { type: 'test case', description: 'https://qas.eu1.qasphere.com/project/PRJ/tcase/123' }
}, async ({ page }) => {
// test code
});
test(
'user login',
{
annotation: {
type: 'test case',
description: 'https://qas.eu1.qasphere.com/project/PRJ/tcase/123',
},
},
async ({ page }) => {
// test code
}
)
```

2. **Test Case Marker in Name** - Include the `PROJECT-SEQUENCE` marker in the test name (same format as JUnit XML)
Expand Down
2 changes: 2 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import globals from 'globals'
import pluginJs from '@eslint/js'
import prettierConfig from 'eslint-config-prettier'
import tseslint from 'typescript-eslint'

export default [
{ languageOptions: { globals: globals.node } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
prettierConfig,
{ ignores: ['build/*'] },
]
Loading