diff --git a/README.md b/README.md
index 40696ce0..3c0955fd 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,16 @@
# Allure notifications
**Allure notifications** - это библиотека, позволяющая выполнять автоматическое оповещение о результатах прохождения автотестов, которое направляется в нужный вам мессенджер (Telegram, Slack, Skype, Email, Mattermost).
+| Telegram | Slack |
+:-------------------------:|:-------------------------:
+ | 
+| **Mattermost** | **Email** |
+ | 
+| **RocketChat** |
+ |
+| **Skype** | **Icq** |
+| Done | Wat? lol |
+
Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
## Содержание
@@ -11,6 +21,22 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
+ [для запуска из Jenkins](#Jenkins)
+ [Особенности заполнения файла config.json в зависимости от выбранного мессенджера](#config)
+
How to:
+
+- [x] [Telegram config](https://github.com/qa-guru/allure-notifications/wiki/Telegram-configuration)
+- [x] [Slack config](https://github.com/qa-guru/allure-notifications/wiki/Slack-configuration)
+- [x] [Email config](https://github.com/qa-guru/allure-notifications/wiki/Email-configuration)
+- [x] [Skype config](https://github.com/qa-guru/allure-notifications/wiki/Skype-configuration)
+- [x] [Mattermost config](https://github.com/qa-guru/allure-notifications/wiki/Mattermost-configuration)
+- [x] [Rocket config]
+
+
+CommandLine options
+All keys should be used with `-D`:
+
+| key | description |
+|:---:| :---------: |
+| configFile | Path to JSON-config file |
@@ -92,6 +118,12 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
"token": "",
"chat": ""
},
+ "rocket" : {
+ "url": "",
+ "auth_token": "",
+ "user_id": "",
+ "channel": ""
+ },
"skype": {
"appId": "",
"appSecret": "",
@@ -109,6 +141,12 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
"from": "",
"recipient": ""
},
+ "testOps": {
+ "url": "",
+ "auth_token": "",
+ "xsrf_token": "",
+ "project_id": ""
+ },
"proxy": {
"host": "",
"port": 0,
@@ -117,6 +155,11 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
}
}
```
+You only need:
+ - to fill needed options in `base` block (please, be careful, `language` field is required!);
+ - to configure desired destinations for notifications (`telegram`, `slack`, `mattermost`, `skype`, `mail`), keep in mind it's possible to set multiple destinations at once, if no destination is set, then no notification will be sent and no error will occur;
+ - to specify optional proxy configuration in `proxy` block.
+ - if you need Allure TestOps integration, you must fill field `enableTestOpsIntegration` in `base` block and fill `testOps` block
Блок `proxy` используется если нужно указать дополнительную конфигурацию proxy.
diff --git a/build.gradle b/build.gradle
index 37093d74..bb265a70 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,6 +27,8 @@ dependencies {
implementation('com.jayway.jsonpath:json-path:2.7.0')
implementation('commons-io:commons-io:2.11.0')
implementation('org.apache.commons:commons-lang3:3.12.0')
+ implementation('io.rest-assured:rest-assured:4.4.0')
+ implementation('org.jboss.resteasy:resteasy-jackson2-provider:3.0.6.Final')
testImplementation('org.junit.jupiter:junit-jupiter:5.9.0')
testImplementation('org.springframework:spring-test:5.3.22') {
diff --git a/readme_images/allure_testops_en.png b/readme_images/allure_testops_en.png
new file mode 100644
index 00000000..ab3538fc
Binary files /dev/null and b/readme_images/allure_testops_en.png differ
diff --git a/src/main/java/guru/qa/allure/notifications/Application.java b/src/main/java/guru/qa/allure/notifications/Application.java
index c8093cbe..24d024e9 100644
--- a/src/main/java/guru/qa/allure/notifications/Application.java
+++ b/src/main/java/guru/qa/allure/notifications/Application.java
@@ -3,7 +3,6 @@
import guru.qa.allure.notifications.clients.Notification;
import guru.qa.allure.notifications.config.ApplicationConfig;
import guru.qa.allure.notifications.config.Config;
-import guru.qa.allure.notifications.exceptions.MessagingException;
import guru.qa.allure.notifications.util.LogInterceptor;
import guru.qa.allure.notifications.util.ProxyManager;
import kong.unirest.Unirest;
diff --git a/src/main/java/guru/qa/allure/notifications/chart/Chart.java b/src/main/java/guru/qa/allure/notifications/chart/Chart.java
index 7e213e0a..42e2916d 100644
--- a/src/main/java/guru/qa/allure/notifications/chart/Chart.java
+++ b/src/main/java/guru/qa/allure/notifications/chart/Chart.java
@@ -1,5 +1,6 @@
package guru.qa.allure.notifications.chart;
+import guru.qa.allure.notifications.config.testops.TestOps;
import guru.qa.allure.notifications.exceptions.MessageBuildException;
import lombok.extern.slf4j.Slf4j;
import org.knowm.xchart.BitmapEncoder;
@@ -9,6 +10,7 @@
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import java.io.File;
@@ -19,6 +21,9 @@
public class Chart {
public static byte[] createChart(Base base) throws MessageBuildException {
+ return createChart(base, null);
+ }
+ public static byte[] createChart(Base base, TestOps testOps) throws MessageBuildException {
log.info("Creating chart...");
PieChart chart = ChartBuilder.createBaseChart(base);
log.info("Adding legend to chart...");
@@ -26,7 +31,13 @@ public static byte[] createChart(Base base) throws MessageBuildException {
log.info("Adding view to chart...");
ChartView.addViewTo(chart);
log.info("Adding series to chart...");
- List colors = new ChartSeries(base).addSeriesTo(chart);
+ List colors;
+ if (base.getEnableTestOpsIntegration()) {
+ colors = new ChartSeries(base, testOps).addSeriesTo(chart);
+ }
+ else {
+ colors = new ChartSeries(base).addSeriesTo(chart);
+ }
log.info("Adding colors to series...");
chart.getStyler().setSeriesColors(colors.toArray(new Color[0]));
BufferedImage chartImage = BitmapEncoder.getBufferedImage(chart);
diff --git a/src/main/java/guru/qa/allure/notifications/chart/ChartSeries.java b/src/main/java/guru/qa/allure/notifications/chart/ChartSeries.java
index a07afb06..61e5dcbd 100644
--- a/src/main/java/guru/qa/allure/notifications/chart/ChartSeries.java
+++ b/src/main/java/guru/qa/allure/notifications/chart/ChartSeries.java
@@ -1,28 +1,47 @@
package guru.qa.allure.notifications.chart;
import guru.qa.allure.notifications.config.base.Base;
+import guru.qa.allure.notifications.config.testops.TestOps;
import guru.qa.allure.notifications.mapper.LegendMapper;
import guru.qa.allure.notifications.mapper.SummaryMapper;
import guru.qa.allure.notifications.model.legend.Legend;
import guru.qa.allure.notifications.model.summary.Summary;
+import guru.qa.allure.notifications.util.TestOpsClient;
import org.knowm.xchart.PieChart;
import java.awt.*;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
public class ChartSeries {
private final LegendMapper legendMapper;
private final SummaryMapper summaryMapper;
+ private final TestOps testOps;
public ChartSeries(Base base) {
this.legendMapper = new LegendMapper(base);
this.summaryMapper = new SummaryMapper(base);
+ testOps = null;
+ }
+
+ public ChartSeries(Base base, TestOps testOps) {
+ this.legendMapper = new LegendMapper(base);
+ this.summaryMapper = new SummaryMapper(base);
+ this.testOps = testOps;
}
public List addSeriesTo(PieChart chart) {
List colors = new ArrayList<>();
- final Summary summary = summaryMapper.map();
+ Summary summary;
+ if (testOps != null) {
+ TestOpsClient testOpsClient = new TestOpsClient(testOps);
+ HashMap statistics = testOpsClient.getLaunchStatistic();
+ summary = Summary.getInstance(statistics);
+ }
+ else {
+ summary = summaryMapper.map();
+ }
final Legend legend = legendMapper.map();
addSeries(chart, colors, summary.getStatistic().getPassed(), legend.getPassed(), new Color(148, 202, 102));
diff --git a/src/main/java/guru/qa/allure/notifications/clients/ClientFactory.java b/src/main/java/guru/qa/allure/notifications/clients/ClientFactory.java
index ef79da8e..31d6e6e0 100644
--- a/src/main/java/guru/qa/allure/notifications/clients/ClientFactory.java
+++ b/src/main/java/guru/qa/allure/notifications/clients/ClientFactory.java
@@ -5,6 +5,7 @@
import guru.qa.allure.notifications.clients.mail.Email;
import guru.qa.allure.notifications.clients.mattermost.MattermostClient;
+import guru.qa.allure.notifications.clients.rocket.RocketClient;
import guru.qa.allure.notifications.clients.skype.SkypeClient;
import guru.qa.allure.notifications.clients.slack.SlackClient;
import guru.qa.allure.notifications.clients.telegram.TelegramClient;
@@ -15,6 +16,9 @@ public class ClientFactory {
public static List from(Config config) {
MessageData messageData = new MessageData(config.getBase());
+ if (config.getTestops() != null) {
+ messageData = new MessageData(config.getBase(), config.getTestops());
+ }
List notifiers = new ArrayList<>();
if (config.getTelegram() != null) {
@@ -32,6 +36,9 @@ public static List from(Config config) {
if (config.getSkype() != null) {
notifiers.add(new SkypeClient(messageData, config.getSkype()));
}
+ if (config.getRocket() != null) {
+ notifiers.add(new RocketClient(messageData, config.getRocket()));
+ }
return notifiers;
}
}
diff --git a/src/main/java/guru/qa/allure/notifications/clients/Notification.java b/src/main/java/guru/qa/allure/notifications/clients/Notification.java
index 41e51c98..1511e5f4 100644
--- a/src/main/java/guru/qa/allure/notifications/clients/Notification.java
+++ b/src/main/java/guru/qa/allure/notifications/clients/Notification.java
@@ -1,5 +1,6 @@
package guru.qa.allure.notifications.clients;
+import com.sun.mail.iap.ByteArray;
import guru.qa.allure.notifications.chart.Chart;
import java.util.List;
@@ -19,7 +20,13 @@ public static boolean send(Config config) {
try {
log.info("Sending message...");
if (config.getBase().getEnableChart()) {
- byte[] chartImage = Chart.createChart(config.getBase());
+ byte[] chartImage = null;
+ if (config.getTestops() != null) {
+ chartImage = Chart.createChart(config.getBase(), config.getTestops());
+ }
+ else {
+ chartImage = Chart.createChart(config.getBase());
+ }
notifier.sendPhoto(chartImage);
}
else {
diff --git a/src/main/java/guru/qa/allure/notifications/clients/rocket/RocketClient.java b/src/main/java/guru/qa/allure/notifications/clients/rocket/RocketClient.java
new file mode 100644
index 00000000..5458c1db
--- /dev/null
+++ b/src/main/java/guru/qa/allure/notifications/clients/rocket/RocketClient.java
@@ -0,0 +1,50 @@
+package guru.qa.allure.notifications.clients.rocket;
+
+import guru.qa.allure.notifications.clients.Notifier;
+import guru.qa.allure.notifications.config.rocket.Rocket;
+import guru.qa.allure.notifications.exceptions.MessagingException;
+import guru.qa.allure.notifications.json.JSON;
+import guru.qa.allure.notifications.template.MarkdownTemplate;
+import guru.qa.allure.notifications.template.RocketTemplate;
+import guru.qa.allure.notifications.template.data.MessageData;
+import kong.unirest.ContentType;
+import kong.unirest.Unirest;
+
+import java.io.ByteArrayInputStream;
+public class RocketClient implements Notifier {
+ private final JSON json = new JSON();
+ private final Rocket rocket;
+ private final RocketTemplate template;
+
+ public RocketClient(MessageData messageData, Rocket rocket) {
+ this.rocket = rocket;
+ this.template = new RocketTemplate(messageData);
+ }
+
+ @Override
+ public void sendText() throws MessagingException {
+ String body = String.format("{\"channel\": \"%s\", \"text\": \"%s\" }",
+ rocket.getChannel(), template.create().replace("\r\n", "\\\n"));
+ String url = String.format("%s/api/v1/chat.postMessage", rocket.getUrl());
+ Unirest.post(url)
+ .header("X-Auth-Token", rocket.getToken())
+ .header("X-User-Id", rocket.getUserId())
+ .header("Content-Type", "application/json")
+ .body(json.prettyPrint(body))
+ .asString()
+ .getBody();
+ }
+
+ @Override
+ public void sendPhoto(byte[] chartImage) throws MessagingException {
+ sendText();
+ String url = String.format("%s/api/v1/rooms.upload/%s", rocket.getUrl(), rocket.getChannel());
+
+ Unirest.post(url)
+ .header("X-Auth-Token", rocket.getToken())
+ .header("X-User-Id", rocket.getUserId())
+ .field("file", new ByteArrayInputStream(chartImage), ContentType.IMAGE_PNG, "chart.png")
+ .asString()
+ .getBody();
+ }
+}
diff --git a/src/main/java/guru/qa/allure/notifications/config/Config.java b/src/main/java/guru/qa/allure/notifications/config/Config.java
index 2116e8bd..e00b1da7 100644
--- a/src/main/java/guru/qa/allure/notifications/config/Config.java
+++ b/src/main/java/guru/qa/allure/notifications/config/Config.java
@@ -5,9 +5,11 @@
import guru.qa.allure.notifications.config.mail.Mail;
import guru.qa.allure.notifications.config.mattermost.Mattermost;
import guru.qa.allure.notifications.config.proxy.Proxy;
+import guru.qa.allure.notifications.config.rocket.Rocket;
import guru.qa.allure.notifications.config.skype.Skype;
import guru.qa.allure.notifications.config.slack.Slack;
import guru.qa.allure.notifications.config.telegram.Telegram;
+import guru.qa.allure.notifications.config.testops.TestOps;
import lombok.Data;
/**
@@ -29,6 +31,10 @@ public class Config {
private Skype skype;
@SerializedName("mail")
private Mail mail;
+ @SerializedName("rocket")
+ private Rocket rocket;
+ @SerializedName("testOps")
+ private TestOps testops;
@SerializedName("proxy")
private Proxy proxy;
}
diff --git a/src/main/java/guru/qa/allure/notifications/config/base/Base.java b/src/main/java/guru/qa/allure/notifications/config/base/Base.java
index a6ee2ca9..e6de33da 100644
--- a/src/main/java/guru/qa/allure/notifications/config/base/Base.java
+++ b/src/main/java/guru/qa/allure/notifications/config/base/Base.java
@@ -27,4 +27,6 @@ public class Base {
private String allureFolder;
@SerializedName("enableChart")
private Boolean enableChart;
+ @SerializedName("enableTestOpsIntegration")
+ private Boolean enableTestOpsIntegration;
}
diff --git a/src/main/java/guru/qa/allure/notifications/config/rocket/Rocket.java b/src/main/java/guru/qa/allure/notifications/config/rocket/Rocket.java
new file mode 100644
index 00000000..77f9cbc0
--- /dev/null
+++ b/src/main/java/guru/qa/allure/notifications/config/rocket/Rocket.java
@@ -0,0 +1,22 @@
+package guru.qa.allure.notifications.config.rocket;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author GerasimchukDV
+ * @since 4.2.2
+ * Model class representing Rocket client settings.
+ */
+@Data
+public class Rocket {
+ @SerializedName("url")
+ private String url;
+ @SerializedName("auth_token")
+ private String token;
+
+ @SerializedName("user_id")
+ private String userId;
+ @SerializedName("channel")
+ private String channel;
+}
diff --git a/src/main/java/guru/qa/allure/notifications/config/testops/TestOps.java b/src/main/java/guru/qa/allure/notifications/config/testops/TestOps.java
new file mode 100644
index 00000000..f9b1b0c9
--- /dev/null
+++ b/src/main/java/guru/qa/allure/notifications/config/testops/TestOps.java
@@ -0,0 +1,23 @@
+package guru.qa.allure.notifications.config.testops;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+
+/**
+ * @author GerasimchukDV
+ * @since 4.2.2
+ * Model class representing Allure TestOps client settings.
+ */
+
+@Data
+public class TestOps {
+ @SerializedName("url")
+ private String url;
+ @SerializedName("auth_token")
+ private String auth_token;
+
+ @SerializedName("xsrf_token")
+ private String xsrf_token;
+ @SerializedName("project_id")
+ private String projectId;
+}
diff --git a/src/main/java/guru/qa/allure/notifications/json/JSON.java b/src/main/java/guru/qa/allure/notifications/json/JSON.java
index 2b404f3e..60a38c85 100644
--- a/src/main/java/guru/qa/allure/notifications/json/JSON.java
+++ b/src/main/java/guru/qa/allure/notifications/json/JSON.java
@@ -3,11 +3,14 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.stream.JsonReader;
import guru.qa.allure.notifications.exceptions.ConfigNotFoundException;
import lombok.extern.slf4j.Slf4j;
import java.io.FileNotFoundException;
import java.io.FileReader;
+import java.io.StringReader;
/**
* @author kadehar
@@ -28,6 +31,15 @@ public T parse(String file, Class clazz) {
}
public String prettyPrint(String json) {
- return GSON.toJson(JsonParser.parseString(json));
+ String result = "";
+ try {
+ result = GSON.toJson(JsonParser.parseString(json));
+ }
+ catch (JsonSyntaxException e) {
+ JsonReader reader = new JsonReader(new StringReader(json));
+ reader.setLenient(true);
+ result = GSON.toJson(JsonParser.parseReader(reader));
+ }
+ return result;
}
}
diff --git a/src/main/java/guru/qa/allure/notifications/model/summary/Statistic.java b/src/main/java/guru/qa/allure/notifications/model/summary/Statistic.java
index 03731d00..39b1f3e9 100644
--- a/src/main/java/guru/qa/allure/notifications/model/summary/Statistic.java
+++ b/src/main/java/guru/qa/allure/notifications/model/summary/Statistic.java
@@ -1,14 +1,19 @@
package guru.qa.allure.notifications.model.summary;
import com.google.gson.annotations.SerializedName;
-import lombok.Getter;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
/**
* @author kadehar
* @since 1.0
* Model class, representing test statistic from Allure Report.
*/
-@Getter
+@Data
+@NoArgsConstructor(access = AccessLevel.PUBLIC)
+@AllArgsConstructor(access = AccessLevel.PUBLIC)
public class Statistic {
@SerializedName("passed")
private Integer passed;
diff --git a/src/main/java/guru/qa/allure/notifications/model/summary/Summary.java b/src/main/java/guru/qa/allure/notifications/model/summary/Summary.java
index 08dcb960..4ac8721c 100644
--- a/src/main/java/guru/qa/allure/notifications/model/summary/Summary.java
+++ b/src/main/java/guru/qa/allure/notifications/model/summary/Summary.java
@@ -1,17 +1,32 @@
package guru.qa.allure.notifications.model.summary;
import com.google.gson.annotations.SerializedName;
-import lombok.Getter;
+import lombok.Data;
+
+import java.util.HashMap;
/**
* @author kadehar
* @since 1.0
* Model class, representing test summary from Allure Report.
*/
-@Getter
+@Data
public class Summary {
@SerializedName("statistic")
private Statistic statistic;
@SerializedName("time")
private Time time;
+
+ public static Summary getInstance(HashMap statistic) {
+ Summary summary = new Summary();
+ Statistic stat = new Statistic();
+ stat.setTotal(statistic.get("total"));
+ stat.setFailed(statistic.get("failed"));
+ stat.setBroken(statistic.get("broken"));
+ stat.setPassed(statistic.get("passed"));
+ stat.setSkipped(statistic.get("skipped"));
+ stat.setUnknown(statistic.containsKey("unknown")?statistic.get("unknown"):0);
+ summary.setStatistic(stat);
+ return summary;
+ }
}
diff --git a/src/main/java/guru/qa/allure/notifications/model/summary/Time.java b/src/main/java/guru/qa/allure/notifications/model/summary/Time.java
index c0960b3b..4bc702b3 100644
--- a/src/main/java/guru/qa/allure/notifications/model/summary/Time.java
+++ b/src/main/java/guru/qa/allure/notifications/model/summary/Time.java
@@ -1,14 +1,14 @@
package guru.qa.allure.notifications.model.summary;
import com.google.gson.annotations.SerializedName;
-import lombok.Getter;
+import lombok.Data;
/**
* @author kadehar
* @since 1.0
* Model class, representing test duration from Allure Report.
*/
-@Getter
+@Data
public class Time {
@SerializedName("duration")
private Long duration;
diff --git a/src/main/java/guru/qa/allure/notifications/template/RocketTemplate.java b/src/main/java/guru/qa/allure/notifications/template/RocketTemplate.java
new file mode 100644
index 00000000..6cb9963e
--- /dev/null
+++ b/src/main/java/guru/qa/allure/notifications/template/RocketTemplate.java
@@ -0,0 +1,21 @@
+package guru.qa.allure.notifications.template;
+
+import guru.qa.allure.notifications.exceptions.MessageBuildException;
+import guru.qa.allure.notifications.template.data.MessageData;
+
+/**
+ * @author GerasimchukDV
+ * @since 4.2.2
+ * Utility class for KaTeX template creation.
+ */
+public class RocketTemplate {
+ private final MessageData messageData;
+
+ public RocketTemplate(MessageData messageData) {
+ this.messageData = messageData;
+ }
+
+ public String create() throws MessageBuildException {
+ return new MessageTemplate(messageData).of("rocket.ftl");
+ }
+}
diff --git a/src/main/java/guru/qa/allure/notifications/template/data/BuildData.java b/src/main/java/guru/qa/allure/notifications/template/data/BuildData.java
index 253d9c06..45362118 100644
--- a/src/main/java/guru/qa/allure/notifications/template/data/BuildData.java
+++ b/src/main/java/guru/qa/allure/notifications/template/data/BuildData.java
@@ -1,7 +1,9 @@
package guru.qa.allure.notifications.template.data;
import guru.qa.allure.notifications.config.base.Base;
+import guru.qa.allure.notifications.config.testops.TestOps;
import guru.qa.allure.notifications.formatters.Formatters;
+import guru.qa.allure.notifications.util.TestOpsClient;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
@@ -14,11 +16,17 @@
*/
@Slf4j
public class BuildData implements TemplateData {
-
private final Base base;
+ private final TestOps testOps;
public BuildData(Base base) {
this.base = base;
+ this.testOps = null;
+ }
+
+ public BuildData(Base base, TestOps testOps) {
+ this.base = base;
+ this.testOps = testOps;
}
@Override
@@ -27,8 +35,16 @@ public Map map() {
Map info = new HashMap<>();
info.put("env", base.getEnvironment());
info.put("comm", base.getComment());
- info.put("reportLink",
- new Formatters().formatReportLink(base.getReportLink()));
+ if (base.getEnableTestOpsIntegration()) {
+ TestOpsClient testOpsClient = new TestOpsClient(testOps);
+ String launchId = testOpsClient.getLastLaunchId();
+ String testOpsLink = String.format("%s/launch/%s", testOps.getUrl(), launchId);
+ info.put("reportLink", testOpsLink);
+ }
+ else {
+ info.put("reportLink",
+ new Formatters().formatReportLink(base.getReportLink()));
+ }
log.info("Build data: {}", info);
return info;
}
diff --git a/src/main/java/guru/qa/allure/notifications/template/data/MessageData.java b/src/main/java/guru/qa/allure/notifications/template/data/MessageData.java
index 032772f0..c2db5938 100644
--- a/src/main/java/guru/qa/allure/notifications/template/data/MessageData.java
+++ b/src/main/java/guru/qa/allure/notifications/template/data/MessageData.java
@@ -4,6 +4,7 @@
import java.util.Map;
import guru.qa.allure.notifications.config.base.Base;
+import guru.qa.allure.notifications.config.testops.TestOps;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -28,6 +29,13 @@ public MessageData(Base base) {
this.phrasesData = new PhrasesData(base);
}
+ public MessageData(Base base, TestOps testOps) {
+ this.project = base.getProject();
+ this.buildData = new BuildData(base, testOps);
+ this.summaryData = new SummaryData(base, testOps);
+ this.phrasesData = new PhrasesData(base);
+ }
+
public Map getValues() {
if (data == null) {
this.data = new HashMap<>();
diff --git a/src/main/java/guru/qa/allure/notifications/template/data/SummaryData.java b/src/main/java/guru/qa/allure/notifications/template/data/SummaryData.java
index 97127c17..0d84fb48 100644
--- a/src/main/java/guru/qa/allure/notifications/template/data/SummaryData.java
+++ b/src/main/java/guru/qa/allure/notifications/template/data/SummaryData.java
@@ -1,10 +1,13 @@
package guru.qa.allure.notifications.template.data;
import guru.qa.allure.notifications.config.base.Base;
+import guru.qa.allure.notifications.config.testops.TestOps;
import guru.qa.allure.notifications.formatters.Formatters;
import guru.qa.allure.notifications.mapper.SummaryMapper;
+import guru.qa.allure.notifications.model.summary.Statistic;
import guru.qa.allure.notifications.model.summary.Summary;
import guru.qa.allure.notifications.util.Percentage;
+import guru.qa.allure.notifications.util.TestOpsClient;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
@@ -19,30 +22,47 @@
public class SummaryData implements TemplateData {
private final SummaryMapper summaryMapper;
+ private final TestOps testOps;
public SummaryData(Base base) {
this.summaryMapper = new SummaryMapper(base);
+ this.testOps = null;
+ }
+
+ public SummaryData(Base base, TestOps testOps) {
+ this.summaryMapper = new SummaryMapper(base);
+ this.testOps = testOps;
}
@Override
public Map map() {
log.info("Collecting summary data for template");
- Summary summary = summaryMapper.map();
+ Summary summary;
+ if (testOps != null) {
+ TestOpsClient testOpsClient = new TestOpsClient(testOps);
+ HashMap statistics = testOpsClient.getLaunchStatistic();
+ summary = Summary.getInstance(statistics);
+ }
+ else {
+ summary = summaryMapper.map();
+ }
Map info = new HashMap<>();
- info.put("time", new Formatters().formatTime(summary.getTime()
- .getDuration()));
+ if (testOps == null) {
+ info.put("time", new Formatters().formatTime(summary.getTime()
+ .getDuration()));
+ info.put("passedPercentage",
+ new Percentage().eval(summary.getStatistic().getPassed(),
+ summary.getStatistic().getTotal()));
+ info.put("failedPercentage",
+ new Percentage().eval(summary.getStatistic().getFailed(),
+ summary.getStatistic().getTotal()));
+ }
info.put("total", summary.getStatistic().getTotal());
info.put("passed", summary.getStatistic().getPassed());
info.put("failed", summary.getStatistic().getFailed());
info.put("broken", summary.getStatistic().getBroken());
info.put("unknown", summary.getStatistic().getUnknown());
info.put("skipped", summary.getStatistic().getSkipped());
- info.put("passedPercentage",
- new Percentage().eval(summary.getStatistic().getPassed(),
- summary.getStatistic().getTotal()));
- info.put("failedPercentage",
- new Percentage().eval(summary.getStatistic().getFailed(),
- summary.getStatistic().getTotal()));
log.info("Summary data: {}", info);
return info;
}
diff --git a/src/main/java/guru/qa/allure/notifications/util/TestOpsClient.java b/src/main/java/guru/qa/allure/notifications/util/TestOpsClient.java
new file mode 100644
index 00000000..28afa732
--- /dev/null
+++ b/src/main/java/guru/qa/allure/notifications/util/TestOpsClient.java
@@ -0,0 +1,61 @@
+package guru.qa.allure.notifications.util;
+
+import guru.qa.allure.notifications.config.testops.TestOps;
+import kong.unirest.Unirest;
+import kong.unirest.json.JSONArray;
+import kong.unirest.json.JSONObject;
+
+import java.util.HashMap;
+
+public class TestOpsClient {
+
+ public static TestOps testops;
+
+ public TestOpsClient(TestOps testOps) {
+ this.testops = testOps;
+ }
+
+ public static String getLastLaunchId() {
+ String url = String.format("%s/api/rs/launch?projectId=%s&page=0&size=10&sort=created_date,DESC",
+ testops.getUrl(),
+ testops.getProjectId());
+
+ String jsonString = Unirest.get(url)
+ .header("Authorization", testops.getAuth_token())
+ .header("XSRF-TOKEN", testops.getXsrf_token())
+ .header("accept", "*/*")
+ .asString()
+ .getBody();
+ JSONObject jsonObject = new JSONObject(jsonString);
+ JSONArray jsonArray = jsonObject.getJSONArray("content");
+ String launchId = jsonArray.getJSONObject(0).getString("id");
+ return launchId;
+ }
+
+ public static HashMap getLaunchStatistic() {
+ String launchId = getLastLaunchId();
+ return getLaunchStatistic(launchId);
+ }
+ public static HashMap getLaunchStatistic(String launchId) {
+ String url = String.format("%s/api/rs/launch/%s/statistic", testops.getUrl(), launchId);
+
+ String jsonString = Unirest.get(url)
+ .header("Authorization", testops.getAuth_token())
+ .header("XSRF-TOKEN", testops.getXsrf_token())
+ .header("accept", "*/*")
+ .asString()
+ .getBody();
+ JSONArray jsonArray = new JSONArray(jsonString);
+ HashMap statistics = new HashMap<>();
+ Integer total = 0;
+ for (int i = 0; i < jsonArray.length(); i++) {
+ JSONObject element = jsonArray.getJSONObject(i);
+ String status = element.getString("status");
+ Integer count = element.getInt("count");
+ statistics.put(status, count);
+ total = total + count;
+ }
+ statistics.put("total", total);
+ return statistics;
+ }
+}
diff --git a/src/main/resources/templates/rocket.ftl b/src/main/resources/templates/rocket.ftl
new file mode 100644
index 00000000..d1209581
--- /dev/null
+++ b/src/main/resources/templates/rocket.ftl
@@ -0,0 +1,12 @@
+<#compress>
+**${results}:**
+ **-${environment}:** ${env}
+ **-${comment}:** ${comm}
+ **-${totalScenarios}:** ${total}
+ <#if passed != 0 > **-${totalPassed}:** ${passed} #if>
+ <#if failed != 0 > **-${totalFailed}:** ${failed} #if>
+ <#if broken != 0 > **-${totalBroken}:** ${broken} #if>
+ <#if unknown != 0 > **-${totalUnknown}:** ${unknown} #if>
+ <#if skipped != 0 > **-${totalSkipped}:** ${skipped} #if>
+ <#if reportLink??>**${reportAvailableAtLink}:** ${reportLink}#if>
+#compress>
\ No newline at end of file