diff --git a/.github/workflows/maven-regression-test.yml b/.github/workflows/maven-regression-test-rest.yml similarity index 86% rename from .github/workflows/maven-regression-test.yml rename to .github/workflows/maven-regression-test-rest.yml index b36da6009..2909a8fb4 100644 --- a/.github/workflows/maven-regression-test.yml +++ b/.github/workflows/maven-regression-test-rest.yml @@ -1,4 +1,4 @@ -name: Maven Regression Test +name: Maven Regression Test (REST) on: push: @@ -7,7 +7,7 @@ on: branches: [ "main" ] jobs: - regression_test_ENG: + test_ENG: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -19,8 +19,8 @@ jobs: - run: mvn clean - run: mvn verify -P regression-testing-rest -D base.url=http://eng.elimu.ai - regression_test_TGL: - needs: regression_test_ENG + test_TGL: + needs: test_ENG runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -32,8 +32,8 @@ jobs: - run: mvn clean - run: mvn verify -P regression-testing-rest -D base.url=http://tgl.elimu.ai - regression_test_HIN: - needs: regression_test_TGL + test_HIN: + needs: test_TGL runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/maven-regression-test-ui.yml b/.github/workflows/maven-regression-test-ui.yml new file mode 100644 index 000000000..81e68e28e --- /dev/null +++ b/.github/workflows/maven-regression-test-ui.yml @@ -0,0 +1,46 @@ +name: Maven Regression Test (UI) + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + test_ENG: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + cache: maven + - run: mvn clean + - run: mvn verify -P regression-testing-ui -D headless=true -D base.url=http://eng.elimu.ai + + test_TGL: + needs: test_ENG + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + cache: maven + - run: mvn clean + - run: mvn verify -P regression-testing-ui -D headless=true -D base.url=http://tgl.elimu.ai + + test_HIN: + needs: test_TGL + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + cache: maven + - run: mvn clean + - run: mvn verify -P regression-testing-ui -D headless=true -D base.url=http://hin.elimu.ai diff --git a/INSTALL.md b/INSTALL.md index cf972ed3f..c8fd9f8eb 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -39,24 +39,7 @@ Next, to access the application in your browser, go to [http://localhost:8080/we ## Test 🚨 -### Unit testing - -Run all tests: - - mvn clean test - -Run individual tests: - - mvn clean test -D test=WordDaoTest - -### Code coverage - -[![codecov](https://codecov.io/gh/elimu-ai/webapp/branch/main/graph/badge.svg?token=T1F9OTQVOH)](https://codecov.io/gh/elimu-ai/webapp) - -[![](https://codecov.io/gh/elimu-ai/webapp/branch/main/graphs/tree.svg?token=T1F9OTQVOH)](https://codecov.io/gh/elimu-ai/webapp) - - mvn test - open target/site/jacoco/index.html +See [`TEST.md`](./TEST.md) ## Test server diff --git a/TEST.md b/TEST.md new file mode 100644 index 000000000..b9b537ddd --- /dev/null +++ b/TEST.md @@ -0,0 +1,83 @@ +## Test Instructions + +### Unit testing β˜‘οΈ + +Run all tests: + + mvn clean test + +Run individual tests: + + mvn clean test -D test=WordDaoTest + +#### Code coverage πŸ“Š + +[![codecov](https://codecov.io/gh/elimu-ai/webapp/branch/main/graph/badge.svg?token=T1F9OTQVOH)](https://codecov.io/gh/elimu-ai/webapp) + +[![](https://codecov.io/gh/elimu-ai/webapp/branch/main/graphs/tree.svg?token=T1F9OTQVOH)](https://codecov.io/gh/elimu-ai/webapp) + + mvn test + open target/site/jacoco/index.html + +### Regression testing + +#### REST API + +First, launch the webapp on localhost: + + mvn jetty:run + +Then, in another terminal window run all the regression tests against the REST API: + + mvn verify -P regression-testing-rest + +> [!TIP] +> If you want to run the tests against another URL, set the `base.url` system property: +> +> mvn verify -P regression-testing-rest -D base.url=https://eng.elimu.ai + +#### UI + +First, launch the webapp on localhost: + + mvn jetty:run + +Then, in another terminal window run all the regression tests against the UI: + + mvn verify -P regression-testing-ui + +> [!TIP] +> If you want to run the tests against another URL, set the `base.url` system property: +> +> mvn verify -P regression-testing-ui -D base.url=https://eng.elimu.ai + +##### Headless πŸ˜Άβ€πŸŒ«οΈ + +If you don't want the automated test software to open browser windows, you can disable that by setting the `headless` system property: + + mvn verify -P regression-testing-ui -D headless=true + +![](https://private-user-images.githubusercontent.com/1451036/361187317-35e99a19-f42d-4934-a0ba-f3d1e06ed6f6.png) + +--- + +

+ +

+

+ elimu.ai - Free open-source learning software for out-of-school children πŸš€βœ¨ +

+

+ Website 🌐 +  β€’  + Wiki πŸ“ƒ +  β€’  + Projects πŸ‘©πŸ½β€πŸ’» +  β€’  + Milestones 🎯 +  β€’  + Community πŸ‘‹πŸ½ +  β€’  + Support πŸ’œ +

+ diff --git a/Test.md b/Test.md deleted file mode 100644 index bae8efb32..000000000 --- a/Test.md +++ /dev/null @@ -1,51 +0,0 @@ -# Regression Testing Guide - -This document outlines the regression testing process for our project using Maven profiles. - -## Available Profiles - -There are two Maven profiles set up for regression testing: - -1. `regression-testing-rest`: For REST API tests -2. `regression-testing-ui`: For UI tests using Selenium - -## Running Tests - -### REST API Tests - -To run the REST API regression tests, use the following command: -```bash -mvn clean verify -P regression-testing-rest -``` -This profile will: -- Skip the default test phase -- Run tests during the integration-test phase -- Include only test files matching the pattern `**/rest/**/*Test.java` - -### UI Tests - -To run the UI regression tests, use the following command: -```bash -mvn clean verify -P regression-testing-ui -``` -This profile will: -- Skip the default test phase -- Run tests during the integration-test phase -- Include only test files matching the pattern `**/selenium/**/*Test.java` - -## Configuration Details - -Both profiles use the Maven Surefire Plugin with the following key configurations: - -- Tests are skipped during the default test phase -- Tests are executed during the integration-test phase -- All tests are initially excluded, then specific patterns are included - -## Notes - -- Ensure that your test files are named appropriately and located in the correct directories to be picked up by the include patterns. -- The REST tests should be in directories containing "rest" in the path and end with "Test.java" -- The UI tests should be in directories containing "selenium" in the path and end with "Test.java" -- You may need to adjust your project structure or test naming conventions if tests are not being picked up as expected. - -For more detailed information about the Maven profiles and plugin configurations, refer to the `pom.xml` file in the project root. \ No newline at end of file diff --git a/pom.xml b/pom.xml index ea608bb85..4265a723f 100644 --- a/pom.xml +++ b/pom.xml @@ -575,8 +575,8 @@ org.seleniumhq.selenium - selenium-chrome-driver - 3.141.59 + selenium-java + 4.23.1 diff --git a/src/test/java/selenium/DomainHelper.java b/src/test/java/selenium/DomainHelper.java index 75829996d..4a712b8fc 100644 --- a/src/test/java/selenium/DomainHelper.java +++ b/src/test/java/selenium/DomainHelper.java @@ -1,9 +1,5 @@ package selenium; -import ai.elimu.model.v2.enums.Language; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -13,27 +9,14 @@ public class DomainHelper { private static final Logger logger = LogManager.getLogger(); public static String getBaseUrl() { - // Read property set on the command line: + String baseUrl = "http://localhost:8080/webapp"; + + // Read "base.url" property set on the command line: // mvn clean verify -P regression-testing-rest -D base.url=https://eng.test.elimu.ai String baseUrlSystemProperty = System.getProperty("base.url"); logger.info("baseUrlSystemProperty: \"" + baseUrlSystemProperty + "\""); - - String baseUrl = baseUrlSystemProperty; - - if (StringUtils.isBlank(baseUrl)) { - // Read property set in the "config.properties" file - // This will trigger if no "base.url" property is set on the command line - InputStream inputStream = DomainHelper.class.getClassLoader().getResourceAsStream("config.properties"); - Properties properties = new Properties(); - try { - properties.load(inputStream); - String contentLanguageProperty = properties.getProperty("content.language"); - logger.info("contentLanguageProperty: \"" + contentLanguageProperty + "\""); - Language language = Language.valueOf(contentLanguageProperty); - baseUrl = "https://" + language.toString().toLowerCase() + ".test.elimu.ai"; - } catch (IOException ex) { - logger.error(ex); - } + if (StringUtils.isNotBlank(baseUrlSystemProperty)) { + baseUrl = baseUrlSystemProperty; } logger.info("baseUrl: \"" + baseUrl + "\""); diff --git a/src/test/java/selenium/ErrorHelper.java b/src/test/java/selenium/ErrorHelper.java index 8aef781d1..b9459ef0a 100644 --- a/src/test/java/selenium/ErrorHelper.java +++ b/src/test/java/selenium/ErrorHelper.java @@ -7,6 +7,5 @@ public class ErrorHelper { public static void verifyNoScriptOrMarkupError(WebDriver driver) { JavaScriptHelper.verifyNoJavaScriptError(driver); // MarkupValidationHelper.verifyNoMarkupError(driver.getPageSource()); - // TODO: verify no missing translations in page source ("???...???") } } diff --git a/src/test/java/selenium/web/WelcomePage.java b/src/test/java/selenium/web/WelcomePage.java index f84096dd9..297152b5f 100644 --- a/src/test/java/selenium/web/WelcomePage.java +++ b/src/test/java/selenium/web/WelcomePage.java @@ -12,7 +12,7 @@ public class WelcomePage { public WelcomePage(WebDriver driver) { this.driver = driver; - driver.findElement(By.id("welcomePageTEST")); + driver.findElement(By.id("welcomePage")); ErrorHelper.verifyNoScriptOrMarkupError(driver); } diff --git a/src/test/java/selenium/web/WelcomePageTest.java b/src/test/java/selenium/web/WelcomePageTest.java index 2e7ffc9a9..616d674a1 100644 --- a/src/test/java/selenium/web/WelcomePageTest.java +++ b/src/test/java/selenium/web/WelcomePageTest.java @@ -2,10 +2,13 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeOptions; + import selenium.DomainHelper; public class WelcomePageTest { @@ -17,13 +20,29 @@ public class WelcomePageTest { @BeforeEach public void setUp() { logger.info("setUp"); + + ChromeOptions chromeOptions = new ChromeOptions(); + + // Read "headless" property set on the command line: + // mvn clean verify -P regression-testing-ui -D headless=true -D base.url=https://eng.test.elimu.ai + String headlessSystemProperty = System.getProperty("headless"); + logger.info("headlessSystemProperty: \"" + headlessSystemProperty + "\""); + if ("true".equals(headlessSystemProperty)) { + chromeOptions.addArguments("headless"); + } - // See https://www.selenium.dev/documentation/en/webdriver/driver_requirements/#chromium-chrome - System.setProperty("webdriver.chrome.driver", "src/test/resources/selenium/chrome_80.0.3987.106/chromedriver_mac64/chromedriver"); - driver = new ChromeDriver(); + driver = new ChromeDriver(chromeOptions); + driver.get(DomainHelper.getBaseUrl()); } + @AfterEach + public void tearDown() { + logger.info("tearDown"); + + driver.quit(); + } + @Test public void testWelcomePage() { logger.info("testWelcomePage"); diff --git a/src/test/resources/selenium/chrome_80.0.3987.106/chromedriver_mac64/chromedriver b/src/test/resources/selenium/chrome_80.0.3987.106/chromedriver_mac64/chromedriver deleted file mode 100755 index 116149712..000000000 Binary files a/src/test/resources/selenium/chrome_80.0.3987.106/chromedriver_mac64/chromedriver and /dev/null differ