diff --git a/openmaqs-base/pom.xml b/openmaqs-base/pom.xml index 984ed6141..5e6e8d299 100644 --- a/openmaqs-base/pom.xml +++ b/openmaqs-base/pom.xml @@ -15,6 +15,10 @@ ${revision} jar + + 5.9.2 + + io.github.openmaqs.utilities @@ -24,5 +28,15 @@ org.testng testng + + org.junit.jupiter + junit-jupiter-api + ${junit.version} + + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + diff --git a/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseGenericTest.java b/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseGenericTest.java index b90dc8f98..ad5bf1b55 100644 --- a/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseGenericTest.java +++ b/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseGenericTest.java @@ -19,6 +19,6 @@ protected void beforeLoggingTeardown(ITestResult resultType) { @Override protected void createNewTestObject() { this.setTestObject( - new BaseTestObject(this.createLogger(), this.getFullyQualifiedTestClassName())); + new BaseTestObject(this.createLogger(), this.getFullyQualifiedTestClassName())); } } \ No newline at end of file diff --git a/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseTest.java b/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseTest.java index e5bd01ab7..97d8cc51d 100644 --- a/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseTest.java +++ b/openmaqs-base/src/main/java/io/github/openmaqs/base/BaseTest.java @@ -7,6 +7,8 @@ import static java.lang.System.out; import io.github.openmaqs.base.exceptions.MAQSRuntimeException; +import io.github.openmaqs.base.interfaces.TestResult; +import io.github.openmaqs.base.watcher.JunitTestWatcher; import io.github.openmaqs.utilities.helper.StringProcessor; import io.github.openmaqs.utilities.logging.ConsoleLogger; import io.github.openmaqs.utilities.logging.FileLogger; @@ -16,6 +18,7 @@ import io.github.openmaqs.utilities.logging.LoggingConfig; import io.github.openmaqs.utilities.logging.LoggingEnabled; import io.github.openmaqs.utilities.logging.MessageType; +import io.github.openmaqs.utilities.logging.TestResultType; import io.github.openmaqs.utilities.performance.IPerfTimerCollection; import io.github.openmaqs.utilities.performance.PerfTimerCollection; import java.lang.reflect.Method; @@ -27,15 +30,19 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.lang3.exception.ExceptionUtils; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInfo; +import org.junit.jupiter.api.extension.RegisterExtension; import org.testng.ITestContext; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; /** - * The Base test class. + * The Base Test class. */ public abstract class BaseTest { @@ -54,6 +61,11 @@ public abstract class BaseTest { */ private ITestResult testResult; + /** + * The JUnit test result object. + */ + private TestResult junitTestResult; + /** * The Collection of Base Test Objects to use. */ @@ -74,12 +86,17 @@ public abstract class BaseTest { */ ThreadLocal fullyQualifiedTestClassName = new ThreadLocal<>(); + + @RegisterExtension + public JunitTestWatcher testWatcher; + /** * Initializes a new instance of the BaseTest class. */ protected BaseTest() { this.loggedExceptions = new ConcurrentHashMap<>(); this.baseTestObjects = new ConcurrentManagerHashMap(); + this.testWatcher = new JunitTestWatcher(this); } /** @@ -215,7 +232,36 @@ public void setTestObject(BaseTestObject baseTestObject) { } /** - * Setup before a test. + * Setup before a JUnit test. + * + * @param info the test info of the unit test being run + */ + @BeforeEach + public void setup(TestInfo info) { + String testClassName = null; + String testMethodName = null; + + // Get the Fully Qualified Test Class Name and set it in the object + if (info.getTestClass().isPresent()) { + Optional> optional = info.getTestClass(); + if (optional.isPresent()) { + testClassName = optional.get().getName(); + } + } + + if (info.getTestMethod().isPresent()) { + Optional optional = info.getTestMethod(); + if (optional.isPresent()) { + testMethodName = optional.get().getName(); + } + } + + String testName = testClassName + "." + testMethodName; + customSetup(testName); + } + + /** + * Setup before a testng unit test. * * @param method The initial executing Method object * @param testContext The initial executing Test Context object @@ -237,22 +283,25 @@ public void setup(Method method, ITestContext testContext) { */ public void customSetup(String testName, ITestContext testContext) { this.testContextInstance = testContext; + customSetup(testName); + } + private void customSetup(String testName) { testName = testName.replaceFirst("class ", ""); this.fullyQualifiedTestClassName.set(testName); - this.createNewTestObject(); } /** - * Cleanup after a test. + * Cleanup after a TestNG test. */ @AfterMethod(alwaysRun = true) public void teardown() { try { this.beforeLoggingTeardown(testResult); } catch (Exception e) { - this.tryToLog(MessageType.WARNING, "Failed before logging teardown because: %s", e.getMessage()); + this.tryToLog(MessageType.WARNING, "Failed before logging teardown because: %s", + e.getMessage()); } // Log the test result @@ -280,6 +329,42 @@ public void teardown() { this.tryToLog(MessageType.WARNING, "Failed to cleanup log files because: %s", e.getMessage()); } + cleanUpTest(); + } + + /** + * Cleanup after a JUnit test. + */ + public void teardownJunit() { + // Log the test result + if (junitTestResult.isSuccess()) { + this.tryToLog(MessageType.SUCCESS, "Test Passed"); + } else if (junitTestResult.getStatus() == TestResultType.FAIL) { + this.tryToLog(MessageType.ERROR, "Test Failed"); + } else if (junitTestResult.getStatus() == TestResultType.SKIP) { + this.tryToLog(MessageType.INFORMATION, "Test was skipped"); + } else { + this.tryToLog(MessageType.WARNING, "Test had an unexpected result."); + } + + // Cleanup log files we don't want + try { + if ((this.getLogger() instanceof FileLogger) + && junitTestResult.getStatus() == TestResultType.PASS + && this.loggingEnabledSetting == LoggingEnabled.ONFAIL) { + Files.delete(Paths.get(((FileLogger) this.getLogger()).getFilePath())); + } + } catch (Exception e) { + this.tryToLog(MessageType.WARNING, "Failed to cleanup log files because: %s", e.getMessage()); + } + + cleanUpTest(); + } + + /** + * Cleans up logs and files after the test. + */ + private void cleanUpTest() { // Get the Fully Qualified Test Name String fullyQualifiedTestName = this.fullyQualifiedTestClassName.get(); @@ -310,6 +395,10 @@ public void setTestResult(ITestResult testResult) { this.testResult = testResult; } + public void setTestResult(TestResult testResult) { + this.junitTestResult = testResult; + } + /** * Steps to take before logging teardown results. * @@ -330,7 +419,8 @@ protected ILogger createLogger() { if (this.loggingEnabledSetting != LoggingEnabled.NO) { return LoggerFactory.getLogger( StringProcessor.safeFormatter("%s - %s", this.fullyQualifiedTestClassName.get(), - DateTimeFormatter.ofPattern(Logger.DEFAULT_DATE_TIME_FORMAT, + DateTimeFormatter.ofPattern( + Logger.DEFAULT_DATE_TIME_FORMAT, Locale.getDefault()).format(LocalDateTime.now(Clock.systemUTC())))); } else { return LoggerFactory.getConsoleLogger(); diff --git a/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/JunitTestResult.java b/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/JunitTestResult.java new file mode 100644 index 000000000..b860b4136 --- /dev/null +++ b/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/JunitTestResult.java @@ -0,0 +1,25 @@ +/* + * Copyright 2023 (C) OpenMAQS, All rights Reserved + */ + +package io.github.openmaqs.base.interfaces; + +import io.github.openmaqs.utilities.logging.TestResultType; + +public class JunitTestResult implements TestResult { + private final TestResultType currentStatus; + + public JunitTestResult(TestResultType status) { + this.currentStatus = status; + } + + @Override + public TestResultType getStatus() { + return this.currentStatus; + } + + @Override + public boolean isSuccess() { + return currentStatus == TestResultType.PASS; + } +} diff --git a/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/TestResult.java b/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/TestResult.java new file mode 100644 index 000000000..0627f60d0 --- /dev/null +++ b/openmaqs-base/src/main/java/io/github/openmaqs/base/interfaces/TestResult.java @@ -0,0 +1,13 @@ +/* + * Copyright 2023 (C) OpenMAQS, All rights Reserved + */ + +package io.github.openmaqs.base.interfaces; + +import io.github.openmaqs.utilities.logging.TestResultType; + +public interface TestResult { + TestResultType getStatus(); + + boolean isSuccess(); +} diff --git a/openmaqs-base/src/main/java/io/github/openmaqs/base/watcher/JunitTestWatcher.java b/openmaqs-base/src/main/java/io/github/openmaqs/base/watcher/JunitTestWatcher.java new file mode 100644 index 000000000..c37df25f1 --- /dev/null +++ b/openmaqs-base/src/main/java/io/github/openmaqs/base/watcher/JunitTestWatcher.java @@ -0,0 +1,36 @@ +/* + * Copyright 2023 (C) OpenMAQS, All rights Reserved + */ + +package io.github.openmaqs.base.watcher; + +import io.github.openmaqs.base.BaseTest; +import io.github.openmaqs.base.interfaces.JunitTestResult; +import io.github.openmaqs.utilities.logging.TestResultType; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestWatcher; + +/** + * The JUnit Test Watcher class. + */ +public class JunitTestWatcher implements TestWatcher { + + // Test instance of the test being executed per each thread. + BaseTest testInstance; + + public JunitTestWatcher(BaseTest testInstance) { + this.testInstance = testInstance; + } + + @Override + public void testSuccessful(ExtensionContext context) { + this.testInstance.setTestResult(new JunitTestResult(TestResultType.PASS)); + this.testInstance.teardownJunit(); + } + + @Override + public void testFailed(ExtensionContext context, Throwable cause) { + this.testInstance.setTestResult(new JunitTestResult(TestResultType.FAIL)); + this.testInstance.teardownJunit(); + } +} \ No newline at end of file diff --git a/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseGenericTestUnitTest.java b/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseGenericTestUnitTest.java new file mode 100644 index 000000000..ca4ddb42c --- /dev/null +++ b/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseGenericTestUnitTest.java @@ -0,0 +1,17 @@ +/* + * Copyright 2023 (C) OpenMAQS, All rights Reserved + */ + +package io.github.openmaqs.base.junit; + +import io.github.openmaqs.base.BaseGenericTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +class JUnitBaseGenericTestUnitTest extends BaseGenericTest { + + @Test + void testCreateTestObject() { + Assertions.assertNotNull(this.getTestObject()); + } +} \ No newline at end of file diff --git a/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseTestObjectUnitTest.java b/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseTestObjectUnitTest.java new file mode 100644 index 000000000..4188676d3 --- /dev/null +++ b/openmaqs-base/src/test/java/io/github/openmaqs/base/junit/JUnitBaseTestObjectUnitTest.java @@ -0,0 +1,301 @@ +/* + * Copyright 2023 (C) OpenMAQS, All rights Reserved + */ + +package io.github.openmaqs.base.junit; + +import io.github.openmaqs.base.BaseGenericTest; +import io.github.openmaqs.base.BaseTestObject; +import io.github.openmaqs.base.DriverManager; +import io.github.openmaqs.base.ITestObject; +import io.github.openmaqs.utilities.logging.ILogger; +import io.github.openmaqs.utilities.performance.PerfTimerCollection; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.Assertions; +import java.io.File; +import java.io.IOException; +import java.util.Objects; +import java.util.function.Supplier; + +/** + * The JUnit Base Test Object unit test. + */ +class JUnitBaseTestObjectUnitTest extends BaseGenericTest { + + /** + * Test Constructor with Log and Method. + */ + @Test + void testBaseTestObject1() { + final ITestObject testObject = this.getTestObject(); + + // final String methodName = this.method.getName(); + BaseTestObject baseTestObject = new BaseTestObject(testObject.getLogger(), "FakeTestName"); + Assertions.assertNotNull(baseTestObject, "Checking that Base Test Object instantiated correctly"); + } + + /** + * Test Constructor with Test Object. + */ + @Test + void testBaseTestObject2() { + final ITestObject testObject = this.getTestObject(); + BaseTestObject baseTestObject = new BaseTestObject(testObject); + Assertions.assertNotNull(baseTestObject, "Checking that Base Test Object instantiated correctly"); + + } + + /** + * Test set value. + */ + @Test + void testSetValue() { + ITestObject testObject = this.getTestObject(); + final String key = "SetKey"; + final String value = "SetKey Value"; + testObject.setValue(key, value); + Assertions.assertTrue(testObject.getValues().containsKey(key), "Checking that key exists in test object dictionary"); + Assertions.assertEquals(testObject.getValues().get(key), value, "Checking that value set correctly"); + } + + /** + * Test set object. + */ + @Test + void testSetObject() { + ITestObject testObject = this.getTestObject(); + final String key = "SetObject"; + final Object object = new Object(); + testObject.setObject(key, object); + Assertions.assertTrue(testObject.getObjects().containsKey(key), "Checking that key exists in test object dictionary"); + Assertions.assertEquals(testObject.getObjects().get(key), object, "Checking that value set correctly"); + } + + /** + * Test get log. + */ + @Test + void testGetLog() { + ITestObject testObject = this.getTestObject(); + Assertions.assertNotNull(testObject.getLogger(), "Checking that logger is not null."); + } + + /** + * Test set log. + */ + @Test + void testSetLog() { + ITestObject testObject = this.getTestObject(); + final ILogger logger = this.getLogger(); + testObject.setLogger(logger); + Assertions.assertEquals(testObject.getLogger(), logger, "Checking that logger set correctly."); + } + + /** + * Test Get Perf Collection Timer - Not Null. + */ + @Test + void testGetPerfTimerCollectionNotNull() { + ITestObject testObject = this.getTestObject(); + Assertions.assertNotNull(testObject.getPerfTimerCollection(), "Checking that logger is not null."); + } + + /** + * Test Set Perf Collection Timer - Get/Set. + */ + @Test + void testSetPerfTimerCollectionGetSet() { + ITestObject testObject = this.getTestObject(); + final PerfTimerCollection perfTimerCollection = new PerfTimerCollection(testObject.getLogger(), "FakeTestName"); + testObject.setPerfTimerCollection(perfTimerCollection); + Assertions.assertEquals(testObject.getPerfTimerCollection(), perfTimerCollection, + "Checking that perf timer collection set correctly."); + } + + /** + * Test get values. + */ + @Test + void testGetValues() { + ITestObject testObject = this.getTestObject(); + Assertions.assertNotNull(testObject.getValues(), "Checking that values is not null."); + } + + /** + * Test get objects. + */ + @Test + void testGetObjects() { + ITestObject testObject = this.getTestObject(); + Assertions.assertNotNull(testObject.getObjects(), "Checking that objects is not null."); + } + + /** + * Test Get Manager Store - Not Null. + */ + @Test + void testGetManagerStoreNotNull() { + ITestObject testObject = this.getTestObject(); + Assertions.assertNotNull(testObject.getManagerStore(), "Checking that objects is not null."); + } + + /** + * Test add driver manager. + */ + @Test + void testAddDriverManager() { + ITestObject testObject = this.getTestObject(); + final Supplier supplier = () -> null; + DriverManager driverManager = getDriverManager(testObject, supplier); + Assertions.assertEquals(0, testObject.getManagerStore().size(), "Checking that manager store is empty"); + testObject.addDriverManager(driverManager); + Assertions.assertEquals(1, testObject.getManagerStore().size(), "Checking that manager store has 1 object added"); + + } + + /** + * Test add driver manager - Overwrite True. + */ + @Test + void testAddDriverManagerTrue() { + ITestObject testObject = this.getTestObject(); + final Supplier supplier = () -> null; + final DriverManager driverManager = getDriverManager(testObject, supplier); + final DriverManager driverManager2 = getDriverManager(testObject, supplier); + Assertions.assertEquals( 0, testObject.getManagerStore().size(), "Checking that manager store is empty"); + testObject.addDriverManager(driverManager, true); + Assertions.assertEquals(1, testObject.getManagerStore().size(), "Checking that manager store has 1 object added"); + testObject.addDriverManager(driverManager2, true); + Assertions.assertEquals(1, testObject.getManagerStore().size(), "Checking that manager store has 1 object added"); + } + + /** + * Test add driver manager - Overwrite False. + */ + @Test + void testAddDriverManagerFalse() { + ITestObject testObject = this.getTestObject(); + final Supplier supplier = () -> null; + final DriverManager driverManager = getDriverManager(testObject, supplier); + + Assertions.assertEquals(0, testObject.getManagerStore().size(), "Checking that manager store is empty"); + testObject.addDriverManager(driverManager, false); + Assertions.assertEquals(1, testObject.getManagerStore().size(), "Checking that manager store has 1 object added"); + } + + /** + * Test add driver manager 2. + */ + @Test + void testAddDriverManager2() { + ITestObject testObject = this.getTestObject(); + final Supplier supplier = () -> null; + final DriverManager driverManager = getDriverManager(testObject, supplier); + final String key = "DriverManager1"; + Assertions.assertEquals(0, testObject.getManagerStore().size(), "Checking that manager store is empty"); + testObject.addDriverManager(key, driverManager); + Assertions.assertEquals(1, testObject.getManagerStore().size(), "Checking that manager store has 1 object added"); + Assertions.assertTrue(testObject.getManagerStore().containsKey(key), "Checking if key exists in Manager Store"); + } + + /** + * Test close. + */ + @Test + void testClose() throws Exception { + ITestObject testObject = this.getTestObject(); + final Supplier supplier = () -> null; + final DriverManager driverManager = getDriverManager(testObject, supplier); + final String key = "DriverManager1"; + testObject.addDriverManager(key, driverManager); + testObject.close(); + Assertions.assertNull(testObject.getManagerStore(), "Checking that manager store has been closed"); + Assertions.assertEquals(0, testObject.getValues().size(), "Checking if values in manager store are closed"); + + } + + /** + * Test add associated file. + */ + @Test + void testAddAssociatedFile() { + ITestObject testObject = this.getTestObject(); + File temp = null; + try { + temp = File.createTempFile("tempFile", ".tmp"); + } catch (IOException e) { + e.printStackTrace(); + } + + Assertions.assertTrue(Objects.requireNonNull(temp).exists()); + Assertions.assertTrue(testObject.addAssociatedFile(temp.getAbsolutePath()), "Checking that associated file was added"); + Assertions.assertEquals(1, testObject.getArrayOfAssociatedFiles().length, "Checking that one file was added to array."); + } + + /** + * Test remove associated file. + */ + @Test + void testRemoveAssociatedFile() { + ITestObject testObject = this.getTestObject(); + File temp = null; + try { + temp = File.createTempFile("tempFile", ".tmp"); + } catch (IOException e) { + e.printStackTrace(); + } + + Assertions.assertTrue(Objects.requireNonNull(temp).exists()); + final String path = temp.getAbsolutePath(); + + Assertions.assertTrue(testObject.addAssociatedFile(path), "Checking that associated file was added"); + Assertions.assertTrue(testObject.removeAssociatedFile(path), "Checking that associated file was removed"); + } + + /** + * Test get array of associated files. + */ + @Test + void testGetArrayOfAssociatedFiles() { + ITestObject testObject = this.getTestObject(); + File temp = null; + try { + temp = File.createTempFile("tempFile", ".tmp"); + } catch (IOException e) { + e.printStackTrace(); + } + + Assertions.assertTrue(Objects.requireNonNull(temp).exists()); + final String path = temp.getAbsolutePath(); + Assertions.assertTrue(testObject.addAssociatedFile(path), "Checking that associated file was added"); + Assertions.assertNotNull(testObject.getArrayOfAssociatedFiles(), "Checking that array is instantiated"); + Assertions.assertEquals(1, testObject.getArrayOfAssociatedFiles().length, "Checking that array is not empty"); + } + + /** + * Test contains associated file. + */ + @Test() + void testContainsAssociatedFile() { + ITestObject testObject = this.getTestObject(); + File temp = null; + try { + temp = File.createTempFile("tempFile", ".tmp"); + } catch (IOException e) { + e.printStackTrace(); + } + + Assertions.assertTrue(Objects.requireNonNull(temp).exists()); + final String path = temp.getAbsolutePath(); + Assertions.assertTrue(testObject.addAssociatedFile(path), "Checking that associated file was added"); + Assertions.assertNotNull(testObject.getArrayOfAssociatedFiles(), "Checking that array is instantiated"); + Assertions.assertTrue(testObject.containsAssociatedFile(path), "Checking if array contains file"); + } + + private DriverManager getDriverManager(ITestObject testObject, Supplier supplier) { + return new DriverManager<>(supplier, testObject) { + @Override public void close() { + } + }; + } +} \ No newline at end of file diff --git a/openmaqs-base/src/test/resources/junit-platform.properties b/openmaqs-base/src/test/resources/junit-platform.properties new file mode 100644 index 000000000..85c81a9f2 --- /dev/null +++ b/openmaqs-base/src/test/resources/junit-platform.properties @@ -0,0 +1,3 @@ +junit.jupiter.execution.parallel.enabled=true +junit.jupiter.execution.parallel.mode.default=concurrent +junit.jupiter.execution.parallel.mode.classes.default=concurrent \ No newline at end of file diff --git a/openmaqs-selenium/src/main/java/io/github/openmaqs/selenium/exceptions/ElementHandlerException.java b/openmaqs-selenium/src/main/java/io/github/openmaqs/selenium/exceptions/ElementHandlerException.java index 1149a1b13..4b2e3ee87 100644 --- a/openmaqs-selenium/src/main/java/io/github/openmaqs/selenium/exceptions/ElementHandlerException.java +++ b/openmaqs-selenium/src/main/java/io/github/openmaqs/selenium/exceptions/ElementHandlerException.java @@ -31,7 +31,4 @@ public ElementHandlerException(String message) { public ElementHandlerException(String message, Exception exception) { super(message, exception); } - - - }