de.qytera.qtaf.testrail.event_subscriber.UploadTestsSubscriber Maven / Gradle / Ivy
// Generated by delombok at Tue Jun 25 12:09:13 UTC 2024
package de.qytera.qtaf.testrail.event_subscriber;
import de.qytera.qtaf.core.QtafFactory;
import de.qytera.qtaf.core.config.ConfigurationFactory;
import de.qytera.qtaf.core.config.entity.ConfigMap;
import de.qytera.qtaf.core.config.exception.MissingConfigurationValueException;
import de.qytera.qtaf.core.events.QtafEvents;
import de.qytera.qtaf.core.events.interfaces.IEventSubscriber;
import de.qytera.qtaf.core.log.model.collection.TestFeatureLogCollection;
import de.qytera.qtaf.core.log.model.collection.TestScenarioLogCollection;
import de.qytera.qtaf.core.log.model.collection.TestSuiteLogCollection;
import de.qytera.qtaf.core.log.model.message.LogMessage;
import de.qytera.qtaf.core.log.model.message.StepInformationLogMessage;
import de.qytera.qtaf.security.aes.AES;
import de.qytera.qtaf.testrail.annotations.TestRail;
import de.qytera.qtaf.testrail.config.TestRailConfigHelper;
import de.qytera.qtaf.testrail.entity.Attachment;
import de.qytera.qtaf.testrail.entity.Attachments;
import de.qytera.qtaf.testrail.utils.APIClient;
import de.qytera.qtaf.testrail.utils.TestRailManager;
import rx.Subscription;
import java.nio.file.Path;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
/**
* This subscriber binds to the test finished event and uploads the tests to the TestRail API.
*/
public class UploadTestsSubscriber implements IEventSubscriber {
/**
* QTAF Event Subscription.
*/
private Subscription testFinishedSubscription;
/**
* Configuration.
*/
private static final ConfigMap CONFIG = QtafFactory.getConfiguration();
/**
* testRail API client.
*/
private APIClient client = null;
@Override
public void initialize() {
if (this.testFinishedSubscription == null) {
this.testFinishedSubscription = QtafEvents.logsPersisted.subscribe(this::onFinishedTesting);
}
}
/**
* Set up the client for the TestRail API.
*
* @return the client
* @throws GeneralSecurityException if encrypted values cannot be decrypted
* @throws MissingConfigurationValueException if the configuration is invalid
*/
public APIClient setUpClient() throws GeneralSecurityException, MissingConfigurationValueException {
if (client == null) {
// Load values from configuration file
String url = CONFIG.getString(TestRailConfigHelper.TESTRAIL_URL);
String clientId = CONFIG.getString(TestRailConfigHelper.TESTRAIL_AUTHENTICATION_CLIENT_ID);
String clientSecret = CONFIG.getString(TestRailConfigHelper.TESTRAIL_AUTHENTICATION_CLIENT_SECRET);
String key = CONFIG.getString(TestRailConfigHelper.SECURITY_KEY);
client = new APIClient(url);
// Check if id and secret exist
if (clientId == null || clientId.isBlank()) {
throw new MissingConfigurationValueException(TestRailConfigHelper.TESTRAIL_AUTHENTICATION_CLIENT_ID, CONFIG);
}
if (clientSecret == null || clientSecret.isBlank()) {
throw new MissingConfigurationValueException(TestRailConfigHelper.TESTRAIL_AUTHENTICATION_CLIENT_SECRET, CONFIG);
}
if (key == null || key.isBlank()) {
// credentials are not encrypted
client.setUser(clientId);
client.setPassword(clientSecret);
} else {
// credentials are encrypted
client.setUser(AES.decrypt(clientId, key));
client.setPassword(AES.decrypt(clientSecret, key));
}
}
return client;
}
/**
* Event handler for finished testing event.
*
* @param testingContext Test context event payload
*/
public void onFinishedTesting(String testingContext) {
if (Boolean.FALSE.equals(CONFIG.getBoolean(TestRailConfigHelper.TESTRAIL_ENABLED))) {
return;
}
try {
client = setUpClient();
} catch (GeneralSecurityException | MissingConfigurationValueException exception) {
QtafFactory.getLogger().error("[QTAF Testrail Plugin] Failed to set up API client", exception);
return;
}
TestSuiteLogCollection logCollection = TestSuiteLogCollection.getInstance();
for (TestFeatureLogCollection testFeatureLogCollection : logCollection.getTestFeatureLogCollections()) {
testFeatureLogCollection.getScenarioLogCollection().forEach(this::handleScenario);
}
}
private void handleScenario(TestScenarioLogCollection scenarioLog) {
if (scenarioLog.getStatus() == null) {
return;
}
TestRail testRailIdAnnotation = scenarioLog.getAnnotation(TestRail.class);
if (testRailIdAnnotation != null) {
Arrays.stream(testRailIdAnnotation.caseId()).forEach(caseId -> {
try {
Attachments attachments = TestRailManager.getAttachmentsForTestCase(client, caseId);
if (attachments != null) {
for (Attachment attachment : attachments.getAttachments()) {
TestRailManager.deleteAttachmentForTestCase(client, attachment.getId());
}
}
} catch (Exception e) {
QtafFactory.getLogger().error("[QTAF TestRail Plugin] Failed to delete attachments of case %s".formatted(caseId));
QtafFactory.getLogger().error(e);
}
});
if (scenarioLog.getStatus().equals(TestScenarioLogCollection.Status.FAILURE)) {
handleScenarioFailure(scenarioLog, testRailIdAnnotation);
} else if (scenarioLog.getStatus().equals(TestScenarioLogCollection.Status.SUCCESS)) {
handleScenarioSuccess(testRailIdAnnotation);
}
}
}
/**
* Handle scenario success.
*
* @param testRailIdAnnotation testrail annotation of scenario
*/
public void handleScenarioSuccess(TestRail testRailIdAnnotation) {
Arrays.stream(testRailIdAnnotation.caseId()).forEach(caseId -> {
try {
TestRailManager.addResultForTestCase(client, caseId, getRunId(testRailIdAnnotation), 1, "");
QtafFactory.getLogger().info("Results are uploaded to testRail");
} catch (Exception e) {
QtafFactory.getLogger().error(e);
}
});
}
/**
* Handle scenario failure.
*
* @param scenarioLog step logs
* @param testRailIdAnnotation testrail annotation of scenario
*/
public void handleScenarioFailure(TestScenarioLogCollection scenarioLog, TestRail testRailIdAnnotation) {
String errorMessage = scenarioLog.getLogMessages(StepInformationLogMessage.class).stream().filter(d -> d.getStatus().equals(StepInformationLogMessage.Status.FAILED)).map(LogMessage::getMessage).findFirst().orElseThrow(() -> new IllegalStateException("expected at least one failed step"));
for (String caseId : testRailIdAnnotation.caseId()) {
try {
TestRailManager.addResultForTestCase(client, caseId, getRunId(testRailIdAnnotation), 5, "Failure found in: " + errorMessage);
TestRailManager.addAttachmentForTestCase(client, caseId, QtafFactory.getTestSuiteLogCollection().getLogDirectory() + "/Report.html");
Set attachmentPaths = new HashSet<>();
for (String screenshotPath : scenarioLog.getScreenshotPaths()) {
attachmentPaths.add(Path.of(screenshotPath).toAbsolutePath());
}
for (StepInformationLogMessage step : scenarioLog.getLogMessages(StepInformationLogMessage.class)) {
attachmentPaths.add(Path.of(step.getScreenshotBefore()).toAbsolutePath());
attachmentPaths.add(Path.of(step.getScreenshotAfter()).toAbsolutePath());
}
for (Path path : attachmentPaths) {
if (path.toFile().isFile()) {
TestRailManager.addAttachmentForTestCase(client, caseId, path.toString());
}
}
QtafFactory.getLogger().info("Results are uploaded to testRail");
} catch (Exception e) {
QtafFactory.getLogger().error(e);
}
}
}
/**
* Returns the runId. The runId set in the configuration file is preferred to the runId set in the annotation.
*
* @param testRailIdAnnotation the annotation Object
* @return the runId
*/
public String getRunId(TestRail testRailIdAnnotation) {
ConfigMap config = ConfigurationFactory.getInstance();
String runId;
if (null != config.getString("testrail.runId")) {
runId = config.getString("testrail.runId");
return runId;
}
if (null == testRailIdAnnotation) {
throw new NullPointerException("The passed testRailId annotation is null");
}
if (testRailIdAnnotation.runId().isEmpty()) {
throw new IllegalArgumentException("No runId could be assigned to the test case. " + "The runId must be set either via the configuration file (testrail.runId) " + "or via the corresponding annotation.(@TestRail)");
}
runId = testRailIdAnnotation.runId();
return runId;
}
@java.lang.SuppressWarnings("all")
@lombok.Generated
public UploadTestsSubscriber() {
}
/**
* QTAF Event Subscription.
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public Subscription getTestFinishedSubscription() {
return this.testFinishedSubscription;
}
/**
* testRail API client.
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public APIClient getClient() {
return this.client;
}
/**
* QTAF Event Subscription.
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public void setTestFinishedSubscription(final Subscription testFinishedSubscription) {
this.testFinishedSubscription = testFinishedSubscription;
}
/**
* testRail API client.
*/
@java.lang.SuppressWarnings("all")
@lombok.Generated
public void setClient(final APIClient client) {
this.client = client;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof UploadTestsSubscriber)) return false;
final UploadTestsSubscriber other = (UploadTestsSubscriber) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$testFinishedSubscription = this.getTestFinishedSubscription();
final java.lang.Object other$testFinishedSubscription = other.getTestFinishedSubscription();
if (this$testFinishedSubscription == null ? other$testFinishedSubscription != null : !this$testFinishedSubscription.equals(other$testFinishedSubscription)) return false;
final java.lang.Object this$client = this.getClient();
final java.lang.Object other$client = other.getClient();
if (this$client == null ? other$client != null : !this$client.equals(other$client)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@lombok.Generated
protected boolean canEqual(final java.lang.Object other) {
return other instanceof UploadTestsSubscriber;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $testFinishedSubscription = this.getTestFinishedSubscription();
result = result * PRIME + ($testFinishedSubscription == null ? 43 : $testFinishedSubscription.hashCode());
final java.lang.Object $client = this.getClient();
result = result * PRIME + ($client == null ? 43 : $client.hashCode());
return result;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@lombok.Generated
public java.lang.String toString() {
return "UploadTestsSubscriber(testFinishedSubscription=" + this.getTestFinishedSubscription() + ", client=" + this.getClient() + ")";
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy