Skip to content

Commit 42faa84

Browse files
committed
Add embedding test
1 parent d3c9f79 commit 42faa84

File tree

5 files changed

+125
-0
lines changed

5 files changed

+125
-0
lines changed
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright 2025 EPAM Systems
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.epam.reportportal.karate.logging;
18+
19+
import com.epam.reportportal.karate.utils.TestUtils;
20+
import com.epam.reportportal.listeners.LogLevel;
21+
import com.epam.reportportal.service.ReportPortal;
22+
import com.epam.reportportal.service.ReportPortalClient;
23+
import com.epam.reportportal.util.test.CommonUtils;
24+
import com.epam.ta.reportportal.ws.model.log.SaveLogRQ;
25+
import com.intuit.karate.Results;
26+
import okhttp3.MultipartBody;
27+
import org.apache.commons.lang3.tuple.Pair;
28+
import org.junit.jupiter.api.BeforeEach;
29+
import org.junit.jupiter.params.ParameterizedTest;
30+
import org.junit.jupiter.params.provider.ValueSource;
31+
import org.mockito.ArgumentCaptor;
32+
33+
import java.util.List;
34+
import java.util.stream.Collectors;
35+
import java.util.stream.Stream;
36+
37+
import static com.epam.reportportal.karate.utils.TestUtils.*;
38+
import static org.hamcrest.MatcherAssert.assertThat;
39+
import static org.hamcrest.Matchers.*;
40+
import static org.mockito.Mockito.*;
41+
42+
public class EmbedLoggingTest {
43+
private static final String TEST_FEATURE = "classpath:feature/embed.feature";
44+
private final String launchUuid = CommonUtils.namedId("launch_");
45+
private final String featureId = CommonUtils.namedId("feature_");
46+
private final String scenarioId = CommonUtils.namedId("scenario_");
47+
private final List<String> stepIds = Stream.generate(() -> CommonUtils.namedId("step_")).limit(2).collect(Collectors.toList());
48+
49+
private final ReportPortalClient client = mock(ReportPortalClient.class);
50+
private final ReportPortal rp = ReportPortal.create(client, standardParameters(), testExecutor());
51+
52+
@BeforeEach
53+
public void setupMock() {
54+
mockLaunch(client, launchUuid, featureId, scenarioId, stepIds);
55+
mockBatchLogging(client);
56+
}
57+
58+
@ParameterizedTest
59+
@ValueSource(booleans = { true, false })
60+
@SuppressWarnings({ "unchecked", "rawtypes" })
61+
public void test_embed_image_attachment(boolean report) {
62+
Results results;
63+
if (report) {
64+
results = TestUtils.runAsReport(rp, TEST_FEATURE);
65+
} else {
66+
results = TestUtils.runAsHook(rp, TEST_FEATURE);
67+
}
68+
assertThat(results.getFailCount(), equalTo(0));
69+
70+
ArgumentCaptor<List> logCaptor = ArgumentCaptor.forClass(List.class);
71+
verify(client).log(logCaptor.capture());
72+
73+
List<SaveLogRQ> logs = logCaptor.getAllValues()
74+
.stream()
75+
.flatMap(rq -> extractJsonParts((List<MultipartBody.Part>) rq).stream())
76+
.collect(Collectors.toList());
77+
assertThat(logs, hasSize(2));
78+
79+
List<SaveLogRQ> attachmentLogs = logs.stream()
80+
.filter(log -> log.getFile() != null)
81+
.filter(log -> log.getMessage() != null && log.getMessage().startsWith("Attachment: "))
82+
.collect(Collectors.toList());
83+
84+
assertThat("Should have one attachment log message", attachmentLogs, hasSize(1));
85+
86+
// Verify the attachment log properties
87+
SaveLogRQ attachmentLog = attachmentLogs.get(0);
88+
assertThat("Attachment log should have INFO level", attachmentLog.getLevel(), equalTo(LogLevel.INFO.name()));
89+
assertThat("Attachment log should have item UUID", attachmentLog.getItemUuid(), notNullValue());
90+
assertThat("Attachment log should have log time", attachmentLog.getLogTime(), notNullValue());
91+
assertThat("Attachment message should contain image/png", attachmentLog.getMessage(), equalTo("Attachment: image/png"));
92+
93+
List<Pair<String, byte[]>> attachments = logCaptor.getAllValues()
94+
.stream()
95+
.flatMap(rq -> extractBinaryParts((List<MultipartBody.Part>) rq).stream())
96+
.collect(Collectors.toList());
97+
assertThat(attachments, hasSize(1));
98+
assertThat(attachments.get(0).getKey(), equalTo("image/png"));
99+
assertThat(attachments.get(0).getValue().length, greaterThan(0));
100+
}
101+
}
102+

src/test/java/com/epam/reportportal/karate/utils/TestUtils.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import io.reactivex.Maybe;
3636
import jakarta.annotation.Nonnull;
3737
import jakarta.annotation.Nullable;
38+
import okhttp3.MediaType;
3839
import okhttp3.MultipartBody;
3940
import okio.Buffer;
4041
import org.apache.commons.lang3.tuple.Pair;
@@ -232,4 +233,21 @@ public static List<SaveLogRQ> extractJsonParts(List<MultipartBody.Part> parts) {
232233
.flatMap(Collection::stream)
233234
.collect(Collectors.toList());
234235
}
236+
237+
public static List<Pair<String, byte[]>> extractBinaryParts(List<MultipartBody.Part> parts) {
238+
return parts.stream()
239+
.filter(p -> ofNullable(p.headers()).map(headers -> headers.get("Content-Disposition"))
240+
.map(h -> h.contains(Constants.LOG_REQUEST_BINARY_PART))
241+
.orElse(false))
242+
.map(MultipartBody.Part::body)
243+
.map(b -> {
244+
Buffer buf = new Buffer();
245+
try {
246+
b.writeTo(buf);
247+
} catch (IOException ignore) {
248+
}
249+
return Pair.of(ofNullable(b.contentType()).map(MediaType::toString).orElse(null), buf.readByteArray());
250+
})
251+
.collect(Collectors.toList());
252+
}
235253
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Feature: Demonstrate image attachment
2+
3+
Scenario: I attach image to report
4+
When def bytes = karate.read('classpath:pug/lucky.png')
5+
Then karate.embed(bytes, 'image/png')

src/test/resources/pug/lucky.png

2.22 MB
Loading

src/test/resources/pug/unlucky.png

2.15 MB
Loading

0 commit comments

Comments
 (0)