diff --git a/java-reporter-junit/.gitignore b/java-reporter-junit/.gitignore index 2e0882f..5ee96b5 100644 --- a/java-reporter-junit/.gitignore +++ b/java-reporter-junit/.gitignore @@ -1,2 +1,58 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ +allure-results/ + +.claude +CLAUDE.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + **/logs/ -**/target/ \ No newline at end of file +**/log/ +*.jar + +**/testomatio.properties + +### IntelliJ IDEA ### +**/.idea/ +.idea +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/java-reporter-junit/README.md b/java-reporter-junit/README.md index 5e6d712..c05e7cb 100644 --- a/java-reporter-junit/README.md +++ b/java-reporter-junit/README.md @@ -4,7 +4,8 @@ This simple demo shows how Testomat.io Java reporter works in your project. -- Some will fail on purpose and other will be disabled for demo. +>NOTE: Some will fail on purpose and other will be disabled for demo. +--- ## Installation @@ -21,31 +22,54 @@ This simple demo shows how Testomat.io Java reporter works in your project. 3. Install dependencies with test skip ```sh - mvn clean install -DskipTests + mvn clean install -DskipTests ##Skip tests as there are some tests to fail on purpose, but you need to install the dependencies though. ``` +For correct handling of tests structure, artifact handling and tests source code importing to the Testomat.io +you need to sync your tests with Testomat.io server. +It's easy to do with Java-Check-Tests CLI. Now there already is the **testomatio.jar** in the root of the project and you don't need +to download it. Just run the command: +```bash + java -jar testomatio.jar sync --apikey=... ##provide your project api key +``` +> NOTE: more details about Java-Check-Tests you can find in its [repository](https://github.com/testomatio/java-check-tests) + +--- ## Configurations -**By default, the library runs with properties default values except `testomatio.api.key` and `testomatio.listening`** +**By default, the reporter runs when Testomat.io api key is provided in any way:** +Reporting can be disabled with property `testomatio.reporting.disable=1` -![properties image](img/properties.png) +1. As **ENV_VARIABLE** as `TESTOMATIO` +2. Add your project API key to the **testomatio.properties** file as `testomatio` (in the `src/main/resources/testomatio.properties`) +3. As JVM property on as `-Dtestomatio=...` +>NOTE: JVM property will take precedence over ENV variable, ENV variable will take precedence over property file. -Add your project API key to the `testomatio.properties` file ad `testomatio.api.key` +--- +## Artifacts +The reporter supports test artifacts. +As you can see in the `src/test/java/artifact` folder, there are some tests that produce artifacts. +The artifacts are passed to the facade method `Testomatio.artifact(String ...)` as path to the file including extensions. +Artifacts handling is enabled by default and can be disabled with `testomatio.artifact.disable=1` property usage. +If artifacts are not disabled but there are no artifacts passed to the facade method - it won't affect reporting and is ok to use. +--- ## Run Run tests with ```bash - mvn test -Dtestomatio.api.key=tstmt_key #if you did not provide it in the `testomatio.properties` file + mvn test -Dtestomatio.api.key=tstmt_key #if you did not provide it in any other way ``` where `tstmt_key` is your Testomat.io key from a particular project. As a result, you will see a run report in your Project tab -> Runs on Testomat.io. -
+
demo report result png
+ + diff --git a/java-reporter-junit/img/runReport.png b/java-reporter-junit/img/runReport.png index ab2a27d..7f04726 100644 Binary files a/java-reporter-junit/img/runReport.png and b/java-reporter-junit/img/runReport.png differ diff --git a/java-reporter-junit/pom.xml b/java-reporter-junit/pom.xml index ea46a11..2cec464 100644 --- a/java-reporter-junit/pom.xml +++ b/java-reporter-junit/pom.xml @@ -13,14 +13,15 @@ 11 UTF-8 5.9.2 - + 4.15.0 + 5.6.2 io.testomat java-reporter-junit - 0.7.2 + 0.8.0 @@ -35,6 +36,18 @@ ${junit.version} test + + org.seleniumhq.selenium + selenium-java + ${selenium.version} + test + + + io.github.bonigarcia + webdrivermanager + ${webdrivermanager.version} + test + diff --git a/java-reporter-junit/src/main/resources/testomatio.properties b/java-reporter-junit/src/main/resources/testomatio.properties index 0e60611..e337335 100644 --- a/java-reporter-junit/src/main/resources/testomatio.properties +++ b/java-reporter-junit/src/main/resources/testomatio.properties @@ -1,11 +1,4 @@ -#Change to https://beta.testomat.io/ if you use it -testomatio.url=https://app.testomat.io/ +#Particular project api key, starts with "tstmt_" (required, but can be provided here or as ENV_VARIABLE, or JVM property) +testomatio.api.key=tstmt_eP6i7hP8ukSYMe87QY44kG_au-Pj0o5M4A1757529796 -#define the run title, or it will be default_run_title -testomatio.run.title=junit-example-run - -#Particular project api key, starts with "tstmt_" -testomatio.api.key= - -#enables/disables the reporting (remove value to disable) -testomatio.listening=true \ No newline at end of file +testomatio.run.title=ExampleRunTitle diff --git a/java-reporter-junit/src/test/java/artifact/WebDriverArtifactTest.java b/java-reporter-junit/src/test/java/artifact/WebDriverArtifactTest.java new file mode 100644 index 0000000..47d052c --- /dev/null +++ b/java-reporter-junit/src/test/java/artifact/WebDriverArtifactTest.java @@ -0,0 +1,183 @@ +package artifact; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import io.github.bonigarcia.wdm.WebDriverManager; +import io.testomat.core.facade.Testomatio; +import java.io.FileWriter; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.By; +import org.openqa.selenium.OutputType; +import org.openqa.selenium.TakesScreenshot; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; +import org.openqa.selenium.support.ui.ExpectedConditions; +import org.openqa.selenium.support.ui.WebDriverWait; + +@DisplayName("WebDriver Artifact Generation Tests") +public class WebDriverArtifactTest { + + private WebDriver driver; + + private String artifactDir; + + @BeforeEach + void setUp() { + WebDriverManager.chromedriver().setup(); + ChromeOptions options = new ChromeOptions(); + options.addArguments("--headless"); + options.addArguments("--no-sandbox"); + options.addArguments("--disable-dev-shm-usage"); + options.addArguments("--disable-gpu"); + driver = new ChromeDriver(options); + driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); + artifactDir = "target/test-artifacts"; + createArtifactDirectory(); + } + + @AfterEach + void tearDown() { + if (driver != null) { + driver.quit(); + } + } + + @Test + @DisplayName("Should create artifacts with WebDriver") + void shouldCreateArtifactsWithWebDriver() { + try { + driver.get("https://www.google.com"); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + WebElement searchBox = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("q"))); + assertNotNull(searchBox, "Search box should be present"); + searchBox.sendKeys("Selenium WebDriver"); + searchBox.submit(); + Thread.sleep(2000); + String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss")); + takeScreenshot("search_results_" + timestamp + ".png"); + savePageSource("page_source_" + timestamp + ".html"); + saveTestInfo("test_info.txt"); + String currentTitle = driver.getTitle(); + String currentUrl = driver.getCurrentUrl(); + assertTrue(currentUrl.contains("search"), "URL should contain search results"); + Testomatio.artifact(artifactDir + "/test_info.txt"); + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + @Test + @DisplayName("Should create artifacts with WebDriver") + void shouldCreateArtifactsWithWebDriver1() { + try { + driver.get("https://www.google.com"); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + WebElement searchBox = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("q"))); + assertNotNull(searchBox, "Search box should be present"); + searchBox.sendKeys("Selenium WebDriver"); + searchBox.submit(); + Thread.sleep(2000); + String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss")); + takeScreenshot("search_results.png"); + savePageSource("page_source_" + timestamp + ".html"); + saveTestInfo("test_info.txt"); + String currentTitle = driver.getTitle(); + String currentUrl = driver.getCurrentUrl(); + assertTrue(currentUrl.contains("search"), "URL should contain search results"); + Testomatio.artifact(artifactDir + "/test_info.txt", artifactDir + "/search_results.png"); + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + @Test + @DisplayName("Should create artifacts with WebDriver") + void shouldCreateArtifactsWithWebDriver2() { + try { + driver.get("https://www.google.com"); + WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); + WebElement searchBox = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("q"))); + assertNotNull(searchBox, "Search box should be present"); + searchBox.sendKeys("Selenium WebDriver"); + searchBox.submit(); + Thread.sleep(2000); + String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss")); + takeScreenshot("search_results_" + timestamp + ".png"); + savePageSource("page_source.html"); + saveTestInfo("test_info.txt"); + String currentTitle = driver.getTitle(); + String currentUrl = driver.getCurrentUrl(); + assertTrue(currentUrl.contains("search"), "URL should contain search results"); + Testomatio.artifact(artifactDir + "/test_info.txt"); + Testomatio.artifact(artifactDir + "/page_source.html"); + } catch (Exception e) { + fail("Test failed with exception: " + e.getMessage()); + } + } + + private void createArtifactDirectory() { + try { + Path path = Paths.get(artifactDir); + if (!Files.exists(path)) { + Files.createDirectories(path); + } + } catch (IOException e) { + System.err.println("Failed to create artifact directory: " + e.getMessage()); + } + } + + private void takeScreenshot(String fileName) { + try { + TakesScreenshot screenshot = (TakesScreenshot) driver; + byte[] screenshotBytes = screenshot.getScreenshotAs(OutputType.BYTES); + Path screenshotPath = Paths.get(artifactDir, fileName); + Files.write(screenshotPath, screenshotBytes); + System.out.println("Screenshot saved: " + screenshotPath.toAbsolutePath()); + } catch (IOException e) { + System.err.println("Failed to save screenshot: " + e.getMessage()); + } + } + + private void savePageSource(String fileName) { + try { + String pageSource = driver.getPageSource(); + Path sourcePath = Paths.get(artifactDir, fileName); + Files.write(sourcePath, pageSource.getBytes()); + System.out.println("Page source saved: " + sourcePath.toAbsolutePath()); + } catch (IOException e) { + System.err.println("Failed to save page source: " + e.getMessage()); + } + } + + private void saveTestInfo(String fileName) { + try { + Path infoPath = Paths.get(artifactDir, fileName); + try (FileWriter writer = new FileWriter(infoPath.toFile())) { + writer.write("Test Execution Info\n"); + writer.write("==================\n"); + writer.write("Timestamp: " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "\n"); + writer.write("URL: " + driver.getCurrentUrl() + "\n"); + writer.write("Title: " + driver.getTitle() + "\n"); + writer.write("Browser: " + ((ChromeDriver) driver).getCapabilities().getBrowserName() + "\n"); + writer.write("Browser Version: " + ((ChromeDriver) driver).getCapabilities().getBrowserVersion() + "\n"); + writer.write("Window Size: " + driver.manage().window().getSize() + "\n"); + } + System.out.println("Test info saved: " + infoPath.toAbsolutePath()); + } catch (IOException e) { + System.err.println("Failed to save test info: " + e.getMessage()); + } + } +} diff --git a/java-reporter-junit/src/test/java/library/AuthorTest.java b/java-reporter-junit/src/test/java/library/AuthorTest.java index 1d2f857..92cba9f 100644 --- a/java-reporter-junit/src/test/java/library/AuthorTest.java +++ b/java-reporter-junit/src/test/java/library/AuthorTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; + import com.library.Author; import com.library.Book; import com.library.Genre; @@ -195,4 +196,4 @@ void testEqualsWithSameObject() { void testEqualsWithDifferentClass() { assertNotEquals("Not an author", author); } -} \ No newline at end of file +} diff --git a/java-reporter-junit/src/test/java/library/BookTest.java b/java-reporter-junit/src/test/java/library/BookTest.java index 5762bd3..6740935 100644 --- a/java-reporter-junit/src/test/java/library/BookTest.java +++ b/java-reporter-junit/src/test/java/library/BookTest.java @@ -4,6 +4,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; + import com.library.Author; import com.library.Book; import com.library.Genre; diff --git a/java-reporter-junit/src/test/java/library/LibraryTest.java b/java-reporter-junit/src/test/java/library/LibraryTest.java index ea53d52..ac6229f 100644 --- a/java-reporter-junit/src/test/java/library/LibraryTest.java +++ b/java-reporter-junit/src/test/java/library/LibraryTest.java @@ -6,6 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; + import com.library.Author; import com.library.Book; import com.library.Genre; diff --git a/java-reporter-junit/src/test/java/library/LoanTest.java b/java-reporter-junit/src/test/java/library/LoanTest.java index 1e64e32..6dd5634 100644 --- a/java-reporter-junit/src/test/java/library/LoanTest.java +++ b/java-reporter-junit/src/test/java/library/LoanTest.java @@ -7,6 +7,7 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; + import com.library.Author; import com.library.Book; import com.library.Genre; diff --git a/java-reporter-junit/src/test/java/library/ReaderTest.java b/java-reporter-junit/src/test/java/library/ReaderTest.java index d8cf5b2..52832e0 100644 --- a/java-reporter-junit/src/test/java/library/ReaderTest.java +++ b/java-reporter-junit/src/test/java/library/ReaderTest.java @@ -5,6 +5,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; + import com.library.Author; import com.library.Book; import com.library.Genre; @@ -12,7 +13,6 @@ import com.library.Loan; import com.library.Publisher; import com.library.Reader; - import java.time.LocalDate; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/java-reporter-junit/src/test/java/parametrized/ArgumentsSourceParameterizedTests.java b/java-reporter-junit/src/test/java/parametrized/ArgumentsSourceParameterizedTests.java index 699b92d..d6da1eb 100644 --- a/java-reporter-junit/src/test/java/parametrized/ArgumentsSourceParameterizedTests.java +++ b/java-reporter-junit/src/test/java/parametrized/ArgumentsSourceParameterizedTests.java @@ -4,8 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; - -import io.testomat.core.annotation.TestId; import java.util.stream.Stream; import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.params.ParameterizedTest; @@ -57,7 +55,6 @@ public Stream provideArguments(ExtensionContext context) { @ParameterizedTest(name = "Person: {0}, Age: {1}, Role: {2}") @ArgumentsSource(PersonArgumentsProvider.class) - @TestId("0952de9d") void testPersonDataValidation(String name, int age, String role) { assertNotNull(name); assertTrue(age > 18); @@ -68,7 +65,6 @@ void testPersonDataValidation(String name, int age, String role) { @ParameterizedTest(name = "Numbers: {0} and {1}") @ArgumentsSource(NumberPairsProvider.class) - @TestId("024b1ab3") void testNumberPairOperations(int first, int second) { assertTrue(first < second); assertTrue(first + second > 0); @@ -77,7 +73,6 @@ void testNumberPairOperations(int first, int second) { @ParameterizedTest(name = " Product: {0}, Price: ${1}, Smartphone: {2}") @ArgumentsSource(ProductDataProvider.class) - @TestId("d8852398") void testProductValidation(String productName, double price, boolean isSmartphone) { assertNotNull(productName); assertTrue(price > 0); @@ -89,7 +84,6 @@ void testProductValidation(String productName, double price, boolean isSmartphon @ParameterizedTest(name = "Math: {0} + {1} = {2}, {0} * {1} = {3}") @ArgumentsSource(CalculationProvider.class) - @TestId("83312e71") void testMathematicalOperations(int a, int b, int sum, int product) { assertEquals(sum, a + b); assertEquals(product, a * b); @@ -99,7 +93,6 @@ void testMathematicalOperations(int a, int b, int sum, int product) { @ParameterizedTest(name = "String: {0}, Valid: {1}") @ArgumentsSource(StringValidationProvider.class) - @TestId("d966ee94") void testStringValidation(String input, boolean isValid) { assertNotNull(input); if (isValid) { diff --git a/java-reporter-junit/src/test/java/parametrized/MultipleArgumentsParameterizedTests.java b/java-reporter-junit/src/test/java/parametrized/MultipleArgumentsParameterizedTests.java index f933a29..1c31796 100644 --- a/java-reporter-junit/src/test/java/parametrized/MultipleArgumentsParameterizedTests.java +++ b/java-reporter-junit/src/test/java/parametrized/MultipleArgumentsParameterizedTests.java @@ -4,8 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; - -import io.testomat.core.annotation.TestId; import java.time.LocalDate; import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; @@ -36,7 +34,6 @@ static Stream provideValidationScenarios() { @ParameterizedTest(name = "User data validation: {0}, {1}, age {2}, {3}, salary ${4}") @MethodSource("provideComplexUserData") - @TestId("c1d93773") void testComplexUserDataValidation(String username, String email, int age, String position, double salary) { assertNotNull(username); assertNotNull(email); @@ -52,7 +49,6 @@ void testComplexUserDataValidation(String username, String email, int age, Strin @ParameterizedTest(name = "Order calculation: {0} x{1} at ${2} with {3}% discount = ${4}") @MethodSource("provideOrderCalculations") - @TestId("23e11530") void testOrderTotalCalculation(String item, int quantity, double unitPrice, double discount, double expectedTotal) { assertNotNull(item); assertTrue(quantity > 0); @@ -66,7 +62,6 @@ void testOrderTotalCalculation(String item, int quantity, double unitPrice, doub @ParameterizedTest(name = "Date range: {0} to {1} = {2} days") @MethodSource("provideDateRangeData") - @TestId("d7d5b24e") void testDateRangeCalculations(String startDateStr, String endDateStr, int expectedDays) { LocalDate startDate = LocalDate.parse(startDateStr); LocalDate endDate = LocalDate.parse(endDateStr); @@ -79,7 +74,6 @@ void testDateRangeCalculations(String startDateStr, String endDateStr, int expec @ParameterizedTest(name = "Geometry: {0} {1}x{2} area={3} perimeter={4}") @MethodSource("provideGeometryData") - @TestId("2a147b77") void testGeometricCalculations(String shape, double width, double height, double expectedArea, double expectedPerimeter) { assertNotNull(shape); assertTrue(width > 0); @@ -105,7 +99,6 @@ void testGeometricCalculations(String shape, double width, double height, double @ParameterizedTest(name = "Password validation: '{0}' minLen={1} digits={2} lower={3} upper={4}") @MethodSource("provideValidationScenarios") - @TestId("51cbaba3") void testPasswordValidation(String password, int minLength, boolean hasDigits, boolean hasLower, boolean hasUpper) { assertNotNull(password); assertTrue(password.length() >= minLength); diff --git a/java-reporter-junit/testomatio.jar b/java-reporter-junit/testomatio.jar deleted file mode 100644 index 09c875b..0000000 Binary files a/java-reporter-junit/testomatio.jar and /dev/null differ