Skip to content
Open
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
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# Allure notifications
**Allure notifications** - это библиотека, позволяющая выполнять автоматическое оповещение о результатах прохождения автотестов, которое направляется в нужный вам мессенджер (Telegram, Slack, Skype, Email, Mattermost).

| Telegram | Slack |
:-------------------------:|:-------------------------:
![shakal_screenshot](readme_images/telegram-en.png) | ![shakal_screenshot](readme_images/slack-en.png)
| **Mattermost** | **Email** |
![shakal_screenshot](readme_images/mattermost-ru.png) | ![shakal_screenshot](readme_images/email_en.png)
| **RocketChat** |
![shakal_screenshot](readme_images/allure_testops_en.png) |
| **Skype** | **Icq** |
| Done | Wat? lol |

Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳

## Содержание
Expand All @@ -11,6 +21,22 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
+ [для запуска из Jenkins](#Jenkins)
+ [Особенности заполнения файла config.json в зависимости от выбранного мессенджера](#config)

<h6>How to:</h6>

- [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]

Choose a reason for hiding this comment

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

broken link



<h6>CommandLine options</h6>
All keys should be used with `-D`: <br/>

| key | description |
|:---:| :---------: |
| configFile | Path to JSON-config file |

<a name="Принцип">

Expand Down Expand Up @@ -92,6 +118,12 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
"token": "",
"chat": ""
},
"rocket" : {
"url": "",
"auth_token": "",
"user_id": "",
"channel": ""
},
"skype": {
"appId": "",
"appSecret": "",
Expand All @@ -109,6 +141,12 @@ Languages: 🇬🇧 🇫🇷 🇷🇺 🇺🇦 🇧🇾 🇨🇳
"from": "",
"recipient": ""
},
"testOps": {
"url": "",
"auth_token": "",
"xsrf_token": "",
"project_id": ""
},
"proxy": {
"host": "",
"port": 0,
Expand All @@ -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;

Choose a reason for hiding this comment

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

add rocket

- 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.

<a name="Base">
Expand Down
2 changes: 2 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Comment on lines +30 to +31
Copy link
Collaborator

Choose a reason for hiding this comment

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

are these dependencies used somewhere?


testImplementation('org.junit.jupiter:junit-jupiter:5.9.0')
testImplementation('org.springframework:spring-test:5.3.22') {
Expand Down
Binary file added readme_images/allure_testops_en.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
13 changes: 12 additions & 1 deletion src/main/java/guru/qa/allure/notifications/chart/Chart.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -19,14 +21,23 @@
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 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

the thing here is generic Chart starts "knowing" about TestOps, which is not good if low coupling is followed

log.info("Creating chart...");
PieChart chart = ChartBuilder.createBaseChart(base);
log.info("Adding legend to chart...");
ChartLegend.addLegendTo(chart);
log.info("Adding view to chart...");
ChartView.addViewTo(chart);
log.info("Adding series to chart...");
List<Color> colors = new ChartSeries(base).addSeriesTo(chart);
List<Color> 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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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<Color> addSeriesTo(PieChart chart) {
List<Color> colors = new ArrayList<>();
final Summary summary = summaryMapper.map();
Summary summary;
if (testOps != null) {
TestOpsClient testOpsClient = new TestOpsClient(testOps);
HashMap<String, Integer> 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));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -15,6 +16,9 @@ public class ClientFactory {

public static List<Notifier> from(Config config) {
MessageData messageData = new MessageData(config.getBase());
if (config.getTestops() != null) {
messageData = new MessageData(config.getBase(), config.getTestops());
}

List<Notifier> notifiers = new ArrayList<>();
if (config.getTelegram() != null) {
Expand All @@ -32,6 +36,9 @@ public static List<Notifier> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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();
}
}
6 changes: 6 additions & 0 deletions src/main/java/guru/qa/allure/notifications/config/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,6 @@ public class Base {
private String allureFolder;
@SerializedName("enableChart")
private Boolean enableChart;
@SerializedName("enableTestOpsIntegration")
private Boolean enableTestOpsIntegration;
}
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -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;
}
14 changes: 13 additions & 1 deletion src/main/java/guru/qa/allure/notifications/json/JSON.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,6 +31,15 @@ public <T> T parse(String file, Class<T> 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);
Copy link
Collaborator

Choose a reason for hiding this comment

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

why is this tweak needed?

result = GSON.toJson(JsonParser.parseReader(reader));
}
return result;
}
}
Loading