Skip to content

Commit

Permalink
HPCC-31857 : Develop an automated ECL Watch Test Suite
Browse files Browse the repository at this point in the history
Developed a testing framework using Java, Selenium, and TestNG. The framework is initiated by `TestRunner.java`, which loads all test classes listed in `config/TestClasses.java` and executes them sequentially. Each test class contains at least one method annotated with `@Test`, which serves as the entry point for the tests. Test cases cover the Activities and ECL Workunit pages, including tests for text presence, link functionality, sorting order, workunits content, description, and checkbox functionality and testing tab clicks. Added loggers in separate files for error, exception, debug, and detail. Updated YML files to reflect jars and commands for the current testing framework. Additionally, provided comprehensive documentation with UML diagrams and detailed explanations of each method within the classes.

Signed-off-by: Nisha Bagdwal <[email protected]>
  • Loading branch information
Nisha-Bagdwal committed Aug 2, 2024
1 parent 5713cdd commit 4dde180
Show file tree
Hide file tree
Showing 61 changed files with 4,153 additions and 31 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/build-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ jobs:
${{ github.workspace }}/HPCC-Platform/.github/workflows/timeoutcmd
if-no-files-found: error

- name: Upload UI Test Files
- name: Upload ECL Watch UI Test Files
if: ${{ inputs.upload-package == true }}
uses: actions/upload-artifact@v3
with:
name: ${{ inputs.asset-name }}-ui_test-files
name: ${{ inputs.asset-name }}-ecl_watch_ui_tests
path: |
${{ github.workspace }}/HPCC-Platform/esp/src/test-ui/**/*
${{ github.workspace }}/HPCC-Platform/esp/src/test-ui/tests/**/*
if-no-files-found: error

- name: Upload Error Logs
Expand Down
77 changes: 50 additions & 27 deletions .github/workflows/test-ui-gh_runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ on:
type: string
description: 'Dependencies'
required: false
default: 'bison flex build-essential binutils-dev curl lsb-release libcppunit-dev python3-dev default-jdk r-base-dev r-cran-rcpp r-cran-rinside r-cran-inline libtool autotools-dev automake git cmake xmlstarlet'
default: 'bison flex build-essential binutils-dev curl lsb-release libcppunit-dev python3-dev r-base-dev r-cran-rcpp r-cran-rinside r-cran-inline libtool autotools-dev automake git cmake xmlstarlet'

env:
uploadArtifact: false

jobs:

Expand All @@ -33,17 +36,17 @@ jobs:
- name: Download UI Test Files
uses: actions/download-artifact@v3
with:
name: ${{ inputs.asset-name }}-ui_test-files
path: ${{ inputs.asset-name }}-ui_test-files
name: ${{ inputs.asset-name }}-ecl_watch_ui_tests
path: ${{ inputs.asset-name }}-ecl_watch_ui_tests

- name: Check ECLWatch UI Test Directory
id: check
run: |
if [[ ! -d ${{ inputs.asset-name }}-ui_test-files ]]
if [[ ! -d ${{ inputs.asset-name }}-ecl_watch_ui_tests ]]
then
echo "ECLWatch UI ${{ inputs.asset-name }}-ui_test-files directory missing."
echo "ECLWatch UI ${{ inputs.asset-name }}-ecl_watch_ui_tests directory missing."
else
javaFilesCount=$(find ${{ inputs.asset-name }}-ui_test-files/ -iname '*.java' -type f -print | wc -l )
javaFilesCount=$(find ${{ inputs.asset-name }}-ecl_watch_ui_tests/ -iname '*.java' -type f -print | wc -l )
echo "Number of test java files is $javaFilesCount"
if [[ ${javaFilesCount} -eq 0 ]]
then
Expand All @@ -66,7 +69,6 @@ jobs:
unzip \
xvfb \
libxi6 \
default-jdk \
gdb \
${{ inputs.dependencies }}
Expand Down Expand Up @@ -95,7 +97,7 @@ jobs:
chmod +x ./${{ inputs.asset-name }}-support-files/*
sudo cp ./${{ inputs.asset-name }}-support-files/* /opt/HPCCSystems/bin
chmod +x ./${{ inputs.asset-name }}-ui_test-files/*
chmod +x ./${{ inputs.asset-name }}-ecl_watch_ui_tests/*
- name: Start HPCC-Platform
shell: "bash"
Expand Down Expand Up @@ -134,36 +136,57 @@ jobs:
if: steps.check.outputs.runtests
shell: "bash"
run: |
sudo apt remove -y openjdk-11-jdk
sudo apt autoremove -y
sudo apt update
sudo apt install -y openjdk-21-jdk
sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/java-21-openjdk-amd64/bin/java 1
sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/java-21-openjdk-amd64/bin/javac 1
sudo update-alternatives --set java /usr/lib/jvm/java-21-openjdk-amd64/bin/java
sudo update-alternatives --set javac /usr/lib/jvm/java-21-openjdk-amd64/bin/javac
export JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64/bin/java
export PATH=$PATH:$JAVA_HOME/bin
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt-get install -y ./google-chrome-stable_current_amd64.deb
wget https://chromedriver.storage.googleapis.com/2.41/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/bin/chromedriver
wget https://storage.googleapis.com/chrome-for-testing-public/126.0.6478.126/linux64/chromedriver-linux64.zip
unzip chromedriver-linux64.zip -d chromedriver
sudo mv chromedriver/chromedriver-linux64/chromedriver /usr/bin/chromedriver
sudo chown root:root /usr/bin/chromedriver
sudo chmod +x /usr/bin/chromedriver
wget https://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar
wget http://www.java2s.com/Code/JarDownload/testng/testng-6.8.7.jar.zip
unzip testng-6.8.7.jar.zip
- name: Run Tests
timeout-minutes: 10 # generous, current runtime is ~1min, this should be increased if new tests are added
wget https://repo1.maven.org/maven2/org/testng/testng/7.7.1/testng-7.7.1.jar
wget https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.17.0/jackson-annotations-2.17.0.jar
wget https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.17.0/jackson-core-2.17.0.jar
wget https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.17.0/jackson-databind-2.17.0.jar
wget https://repo1.maven.org/maven2/com/beust/jcommander/1.82/jcommander-1.82.jar
wget https://github.com/SeleniumHQ/selenium/releases/download/selenium-4.22.0/selenium-java-4.22.0.zip
wget https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar
wget https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.30/slf4j-simple-1.7.30.jar
unzip selenium-java-4.22.0.zip -d selenium-libs
- name: Run ECL Watch UI Tests
timeout-minutes: 80 # generous, current runtime is ~38 minutes, this should be increased if new tests are added
if: steps.check.outputs.runtests
shell: "bash"
run: |
export CLASSPATH=".:${{ github.workspace }}/selenium-server-standalone-3.141.59.jar:${{ github.workspace }}/testng-6.8.7.jar"
pushd ${{ inputs.asset-name }}-ui_test-files
./run.sh tests http://localhost:8010 > eclWatchUiTest.log 2>&1
retCode=$?
echo "UI test done"
[[ $retCode -ne 0 ]] && exit 1
export CLASSPATH=".:${{ inputs.asset-name }}-ecl_watch_ui_tests:${{ github.workspace }}/selenium-libs/*:${{ github.workspace }}/testng-7.7.1.jar:${{ github.workspace }}/jackson-annotations-2.17.0.jar:${{ github.workspace }}/jackson-core-2.17.0.jar:${{ github.workspace }}/jackson-databind-2.17.0.jar:${{ github.workspace }}/jcommander-1.82.jar:${{ github.workspace }}/slf4j-api-1.7.30.jar:${{ github.workspace }}/slf4j-simple-1.7.30.jar"
pushd ${{ inputs.asset-name }}-ecl_watch_ui_tests
find . -iname '*.java' -type f -print -exec javac -Xlint:none {} \;
java framework.TestRunner -l detail -p /home/runner/HPCCSystems-regression/log/
echo "ECL Watch UI test done"
lines=$(wc -l < error_ecl_test.log)
[[ $lines -ne 0 ]] && exit 1
if [[ -f debug_ecl_test.log || -f detail_ecl_test.log || -f exception_ecl_test.log ]]
then
echo "uploadArtifact=true" >> $GITHUB_ENV
fi
popd
- name: eclwatch-ui-test-logs-artifact
if: ${{ failure() || cancelled() }}
- name: Upload ECL Watch UI Test Logs To Artifact
if: ${{ failure() || cancelled() || env.uploadArtifact == 'true' }}
uses: actions/upload-artifact@v3
with:
name: ${{ inputs.asset-name }}-ui_test-logs
name: ${{ inputs.asset-name }}-ecl_watch_ui_tests
path: |
${{ inputs.asset-name }}-ui_test-files/eclWatchUiTest.log
${{ inputs.asset-name }}-ecl_watch_ui_tests/*.log
/home/runner/HPCCSystems-regression/log/*.json
if-no-files-found: error
2 changes: 1 addition & 1 deletion esp/src/test-ui/tests/Activities.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static void main(String[] args) throws IOException, InterruptedException
Capabilities caps = ((RemoteWebDriver) driver).getCapabilities();

String browserName = caps.getBrowserName();
String browserVersion = caps.getVersion();
//String browserVersion = caps.getVersion();
// System.out.println(browserName+" "+browserVersion);

driver.get(args[0]);
Expand Down
65 changes: 65 additions & 0 deletions esp/src/test-ui/tests/framework/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
### Project: An Automated ECL Watch Test Suite

This project's code begins with the TestRunner.java file. The main method in this class loads all the Java classes
created for writing test cases for specific web pages of the ECL Watch UI and then runs the tests in those classes
sequentially.

The names of the Java classes that the TestRunner class needs to load should be listed in the config/TestClasses.java
file. ActivitiesTest class should always be the first class to load in TestClasses.java, as it gets URLs for all other web pages.

Each Java class created to write tests for specific web pages should have at least one method annotated with @Test. The
code for each class starts to run from this method.

#### Important Note: ChromeDriver Version Compatibility

If the Chrome browser version updates in the future, it's crucial to ensure that the corresponding ChromeDriver version is also updated. Failure to do so may cause tests to fail due to compatibility issues between the browser and driver. Always verify and update ChromeDriver to the latest version whenever running tests to maintain compatibility and ensure smooth test execution.

#### CLI Arguments for TestRunner.java

While running the test suite, you can pass arguments in this way -> "-l log_level -p path".
- "log_level" is of two types "debug" and "detail"
- "debug" means generate error and exception log file with a debug log file.
- "detail" means generate error and exception log file with a detailed debug file.
- If no -l and log_level is passed in the argument, only error and exception log will be generated
- "path" is the path of the folder where the json files are
- The code will log an error if the '-p' and 'path' arguments are not provided, as the JSON folder path is required for the test suite.
- -h in the CLI arguments prints the details of parameter usage to the console

path could be something like:

for GitHub Actions -> /home/runner/HPCCSystems-regression/log/

for local machine -> C:/Users/{your_working_directory_of_json_files}/

So an example of complete CLI arguments would look like this:

-l detail -p /home/runner/HPCCSystems-regression/log/

#### Implementation Steps for URL Management

- A HashMap (urlMap) is created to store URL mappings in config/URLConfig.java file. This map will use the page name as the key and a URLMapping object as the value. The URLMapping object contains the page name, its URL, and another HashMap for nested pages and tabs.
- A static block is used to initialize the urlMap with the initial URL mapping for the Activities navigation. The URL is retrieved using a method from the Common utility class, which handles the dynamic retrieval of the IP address based on the environment whether it is local or GitHub Actions.
- For each main navigation section, a URLMapping object is created. This object includes the page name and its corresponding URL. Additionally, it contains another HashMap to store URLs for nested tabs and pages.
- Each URLMapping object is stored in the urlMap with the main navigation name as the key. This initial setup in the Activities.java class ensures that each navigation section has its base URL stored and accessible.
- For instance, for any navigation page, each page has multiple tabs, and within those tabs, there are multiple pages and tabs. This structure facilitates easy access to the URL of a particular page.
- Starting from the Activities page, for each main navigation section, the code iterates over its associated tabs. For each tab, a new URLMapping object is created and added to the HashMap within the corresponding URLMapping object of the main navigation section. This creates a tree-like structure, allowing easy access to URLs for both navigation sections and their nested tabs.
- By following these implementation steps, the URLConfig class ensures that all URLs within the application are well-organized and easily accessible through a hierarchical structure. This setup simplifies navigation and URL management within the application, making it easier to handle complex page structures and dynamic URL retrievals.


Below are the dependencies used in the project:

- https://repo1.maven.org/maven2/org/testng/testng/7.7.1/testng-7.7.1.jar
- https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.17.0/jackson-annotations-2.17.0.jar
- https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.17.0/jackson-core-2.17.0.jar
- https://repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.17.0/jackson-databind-2.17.0.jar
- https://repo1.maven.org/maven2/com/beust/jcommander/1.82/jcommander-1.82.jar
- https://github.com/SeleniumHQ/selenium/releases/download/selenium-4.22.0/selenium-java-4.22.0.zip
- https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.30/slf4j-api-1.7.30.jar
- https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.30/slf4j-simple-1.7.30.jar

Notes:
1. Users need to run these tests with regression test suite only.
2. Code should be updated accordingly if selenium server jar updates.
3. ActivitiesTest class should always be the first class to load in TestClasses.java, as it gets URLs for all other pages.
4. For future testing developers, custom class names or attributes defined by UI developers can change frequently during updates or redesigns. However, standard attributes that are part of the HTML specifications (such as id, type, value, href, aria-sort, aria-disabled, etc.) are much more stable. Therefore, it is advisable to use only standard HTML attributes to access web elements. This approach ensures that test cases remain consistent and are less likely to break due to UI changes.
5. Ignore the compiler warnings/errors before the beginning of the test logs. They are because of guava-33.2.1-jre-sources.jar, it seems it is not fully compatible with JRE 21, that is installed on GH Actions. But that does not impact our code in any way, so it is better to just ignore it.
Loading

0 comments on commit 4dde180

Please sign in to comment.