diff --git a/README.md b/README.md
index e452787b..57d691bf 100644
--- a/README.md
+++ b/README.md
@@ -240,3 +240,19 @@ Usage example:
Awaitility.setDefaultConditionEvaluationListener(new AllureAwaitilityListener());
```
+## Java-diff-utils
+This library provides advanced data logging in allure when using `java-diff-utils`.
+For more usage example look into module `allure-java-diff-utils`
+
+```xml
+
+ io.qameta.allure
+ allure-java-diff-utils
+ $LATEST_VERSION
+
+```
+
+Usage example:
+```java
+new AllureDiff().diff("my first line\nmy second line", "my first line");
+```
\ No newline at end of file
diff --git a/allure-java-diff-utils/build.gradle.kts b/allure-java-diff-utils/build.gradle.kts
new file mode 100644
index 00000000..1453c66f
--- /dev/null
+++ b/allure-java-diff-utils/build.gradle.kts
@@ -0,0 +1,28 @@
+description = "Allure java-diff-utils integration"
+
+val javaDiffUtils = "4.15"
+
+dependencies {
+ api(project(":allure-attachments"))
+ implementation("io.github.java-diff-utils:java-diff-utils:$javaDiffUtils")
+ testImplementation("javax.annotation:javax.annotation-api")
+ testImplementation("org.assertj:assertj-core")
+ testImplementation("org.junit.jupiter:junit-jupiter-api")
+ testImplementation("org.junit.jupiter:junit-jupiter-params")
+ testImplementation("org.slf4j:slf4j-simple")
+ testImplementation(project(":allure-java-commons-test"))
+ testImplementation(project(":allure-junit-platform"))
+ testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
+}
+
+tasks.jar {
+ manifest {
+ attributes(mapOf(
+ "Automatic-Module-Name" to "io.qameta.allure.diff"
+ ))
+ }
+}
+
+tasks.test {
+ useJUnitPlatform()
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/examples/diff-two-jsons.html b/allure-java-diff-utils/examples/diff-two-jsons.html
new file mode 100644
index 00000000..5e75d80e
--- /dev/null
+++ b/allure-java-diff-utils/examples/diff-two-jsons.html
@@ -0,0 +1,262 @@
+
+
+
+ Diff
+
+
+
+
+
+
+
+
+
+
+
+
+
3
+
3
+
"name": "John Doe",
+
+
+
4
+
4
+
"email": "john.doe@example.com",
+
+
+
5
+
5
+
"isActive": true,
+
+
+
+
+
+
+
10
+
10
+
"address": {
+
+
+
11
+
-
+
"street": "123 Main St",
+
+
+
13
+
-
+
"zipcode": "10001"
+
+
+
-
+
11
+
"city": "New York",
+
+
+
+
-
+
12
+
"zipcode": "10001",
+
+
+
+
-
+
13
+
"additional": "test"
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/allure-java-diff-utils/examples/diff-two-lines.html b/allure-java-diff-utils/examples/diff-two-lines.html
new file mode 100644
index 00000000..cf8e8546
--- /dev/null
+++ b/allure-java-diff-utils/examples/diff-two-lines.html
@@ -0,0 +1,177 @@
+
+
+
+ Diff
+
+
+
+
+
+
+
+
+
+
+
1
+
1
+
my first line
+
+
+
2
+
-
+
my second line
+
+
+
+
+
\ No newline at end of file
diff --git a/allure-java-diff-utils/examples/diff-two-xmls.html b/allure-java-diff-utils/examples/diff-two-xmls.html
new file mode 100644
index 00000000..cc4ad413
--- /dev/null
+++ b/allure-java-diff-utils/examples/diff-two-xmls.html
@@ -0,0 +1,262 @@
+
+
+
+ Diff
+
+
+
+
+
+
+
+
+
+
+
1
+
1
+
<?xml version="1.0" encoding="UTF-8"?>
+
+
+
2
+
2
+
<user id="123">
+
+
+
3
+
3
+
<name>John Doe</name>
+
+
+
4
+
4
+
<email>john.doe@example.com</email>
+
+
+
5
+
5
+
<isActive>true</isActive>
+
+
+
+
7
+
7
+
<role>admin</role>
+
+
+
8
+
8
+
<role>user</role>
+
+
+
+
+
11
+
-
+
<street>123 Main St</street>
+
+
+
13
+
-
+
<zipcode>10001</zipcode>
+
+
+
-
+
11
+
<city>New York</city>
+
+
+
+
-
+
12
+
<zipcode>10001</zipcode>
+
+
+
+
-
+
13
+
<additional>test</additional>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/allure-java-diff-utils/readme.md b/allure-java-diff-utils/readme.md
new file mode 100644
index 00000000..1266ffdb
--- /dev/null
+++ b/allure-java-diff-utils/readme.md
@@ -0,0 +1,117 @@
+## Allure-java-diff-utils
+This library provides advanced data logging to allure when using [java-diff-utils](https://github.com/java-diff-utils/java-diff-utils)
+
+## Wiki
+https://java-diff-utils.github.io/java-diff-utils/
+
+## Usage
+Add dependency:
+```xml
+
+ io.qameta.allure
+ allure-java-diff-utils
+ LATEST
+ test
+
+```
+
+The library does not provide any ready-to-use assertions, but it does provide a method for generating an attachment
+to analyze the difference between left and right strings.
+```java
+ new AllureDiff().diff("my first line\nmy second line", "my first line");
+```
+
+Then an attachment will be generated in the Allure report to display the difference in the two lines.
+Attachment example [here](examples/diff-two-lines.html)
+
+# Examples
+The library reveals itself to the maximum when comparing large structured data, such as json, csv or xml.
+
+Json compare example:
+```java
+new AllureDiff().diff(
+ """
+ {
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "street": "123 Main St",
+ "city": "New York",
+ "zipcode": "10001"
+ }
+ }
+ """ ,
+ """
+ {
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "city": "New York",
+ "zipcode": "10001",
+ "additional": "test"
+ }
+ }
+ """
+);
+```
+Attachment example [here](examples/diff-two-jsons.html)
+
+Xml compare example:
+```java
+new AllureDiff().diff(
+ """
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ 123 Main St
+ New York
+ 10001
+
+
+ """,
+ """
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ New York
+ 10001
+ test
+
+
+ """
+);
+```
+Attachment example [here](examples/diff-two-xmls.html)
+
+## Assert
+The library does not provide any assertions, but it does provide a Patch object that contains a diff that is available to any assertions needed.
+```java
+ final Patch patch = new AllureDiff().diff("my first line\nmy second line", "my first line");
+ assertThat(patch.getDeltas()).isEmpty();
+```
diff --git a/allure-java-diff-utils/src/main/java/io/qameta/allure/diff/AllureDiff.java b/allure-java-diff-utils/src/main/java/io/qameta/allure/diff/AllureDiff.java
new file mode 100644
index 00000000..4f3d2ad0
--- /dev/null
+++ b/allure-java-diff-utils/src/main/java/io/qameta/allure/diff/AllureDiff.java
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2016-2024 Qameta Software Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.qameta.allure.diff;
+
+import com.github.difflib.DiffUtils;
+import com.github.difflib.patch.AbstractDelta;
+import com.github.difflib.patch.Patch;
+import io.qameta.allure.attachment.AttachmentData;
+import io.qameta.allure.attachment.AttachmentProcessor;
+import io.qameta.allure.attachment.DefaultAttachmentProcessor;
+import io.qameta.allure.attachment.FreemarkerAttachmentRenderer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Class for generating diffs between two strings and attaching them to Allure reports.
+ *
+ * Provides a visual comparison of differences between original and revised text content,
+ * highlighting additions, removals, and unchanged lines.
+ *
+ */
+public class AllureDiff {
+
+ private String diffTemplatePath = "diff-template.ftl";
+
+ /**
+ * Set allure template file path. Default is 'diff-template.ftl' in 'resources/tpl/diff-template.ftl'.
+ *
+ * @param diffTemplatePath what the path to ftl template
+ */
+ public void setDiffTemplatePath(final String diffTemplatePath) {
+ this.diffTemplatePath = diffTemplatePath;
+ }
+
+ /**
+ * Computes the differences between two strings and generates an Allure report attachment.
+ *
+ * @param original The original text content
+ * @param revised The revised text content
+ * @return Diff result containing both the patch and Allure attachment
+ * @throws IllegalArgumentException if there's an error processing the diff
+ */
+ public Patch diff(final String original, final String revised) {
+ final List originalLines = splitInputString(original);
+ final List revisedLines = splitInputString(revised);
+
+ final Patch patch = DiffUtils.diff(originalLines, revisedLines);
+ final List> deltas = patch.getDeltas();
+
+ final List diffLines = new ArrayList<>();
+ int origLine = 1;
+ int revLine = 1;
+ int deltaIndex = 0;
+
+ while (origLine <= originalLines.size() || revLine <= revisedLines.size()) {
+ final AbstractDelta currentDelta = deltaIndex < deltas.size() ? deltas.get(deltaIndex) : null;
+
+ if (currentDelta != null && isDeltaPosition(currentDelta, origLine, revLine)) {
+ // Process deleted lines
+ for (String line : currentDelta.getSource().getLines()) {
+ diffLines.add(new AllureDiffLine(line, AllureDiffType.REMOVED, origLine++, -1));
+ }
+ // Process inserted lines
+ for (String line : currentDelta.getTarget().getLines()) {
+ diffLines.add(new AllureDiffLine(line, AllureDiffType.ADDED, -1, revLine++));
+ }
+ origLine += currentDelta.getSource().size();
+ revLine += currentDelta.getTarget().size();
+ deltaIndex++;
+ } else {
+ processUnchangedOrDivergedLines(originalLines, revisedLines, diffLines, origLine, revLine);
+ origLine++;
+ revLine++;
+ }
+ }
+
+ final AttachmentProcessor processor = new DefaultAttachmentProcessor();
+ processor.addAttachment(new AllureDiffModel(diffLines), new FreemarkerAttachmentRenderer(diffTemplatePath));
+
+ return patch;
+ }
+
+ /**
+ * Split the input string to lines.
+ *
+ * @param input any String
+ * @return list of lines from input string
+ */
+ private static List splitInputString(final String input) {
+ return Arrays.asList((input == null ? "" : input).split("\\R"));
+ }
+
+ /**
+ * Checks if the current position matches the delta's expected position.
+ *
+ * @param delta The delta to check
+ * @param origLine Current original line number
+ * @param revLine Current revised line number
+ * @return true if the current position matches the delta's position
+ */
+ private static boolean isDeltaPosition(final AbstractDelta delta,
+ final int origLine,
+ final int revLine) {
+ return delta.getSource().getPosition() + 1 == origLine
+ && delta.getTarget().getPosition() + 1 == revLine;
+ }
+
+ /**
+ * Processes lines that are either unchanged or diverged (unexpected differences).
+ *
+ * @param originalLines Original text lines
+ * @param revisedLines Revised text lines
+ * @param diffLines List to accumulate diff lines
+ * @param origLine Current original line number
+ * @param revLine Current revised line number
+ */
+ private static void processUnchangedOrDivergedLines(final List originalLines,
+ final List revisedLines,
+ final List diffLines,
+ final int origLine,
+ final int revLine) {
+ final String orig = getLine(originalLines, origLine);
+ final String rev = getLine(revisedLines, revLine);
+ if (orig != null && orig.equals(rev)) {
+ diffLines.add(new AllureDiffLine(orig, AllureDiffType.UNCHANGED, origLine, revLine));
+ } else {
+ if (orig != null) {
+ diffLines.add(new AllureDiffLine(orig, AllureDiffType.REMOVED, origLine, -1));
+ }
+ if (rev != null) {
+ diffLines.add(new AllureDiffLine(rev, AllureDiffType.ADDED, -1, revLine));
+ }
+ }
+ }
+
+ /**
+ * Safely retrieves a line from the text content.
+ *
+ * @param lines List of text lines
+ * @param lineNumber 1-based line number to retrieve
+ * @return The line content or null if out of bounds
+ */
+ private static String getLine(final List lines, final int lineNumber) {
+ return lineNumber <= lines.size() ? lines.get(lineNumber - 1) : null;
+ }
+
+ /**
+ * Represents the type of difference for a line in the comparison.
+ */
+ public enum AllureDiffType {
+ /**
+ * Line was added in the revised text.
+ */
+ ADDED,
+ /**
+ * Line was removed from the original text.
+ */
+ REMOVED,
+ /**
+ * Line is unchanged between versions.
+ */
+ UNCHANGED
+ }
+
+ /**
+ * Represents a single line in the diff comparison.
+ */
+ public static class AllureDiffLine {
+ private final String text;
+ private final AllureDiff.AllureDiffType type;
+ private final int originalLine;
+ private final int revisedLine;
+
+ /**
+ * Represents a single line in the diff comparison.
+ *
+ * @param text The text content of the line
+ * @param type The type of difference (ADDED/REMOVED/UNCHANGED)
+ * @param originalLine Original line number (-1 if line was added)
+ * @param revisedLine Revised line number (-1 if line was removed)
+ */
+ public AllureDiffLine(final String text,
+ final AllureDiffType type,
+ final int originalLine,
+ final int revisedLine) {
+ this.text = text;
+ this.type = type;
+ this.originalLine = originalLine;
+ this.revisedLine = revisedLine;
+ }
+
+ /**
+ * Get the text content of the line. Using only in FTL.
+ *
+ * @return what actually String contains
+ */
+ public String text() {
+ return text;
+ }
+
+ /**
+ * Get the type of difference (ADDED/REMOVED/UNCHANGED). Using only in FTL.
+ *
+ * @return what diff type String contatins
+ */
+ public AllureDiffType type() {
+ return type;
+ }
+
+ /**
+ * Get original line number (-1 if line was added). Using only in FTL.
+ *
+ * @return what the original line number
+ */
+ public int originalLine() {
+ return originalLine;
+ }
+
+ /**
+ * Get revised line number (-1 if line was removed). Using only in FTL.
+ *
+ * @return what the revised line number
+ */
+ public int revisedLine() {
+ return revisedLine;
+ }
+ }
+
+ /**
+ * Data model for the Allure attachment containing diff results. Using only in FTL.
+ */
+ public static class AllureDiffModel implements AttachmentData {
+ private final List rows;
+
+ /**
+ * Default constructor for data model for the Allure attachment containing diff results.
+ *
+ * @param rows List of diff lines to display in the report
+ */
+ public AllureDiffModel(final List rows) {
+ this.rows = rows;
+ }
+
+ /**
+ * Getting all rows with inner data model of diff representation. Using only in FTL.
+ *
+ * @return List of AllureDiffLine.
+ */
+ public List rows() {
+ return rows;
+ }
+
+ /**
+ * Get attachment name.
+ *
+ * @return attachment name
+ */
+ @Override
+ public String getName() {
+ return "Diff";
+ }
+ }
+}
diff --git a/allure-java-diff-utils/src/main/resources/tpl/diff-template.ftl b/allure-java-diff-utils/src/main/resources/tpl/diff-template.ftl
new file mode 100644
index 00000000..8660be41
--- /dev/null
+++ b/allure-java-diff-utils/src/main/resources/tpl/diff-template.ftl
@@ -0,0 +1,188 @@
+<#ftl output_format="HTML">
+<#-- @ftlvariable name="data" type="io.qameta.allure.diff.AllureDiff.AllureDiffModel" -->
+
+
+
+ Diff
+
+
+
+
+
+
+<#assign hasChanges = false>
+<#list data.rows() as line>
+ <#if line.type().name() != "UNCHANGED">
+ <#assign hasChanges = true>
+ <#break>
+ #if>
+#list>
+
+<#if !hasChanges>
+
+#if>
+
+
+ <#list data.rows() as line>
+
+
<#if line.originalLine() != -1>${line.originalLine()}<#else>-#if>
+
<#if line.revisedLine() != -1>${line.revisedLine()}<#else>-#if>
+
${line.text()}
+
+ #list>
+
+
+<#noparse>
+
+#noparse>
+
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/java/io/qameta/allure/diff/AllureDiffTest.java b/allure-java-diff-utils/src/test/java/io/qameta/allure/diff/AllureDiffTest.java
new file mode 100644
index 00000000..c261e9f9
--- /dev/null
+++ b/allure-java-diff-utils/src/test/java/io/qameta/allure/diff/AllureDiffTest.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2016-2024 Qameta Software Inc
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.qameta.allure.diff;
+
+import io.qameta.allure.Allure;
+import io.qameta.allure.model.StepResult;
+import io.qameta.allure.model.TestResult;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.stream.Stream;
+
+import static io.qameta.allure.test.RunUtils.runWithinTestContext;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class AllureDiffTest {
+
+ public static Stream testData() {
+ return Stream.of(
+ Arguments.of(null, "example.json"),
+ Arguments.of("example.json", null),
+ Arguments.of("example.json", "example.json"),
+ Arguments.of("example.json", "example-with-additional-line.json"),
+ Arguments.of("example.json", "example-with-changed-one-line.json"),
+ Arguments.of("example.json", "example-with-one-deleted-and-one-added.json"),
+ Arguments.of("example.json", "example-without-street-line.json"),
+ Arguments.of("example.xml", "example.xml"),
+ Arguments.of("example.xml", "example-with-additional-line.xml"),
+ Arguments.of("example.xml", "example-with-changed-one-line.xml"),
+ Arguments.of("example.xml", "example-with-one-deleted-and-one-added.xml"),
+ Arguments.of("example.xml", "example-without-street-line.xml")
+ );
+ }
+
+ @DisplayName("Diff test between ")
+ @ParameterizedTest(name = "{0} and {1}")
+ @MethodSource("testData")
+ void diffTest(String original, String revised) {
+ final List testResult = runWithinTestContext(() -> Allure.step("Diff test", () -> {
+ try {
+ new AllureDiff().diff(read(original), read(revised));
+ } catch (IOException e) {
+ throw new RuntimeException("Test is broken, check test data", e);
+ }
+ })).getTestResults();
+
+ assertThat(testResult)
+ .describedAs("Result is exactly one TestResult")
+ .hasSize(1)
+ .flatExtracting(TestResult::getSteps)
+ .describedAs("TestResult contains exactly one StepResult")
+ .hasSize(1)
+ .flatExtracting(StepResult::getAttachments)
+ .describedAs("StepResult contains exactly one Attachment with diff")
+ .hasSize(1);
+ }
+
+ private String read(String fileName) throws IOException {
+ if (fileName == null) {
+ return null;
+ }
+ try (InputStream stream = getClass().getClassLoader().getResourceAsStream(fileName)) {
+ if (stream == null) throw new IOException("Resource not found: " + fileName);
+ return new String(stream.readAllBytes(), StandardCharsets.UTF_8);
+ }
+ }
+}
diff --git a/allure-java-diff-utils/src/test/resources/allure.properties b/allure-java-diff-utils/src/test/resources/allure.properties
new file mode 100644
index 00000000..9c0b0a2d
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/allure.properties
@@ -0,0 +1,2 @@
+allure.results.directory=build/allure-results
+allure.label.epic=#project.description#
diff --git a/allure-java-diff-utils/src/test/resources/example-with-additional-line.json b/allure-java-diff-utils/src/test/resources/example-with-additional-line.json
new file mode 100644
index 00000000..626e89e3
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-additional-line.json
@@ -0,0 +1,16 @@
+{
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "street": "123 Main St",
+ "city": "New York",
+ "zipcode": "10001",
+ "additional": "test"
+ }
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/resources/example-with-additional-line.xml b/allure-java-diff-utils/src/test/resources/example-with-additional-line.xml
new file mode 100644
index 00000000..bcb7fb52
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-additional-line.xml
@@ -0,0 +1,16 @@
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ 123 Main St
+ New York
+ 10001
+ test
+
+
diff --git a/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.json b/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.json
new file mode 100644
index 00000000..8941fb73
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.json
@@ -0,0 +1,15 @@
+{
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "street": "Main St",
+ "city": "New York",
+ "zipcode": "10001"
+ }
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.xml b/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.xml
new file mode 100644
index 00000000..22cecf3e
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-changed-one-line.xml
@@ -0,0 +1,15 @@
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ Main St
+ New York
+ 10001
+
+
diff --git a/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.json b/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.json
new file mode 100644
index 00000000..fee9abb8
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.json
@@ -0,0 +1,15 @@
+{
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "city": "New York",
+ "zipcode": "10001",
+ "additional": "test"
+ }
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.xml b/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.xml
new file mode 100644
index 00000000..81655845
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-with-one-deleted-and-one-added.xml
@@ -0,0 +1,15 @@
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ New York
+ 10001
+ test
+
+
diff --git a/allure-java-diff-utils/src/test/resources/example-without-street-line.json b/allure-java-diff-utils/src/test/resources/example-without-street-line.json
new file mode 100644
index 00000000..3e9d2dbf
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-without-street-line.json
@@ -0,0 +1,14 @@
+{
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "city": "New York",
+ "zipcode": "10001"
+ }
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/resources/example-without-street-line.xml b/allure-java-diff-utils/src/test/resources/example-without-street-line.xml
new file mode 100644
index 00000000..7b24053b
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example-without-street-line.xml
@@ -0,0 +1,14 @@
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ New York
+ 10001
+
+
diff --git a/allure-java-diff-utils/src/test/resources/example.json b/allure-java-diff-utils/src/test/resources/example.json
new file mode 100644
index 00000000..43182fa4
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example.json
@@ -0,0 +1,15 @@
+{
+ "id": 123,
+ "name": "John Doe",
+ "email": "john.doe@example.com",
+ "isActive": true,
+ "roles": [
+ "admin",
+ "user"
+ ],
+ "address": {
+ "street": "123 Main St",
+ "city": "New York",
+ "zipcode": "10001"
+ }
+}
\ No newline at end of file
diff --git a/allure-java-diff-utils/src/test/resources/example.xml b/allure-java-diff-utils/src/test/resources/example.xml
new file mode 100644
index 00000000..36b36e60
--- /dev/null
+++ b/allure-java-diff-utils/src/test/resources/example.xml
@@ -0,0 +1,15 @@
+
+
+ John Doe
+ john.doe@example.com
+ true
+
+ admin
+ user
+
+
+ 123 Main St
+ New York
+ 10001
+
+
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 9eead326..70a518c4 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -16,6 +16,7 @@ include("allure-httpclient")
include("allure-httpclient5")
include("allure-java-commons")
include("allure-java-commons-test")
+include("allure-java-diff-utils")
include("allure-jax-rs")
include("allure-jbehave")
include("allure-jbehave5")