Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TestNG template project - reviewed by free CodeRabbit with GPT-4-turbo model #40

Closed
wants to merge 1 commit into from

Conversation

mialeska
Copy link
Contributor

@mialeska mialeska commented Apr 5, 2024

Summary by CodeRabbit

  • New Feature: Introduced TestNG support with a new Maven POM configuration, enabling the use of TestNG for test execution.
  • Refactor: Implemented CustomBrowserModule and CustomActionRetrier to enhance browser interactions and retry mechanisms.
  • Refactor: Restructured package organization for ServiceModule to improve modularity.
  • Enhancement: Updated AllureBasedLocalizedLogger for better logging capabilities integrated with Allure reports.
  • New Feature: Added ContactUsSteps, LandingSteps, BaseTest, ContactUsTests classes for streamlined UI testing workflows.
  • New Feature: Created JsonDataProvider and ModuleFactory utilities for data-driven testing and module management in TestNG tests.

@mialeska mialeska self-assigned this Apr 5, 2024
Copy link

github-actions bot commented Apr 5, 2024

Image description CodeRabbit

Walkthrough

The update involves refactoring and enhancing a Selenium-based test automation framework. It introduces new classes for better modularity, updates dependencies, and improves the initialization of browser modules. The changes aim to streamline the testing process with TestNG, improve logging with Allure, and facilitate data-driven tests using JSON.

Changes

Files Summary
aquality-selenium-template-cucumber/src/...
aquality-selenium-template/src/main/java/aquality/selenium/template/...
Refactored the project structure, updated import statements, removed unnecessary custom browser module class, added new utility classes, and improved logger implementation.
aquality-selenium-template-testng/pom.xml
aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/...
pom.xml
Added a new Maven POM file for TestNG template project, introduced various new classes for UI interaction, test setup, JSON data provisioning, and module creation. Included a new module in the project configuration.

🐇 A whimsical code hop, we've made today,
With modules and steps in a neat array.
Tests now run with such ease and flair,
Thanks to the changes made with care.
🌟 Through the fields of logic, we dash,
Avoiding bugs with a swift, agile flash.
In our automated world, so pristine and bright,
We celebrate the green tests taking flight. 🚀


Uplevel your code reviews with CodeRabbit Pro

CodeRabbit Pro

If you like this project, please support us by purchasing the Pro version. The Pro version has advanced context, superior noise reduction and several proprietary improvements compared to the open source version. Moreover, CodeRabbit Pro is free for open source projects.

@mialeska mialeska closed this Apr 5, 2024
@mialeska mialeska reopened this Apr 5, 2024
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

Commits Files that changed from the base of the PR and between b7ca6d6 and c3a0d0a commits.
Files selected (15)
  • aquality-selenium-template-cucumber/src/test/java/aquality/selenium/template/cucumber/hooks/AqualityServicesHooks.java (1)
  • aquality-selenium-template-cucumber/src/test/java/aquality/selenium/template/cucumber/objectfactory/CustomBrowserModule.java (1)
  • aquality-selenium-template-cucumber/src/test/java/aquality/selenium/template/cucumber/objectfactory/CustomObjectFactory.java (2)
  • aquality-selenium-template-testng/pom.xml (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/steps/ui/ContactUsSteps.java (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/steps/ui/LandingSteps.java (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/tests/BaseTest.java (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/tests/ContactUsTests.java (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/utilities/JsonDataProvider.java (1)
  • aquality-selenium-template-testng/src/test/java/aquality/selenium/template/testng/utilities/ModuleFactory.java (1)
  • aquality-selenium-template/src/main/java/aquality/selenium/template/modules/CustomBrowserModule.java (1)
  • aquality-selenium-template/src/main/java/aquality/selenium/template/modules/ServiceModule.java (1)
  • aquality-selenium-template/src/main/java/aquality/selenium/template/utilities/AllureBasedLocalizedLogger.java (3)
  • aquality-selenium-template/src/main/java/aquality/selenium/template/utilities/CustomActionRetrier.java (1)
  • pom.xml (1)
Files ignored due to filter (1)
  • aquality-selenium-template-testng/src/test/resources/data/contacts.json
Files skipped from review due to trivial changes (2)
  • aquality-selenium-template-cucumber/src/test/java/aquality/selenium/template/cucumber/hooks/AqualityServicesHooks.java
  • pom.xml
Review comments generated (35)
  • Review: 21
  • LGTM: 14

Tips

Chat with Image description CodeRabbit Bot (@coderabbitai)

  • Reply on review comments left by this bot to ask follow-up questions. A review comment is a comment on a diff or a file.
  • Invite the bot into a review comment chain by tagging @coderabbitai in a reply.

Code suggestions

  • The bot may make code suggestions, but please review them carefully before committing since the line number ranges may be misaligned.
  • You can edit the comment made by the bot and manually tweak the suggestion if it is slightly off.

Pausing incremental reviews

  • Add @coderabbitai: ignore anywhere in the PR description to pause further reviews from the bot.

@@ -14,7 +15,7 @@ public class CustomObjectFactory implements ObjectFactory {

public CustomObjectFactory() {
this.injector = Guice.createInjector(Stage.PRODUCTION, CucumberModules.createScenarioModule(),
new ServiceModule(), new CustomBrowserModule(AqualityServices::getBrowser));
new ServiceModule(), new CustomBrowserModule());
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The change in the CustomObjectFactory constructor removes the reference to AqualityServices::getBrowser when creating a new CustomBrowserModule. This could potentially alter the behavior of how the browser is managed within the tests. Ensure that the CustomBrowserModule is correctly implemented without the need for this reference, and that it does not introduce any regressions or unexpected behaviors.

-                new ServiceModule(), new CustomBrowserModule(AqualityServices::getBrowser));
+                new ServiceModule(), new CustomBrowserModule());

Comment on lines +18 to +22
@Step("Main page is opened")
public void checkMainPageIsOpened() {
assertThat(mainPage.state().waitForDisplayed())
.describedAs(mainPage.getName() + " must be opened")
.isTrue();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The method checkMainPageIsOpened uses an assertion to check if the main page is displayed. However, it does not handle the case where the assertion fails and the test continues running, potentially leading to misleading test results. It would be better to throw an exception if the condition is not met, ensuring that the test stops execution at this point.

- assertThat(mainPage.state().waitForDisplayed())
-         .describedAs(mainPage.getName() + " must be opened")
-         .isTrue();
+ boolean isDisplayed = mainPage.state().waitForDisplayed();
+ if (!isDisplayed) {
+     throw new AssertionError(mainPage.getName() + " must be opened");
+ }

Comment on lines +1 to +59
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium-template-project</artifactId>
<version>1.0.1-SNAPSHOT</version>
</parent>

<artifactId>aquality-selenium-template-testng</artifactId>

<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<dependencies>
<dependency>
<groupId>com.github.aquality-automation</groupId>
<artifactId>aquality-selenium-template</artifactId>
<version>1.0.1-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.qameta.allure</groupId>
<artifactId>allure-testng</artifactId>
<version>${allure.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.25.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.10</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The Maven POM file for the aquality-selenium-template-testng project is well-structured and includes necessary dependencies for a TestNG-based Selenium project. However, there are a couple of points that need attention:

  • The ${allure.version} property is used in line 43 but it's not defined within the <properties> section. This could lead to a build failure if the property is not defined elsewhere.
  • There is no newline at the end of the file (line 59). While this is not a functional issue, it is a common practice to include a newline at the end of files to comply with POSIX standards.
    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <allure.version>2.13.9</allure.version> <!-- Example version, should be replaced with the actual version intended to use -->

    </properties>
...
    </dependencies>
</project>
+ <!-- Newline added at the end of the file -->

Comment on lines +10 to +11
import aquality.selenium.template.utilities.IScreenshotProvider;
import com.google.inject.Inject;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The use of IScreenshotProvider and dependency injection with @Inject is good for maintainability and modularity, but ensure that the implementation of IScreenshotProvider is thread-safe if tests are to be run in parallel.

Comment on lines +24 to +25
@Guice(moduleFactory = ModuleFactory.class)
public class BaseTest {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

Using the @Guice annotation with a custom module factory is a good practice for dependency injection. It allows for better test configuration and easier maintenance.

Comment on lines +13 to +27
@Test(description = "Empty email validation is working on Contact Us page",
dataProvider = "getContacts", dataProviderClass = JsonDataProvider.class)
public void testEmailValidation(ContactUsInfo contactInfo) {
landingSteps.checkMainPageIsOpened();
landingSteps.openContactUsPage();
contactUsSteps.checkContactUsPageIsOpened();

contactUsSteps.saveContactUsPageDump();
contactUsSteps.fillContactUsPage(contactInfo);
contactUsSteps.acceptPrivacyAndCookiesPolicy();
contactUsSteps.clickSendButton();

contactUsSteps.checkEmptyFieldWarning();
contactUsSteps.contactUsPageDumpIsDifferent();
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The test method testEmailValidation seems to be testing multiple behaviors: navigation, form submission, and validation messages. Consider breaking this down into smaller tests that each verify a single behavior for better maintainability and clarity. Additionally, the method name suggests it only tests email validation, but the steps indicate broader functionality is being tested.

-    @Test(description = "Empty email validation is working on Contact Us page",
+    @Test(description = "Navigate to Contact Us page")
     public void navigateToContactUsPage() {
         landingSteps.checkMainPageIsOpened();
         landingSteps.openContactUsPage();
         contactUsSteps.checkContactUsPageIsOpened();
     }

+    @Test(description = "Check empty email field warning on Contact Us page",
+          dependsOnMethods = {"navigateToContactUsPage"})
     public void checkEmptyEmailFieldWarning(ContactUsInfo contactInfo) {
         contactUsSteps.saveContactUsPageDump();
         contactUsSteps.fillContactUsPage(contactInfo);
         contactUsSteps.acceptPrivacyAndCookiesPolicy();
         contactUsSteps.clickSendButton();

         contactUsSteps.checkEmptyFieldWarning();
         contactUsSteps.contactUsPageDumpIsDifferent();
     }

Comment on lines +20 to +26
contactUsSteps.saveContactUsPageDump();
contactUsSteps.fillContactUsPage(contactInfo);
contactUsSteps.acceptPrivacyAndCookiesPolicy();
contactUsSteps.clickSendButton();

contactUsSteps.checkEmptyFieldWarning();
contactUsSteps.contactUsPageDumpIsDifferent();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The method saveContactUsPageDump and contactUsPageDumpIsDifferent suggest that there is some kind of comparison being made between the state of the page before and after an action. This could potentially be flaky if the page content is dynamic or if there are timing issues. Ensure that these methods are reliable and consider using more deterministic checks where possible.

-        contactUsSteps.saveContactUsPageDump();
-        contactUsSteps.fillContactUsPage(contactInfo);
-        contactUsSteps.acceptPrivacyAndCookiesPolicy();
-        contactUsSteps.clickSendButton();
-
-        contactUsSteps.checkEmptyFieldWarning();
-        contactUsSteps.contactUsPageDumpIsDifferent();
+        // Ensure that the page dump comparison logic is robust against dynamic content and timing issues.
+        // Consider using explicit waits or assertions that target specific elements or states.

Comment on lines +14 to +35
@UtilityClass
public class JsonDataProvider {
private static final ObjectMapper MAPPER = new ObjectMapper();

@DataProvider
@SneakyThrows
public Object[][] getContacts() {
return getDataListFromJson("contacts", ContactUsInfo[].class);
}

private Object[][] getDataListFromJson(String filename, Class<? extends Object[]> valueType) {
Object[] dataList;
try {
File file = Paths.get(String.format("src/test/resources/data/%s.json", filename)).toFile();
dataList = MAPPER.readValue(file, valueType);
}
catch (IOException exception) {
AqualityServices.getLogger().debug("IO error occurred while reading the data from the file " + filename, exception);
throw new RuntimeException(exception);
}
return new Object[][] {dataList};
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The JsonDataProvider class is using a UtilityClass annotation from Lombok, which is intended for classes that only have static methods and fields. However, the use of this annotation along with TestNG's @DataProvider annotation could be misleading because data providers are typically not static in nature as they are meant to be invoked by the testing framework. Additionally, there is an exception handling issue where a generic RuntimeException is thrown after catching an IOException. It would be better to throw a more specific custom exception that provides context about the failure related to test data provisioning.

- @UtilityClass
- public class JsonDataProvider {
+ public final class JsonDataProvider {
+     private JsonDataProvider() {
+         // Private constructor to prevent instantiation
+     }

-             throw new RuntimeException(exception);
+             throw new TestDataReadException("IO error occurred while reading the data from the file " + filename, exception);
+ }
+
+ public static class TestDataReadException extends RuntimeException {
+     public TestDataReadException(String message, Throwable cause) {
+         super(message, cause);
+     }
+ }

Comment on lines +18 to +22
@DataProvider
@SneakyThrows
public Object[][] getContacts() {
return getDataListFromJson("contacts", ContactUsInfo[].class);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

Using @SneakyThrows to bypass checked exceptions can lead to unexpected runtime failures without proper handling. It's generally better to handle checked exceptions explicitly or declare them in the method signature so that users of the method are aware of potential exceptions.

- @SneakyThrows
- public Object[][] getContacts() {
+ public Object[][] getContacts() throws IOException {
      return getDataListFromJson("contacts", ContactUsInfo[].class);
  }

Comment on lines +24 to +34
private Object[][] getDataListFromJson(String filename, Class<? extends Object[]> valueType) {
Object[] dataList;
try {
File file = Paths.get(String.format("src/test/resources/data/%s.json", filename)).toFile();
dataList = MAPPER.readValue(file, valueType);
}
catch (IOException exception) {
AqualityServices.getLogger().debug("IO error occurred while reading the data from the file " + filename, exception);
throw new RuntimeException(exception);
}
return new Object[][] {dataList};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image description CodeRabbit

The method getDataListFromJson reads a JSON file and converts it into an array of objects. The current implementation assumes that the JSON file will always be correctly formatted and located in the expected directory. It would be beneficial to add checks to ensure that the file exists before attempting to read it, and to provide a clear error message if the file is not found.

+             if (!file.exists()) {
+                 throw new TestDataReadException("Test data file not found: " + file.getAbsolutePath());
+             }
              dataList = MAPPER.readValue(file, valueType);

Additionally, wrapping the entire array within another array (new Object[][] {dataList}) may not be necessary depending on how the data provider is used in the tests. If each element of dataList is supposed to be passed as a separate set of parameters to a test method, then you should iterate over dataList and create a two-dimensional array where each sub-array contains one element from dataList.

-         return new Object[][] {dataList};
+         Object[][] dataProvider = new Object[dataList.length][];
+         for (int i = 0; i < dataList.length; i++) {
+             dataProvider[i] = new Object[] {dataList[i]};
+         }
+         return dataProvider;

Copy link

sonarcloud bot commented Apr 5, 2024

Quality Gate Passed Quality Gate passed

Issues
1 New issue
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
0.0% Duplication on New Code

See analysis details on SonarCloud

@mialeska mialeska changed the title TestNG template project TestNG template project - reviewed by free CodeRabbit with GPT-4-turbo model Apr 5, 2024
@mialeska mialeska closed this Apr 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant