Skip to content

Commit 683b6d7

Browse files
committed
feat: enable public report link generation for test runs
- Updated `ApiClientV1` to include a method for enabling public report links for test runs. - Enhanced `TestOpsReporter` to trigger public report link generation upon test run completion if configured. - Added new configuration option `showPublicReportLink` in `TestopsConfig` and updated `ConfigLoader` to support it. - Introduced logging for public report link generation in the `Logger` class. - Created unit tests to validate the functionality of public report link generation from environment variables and configuration files. - Incremented project version to `2.1.7` in `composer.json` and updated `composer.lock` with new content hash. - Updated `README.md` to document the new public report link feature and its configuration.
1 parent 6e48526 commit 683b6d7

File tree

11 files changed

+274
-2
lines changed

11 files changed

+274
-2
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ All configuration options are listed in the table below:
5151
| Qase test plan ID | `testops.plan.id` | `QASE_TESTOPS_PLAN_ID` | undefined | No | Any integer |
5252
| Size of batch for sending test results | `testops.batch.size` | `QASE_TESTOPS_BATCH_SIZE` | `200` | No | Any integer |
5353
| Enable defects for failed test cases | `testops.defect` | `QASE_TESTOPS_DEFECT` | `False` | No | `True`, `False` |
54+
| Enable public report link generation after run completion | `testops.showPublicReportLink` | `QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK` | `False` | No | `True`, `False` |
5455
| Configuration values to associate with test run | `testops.configurations.values` | `QASE_TESTOPS_CONFIGURATIONS_VALUES` | `[]` | No | Comma-separated key=value pairs |
5556
| Create configuration groups and values if they don't exist | `testops.configurations.createIfNotExists` | `QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS` | `False` | No | `True`, `False` |
5657
| Status filter for test results | `testops.statusFilter` | `QASE_TESTOPS_STATUS_FILTER` | `[]` | No | Comma-separated string |
@@ -94,6 +95,7 @@ All configuration options are listed in the table below:
9495
}
9596
},
9697
"defect": false,
98+
"showPublicReportLink": true,
9799
"project": "<project_code>",
98100
"batch": {
99101
"size": 100
@@ -130,6 +132,7 @@ export QASE_TESTOPS_CONFIGURATIONS_CREATE_IF_NOT_EXISTS=true
130132
export QASE_TESTOPS_STATUS_FILTER="skipped,blocked,untested"
131133
export QASE_TESTOPS_RUN_EXTERNAL_LINK_TYPE="jiraCloud"
132134
export QASE_TESTOPS_RUN_EXTERNAL_LINK_URL="PROJ-123"
135+
export QASE_TESTOPS_SHOW_PUBLIC_REPORT_LINK=true
133136
export QASE_STATUS_MAPPING="invalid=failed,skipped=passed"
134137
```
135138

@@ -138,6 +141,7 @@ The `QASE_TESTOPS_CONFIGURATIONS_VALUES` should be a comma-separated list of key
138141
### How Configurations Work
139142

140143
Configurations in Qase TestOps work as follows:
144+
141145
* **name** field represents the configuration group (e.g., "browser", "environment")
142146
* **value** field represents the configuration item within that group (e.g., "chrome", "staging")
143147
* When `createIfNotExists` is true, the system will:

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"scripts": {
4141
"test": "phpunit"
4242
},
43-
"version": "2.1.6",
43+
"version": "2.1.7",
4444
"config": {
4545
"platform": {
4646
"php": "8.0"

composer.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Client/ApiClientV1.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,4 +340,36 @@ public function runUpdateExternalIssue(string $code, string $type, array $links)
340340
$this->logger->error('Failed to update external issue: ' . $e->getMessage());
341341
}
342342
}
343+
344+
public function enablePublicReport(string $code, int $runId): ?string
345+
{
346+
try {
347+
$this->logger->debug('Enable public report for run: ' . $runId);
348+
349+
// Make PATCH request to enable public report
350+
$response = $this->client->request('PATCH', $this->clientConfig->getHost() . '/run/' . $code . '/' . $runId . '/public', [
351+
'headers' => [
352+
'Token' => $this->config->api->getToken(),
353+
'Content-Type' => 'application/json',
354+
],
355+
'json' => [
356+
'status' => true,
357+
],
358+
]);
359+
360+
$responseData = json_decode($response->getBody()->getContents(), true);
361+
362+
if (isset($responseData['result']['hash'])) {
363+
$publicUrl = $this->appUrl . '/public/report/' . $responseData['result']['hash'];
364+
$this->logger->info('Public report link: ' . $publicUrl);
365+
return $publicUrl;
366+
}
367+
368+
$this->logger->warning('Public report hash not found in response');
369+
return null;
370+
} catch (Exception $e) {
371+
$this->logger->warning('Failed to generate public report link: ' . $e->getMessage());
372+
return null;
373+
}
374+
}
343375
}

src/Config/ConfigLoader.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ private function loadFromJsonFile(): QaseConfig
7070

7171
if (isset($data['testops']['project'])) $config->testops->setProject($data['testops']['project']);
7272
if (isset($data['testops']['defect'])) $config->testops->setDefect($data['testops']['defect']);
73+
if (isset($data['testops']['showPublicReportLink'])) $config->testops->setShowPublicReportLink($data['testops']['showPublicReportLink']);
7374

7475
if (isset($data['testops']['api']['token'])) $config->testops->api->setToken($data['testops']['api']['token']);
7576
if (isset($data['testops']['api']['host'])) $config->testops->api->setHost($data['testops']['api']['host']);
@@ -147,6 +148,9 @@ private function overrideWithEnvVariables(): void
147148
case "qase_testops_defect":
148149
$this->config->testops->setDefect($value);
149150
break;
151+
case "qase_testops_show_public_report_link":
152+
$this->config->testops->setShowPublicReportLink(filter_var($value, FILTER_VALIDATE_BOOLEAN));
153+
break;
150154
case "qase_testops_api_token":
151155
$this->config->testops->api->setToken($value);
152156
break;

src/Interfaces/ClientInterface.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,13 @@ public function createConfigurationItem(string $code, int $groupId, string $titl
6161
* @return void
6262
*/
6363
public function runUpdateExternalIssue(string $code, string $type, array $links): void;
64+
65+
/**
66+
* Enable public report for a test run
67+
*
68+
* @param string $code Project code
69+
* @param int $runId Test run ID
70+
* @return string|null Public report link or null on failure
71+
*/
72+
public function enablePublicReport(string $code, int $runId): ?string;
6473
}

src/Interfaces/LoggerInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ interface LoggerInterface
99
public function info(string $message): void;
1010
public function debug(string $message): void;
1111
public function error(string $message): void;
12+
public function warning(string $message): void;
1213
}

src/Loggers/Logger.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class Logger implements LoggerInterface
1313
'INFO' => "\033[32m", // Green
1414
'DEBUG' => "\033[36m", // Blue
1515
'ERROR' => "\033[31m", // Red
16+
'WARNING' => "\033[33m", // Yellow
1617
'RESET' => "\033[0m", // Reset color
1718
];
1819
private bool $debug;
@@ -64,6 +65,10 @@ public function error(string $message): void
6465
$this->writeLog($message, 'ERROR');
6566
}
6667

68+
public function warning(string $message): void
69+
{
70+
$this->writeLog($message, 'WARNING');
71+
}
6772

6873
private function writeLog(string $message, string $level): void
6974
{

src/Models/Config/TestopsConfig.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class TestopsConfig
77
{
88
public ?string $project = null;
99
public bool $defect = false;
10+
public bool $showPublicReportLink = false;
1011
public ApiConfig $api;
1112
public RunConfig $run;
1213
public PlanConfig $plan;
@@ -52,4 +53,14 @@ public function setStatusFilter(array $statusFilter): void
5253
{
5354
$this->statusFilter = $statusFilter;
5455
}
56+
57+
public function isShowPublicReportLink(): bool
58+
{
59+
return $this->showPublicReportLink;
60+
}
61+
62+
public function setShowPublicReportLink(bool $showPublicReportLink): void
63+
{
64+
$this->showPublicReportLink = $showPublicReportLink;
65+
}
5566
}

src/Reporters/TestOpsReporter.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ public function completeRun(): void
5858
$this->state->completeRun(
5959
function () {
6060
$this->client->completeTestRun($this->config->testops->getProject(), $this->runId);
61+
62+
// Enable public report if configured
63+
if ($this->config->testops->isShowPublicReportLink()) {
64+
$this->enablePublicReportForRun();
65+
}
6166
}
6267
);
6368
}
@@ -300,4 +305,23 @@ private function updateExternalIssue(int $runId): void
300305
$this->logger->error('Failed to update external issue: ' . $e->getMessage());
301306
}
302307
}
308+
309+
/**
310+
* Enable public report for the current test run
311+
*/
312+
private function enablePublicReportForRun(): void
313+
{
314+
try {
315+
$publicUrl = $this->client->enablePublicReport(
316+
$this->config->testops->getProject(),
317+
$this->runId
318+
);
319+
320+
// Logger already prints the link inside the client method
321+
// No need to print again here
322+
} catch (Exception $e) {
323+
// Log warning through the centralized logger
324+
$this->logger->warning('Failed to enable public report: ' . $e->getMessage());
325+
}
326+
}
303327
}

0 commit comments

Comments
 (0)