Skip to content

test: improve ui test coverage#2163

Merged
jo-elimu merged 4 commits intomainfrom
2037-improve-ui-test-coverage
Apr 25, 2025
Merged

test: improve ui test coverage#2163
jo-elimu merged 4 commits intomainfrom
2037-improve-ui-test-coverage

Conversation

@jo-elimu
Copy link
Copy Markdown
Member

Issue Number

Purpose

Technical Details

Testing Instructions

Screenshots


Format Checks

Note

Files in PRs are automatically checked for format violations with mvn spotless:check.

If this PR contains files with format violations, run mvn spotless:apply to fix them.

@jo-elimu jo-elimu self-assigned this Apr 25, 2025
@jo-elimu jo-elimu requested a review from a team as a code owner April 25, 2025 05:51
@jo-elimu jo-elimu requested review from AshishBagdane, alexander-kuruvilla and eymaal and removed request for a team April 25, 2025 05:51
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 25, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 15.33%. Comparing base (bc26ed4) to head (267d40b).
Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #2163   +/-   ##
=========================================
  Coverage     15.33%   15.33%           
  Complexity      391      391           
=========================================
  Files           233      233           
  Lines          6148     6148           
  Branches        710      710           
=========================================
  Hits            943      943           
  Misses         5154     5154           
  Partials         51       51           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 25, 2025

Walkthrough

This update extends Selenium-based UI test coverage to storybook-related pages under /content/storybook alongside existing image-related page tests. It adds unique id and class attributes to anchor elements in JSP files for reliable element selection in tests, including IDs for "create" buttons and editLink classes for edit links. New page object classes (StoryBookListPage, StoryBookEditPage, StoryBookCreatePage) and a new test class (StoryBookTest) are implemented to automate navigation and interaction with storybook list, edit, and create pages. Corresponding helper methods were added to the MainContentPage class. The project version is incremented in the dependency tree.

Changes

File(s) Change Summary
pom-dependency-tree.txt Updated main artifact version from 2.5.102-SNAPSHOT to 2.5.103-SNAPSHOT.
src/main/webapp/WEB-INF/jsp/content/main.jsp Added id="imageListLink" and id="storyBookListLink" to anchor elements linking to image and storybook lists.
src/main/webapp/WEB-INF/jsp/content/multimedia/image/list.jsp Added id="createButton" to the "Add image" button anchor.
src/main/webapp/WEB-INF/jsp/content/storybook/list.jsp Added class="editLink" to all storybook edit links and id="createButton" to the "Add storybook" button.
src/test/java/selenium/content/MainContentPage.java Added pressImageListLink() and pressStoryBookListLink() methods to click respective links by ID.
src/test/java/selenium/content/image/ImageListPage.java New page object class for the image list page; methods for selecting/editing images and clicking create button.
src/test/java/selenium/content/image/ImageEditPage.java New page object class for the image edit page; verifies presence of page by ID.
src/test/java/selenium/content/image/ImageCreatePage.java New page object class for the image create page; verifies presence of page by ID.
src/test/java/selenium/content/image/ImageTest.java New test class with setup/teardown and two UI tests for navigating to image edit and create pages.
src/test/java/selenium/content/storybook/StoryBookListPage.java New page object class for the storybook list page; methods for selecting/editing storybooks and clicking create button.
src/test/java/selenium/content/storybook/StoryBookEditPage.java New page object class for the storybook edit page; verifies presence of page by ID.
src/test/java/selenium/content/storybook/StoryBookCreatePage.java New page object class for the storybook create page; verifies presence of page by ID.
src/test/java/selenium/content/storybook/StoryBookTest.java New test class with setup/teardown and two UI tests for navigating to storybook edit and create pages.

Sequence Diagram(s)

sequenceDiagram
    participant TestRunner
    participant MainContentPage
    participant ImageListPage
    participant ImageEditPage
    participant ImageCreatePage
    participant StoryBookListPage
    participant StoryBookEditPage
    participant StoryBookCreatePage

    TestRunner->>MainContentPage: pressImageListLink()
    MainContentPage->>ImageListPage: (constructor)
    alt Image Edit Page Test
        ImageListPage->>ImageListPage: pressRandomImage()
        ImageListPage->>ImageEditPage: (constructor)
    else Image Create Page Test
        ImageListPage->>ImageListPage: pressCreateButton()
        ImageListPage->>ImageCreatePage: (constructor)
    end

    TestRunner->>MainContentPage: pressStoryBookListLink()
    MainContentPage->>StoryBookListPage: (constructor)
    alt StoryBook Edit Page Test
        StoryBookListPage->>StoryBookListPage: pressRandomStoryBook()
        StoryBookListPage->>StoryBookEditPage: (constructor)
    else StoryBook Create Page Test
        StoryBookListPage->>StoryBookListPage: pressCreateButton()
        StoryBookListPage->>StoryBookCreatePage: (constructor)
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Add UI tests for /content/multimedia/image pages (Image list, edit, create) [#2037]
Add UI tests for /content/storybook pages (Storybook list, edit, create) [#2037]

Suggested reviewers

  • nya-elimu
  • AshishBagdane
  • vuriaval
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (8)
src/test/java/selenium/content/image/ImageEditPage.java (2)

6-15: Add JavaDoc documentation to improve code maintainability.

While the implementation follows the Page Object Model pattern correctly, adding class-level and method-level JavaDoc comments would improve maintainability and help other developers understand the purpose of this class.

+/**
+ * Page Object representing the Image Edit page.
+ * This class provides methods to interact with UI elements on the image edit page.
+ */
 public class ImageEditPage {
     
     private WebDriver driver;
 
+    /**
+     * Constructor that initializes the page object and verifies that the browser
+     * is on the correct page by checking for the presence of the imageEditPage element.
+     * 
+     * @param driver The WebDriver instance to use for browser interaction
+     */
     public ImageEditPage(WebDriver driver) {
         this.driver = driver;
 
         driver.findElement(By.id("imageEditPage"));
     }
 }

6-15: Consider adding methods for page interactions.

The page object currently only verifies navigation but doesn't provide methods to interact with form elements on the edit page. To improve test coverage, consider adding methods for common interactions like form submission, field editing, etc.

 public class ImageEditPage {
     
     private WebDriver driver;
 
     public ImageEditPage(WebDriver driver) {
         this.driver = driver;
 
         driver.findElement(By.id("imageEditPage"));
     }
+    
+    /**
+     * Submits the image edit form
+     */
+    public void submitForm() {
+        WebElement submitButton = driver.findElement(By.id("submitButton"));
+        submitButton.click();
+    }
+
+    /**
+     * Sets a value in a specific form field
+     * 
+     * @param fieldId The ID of the field to set
+     * @param value The value to set in the field
+     */
+    public void setFieldValue(String fieldId, String value) {
+        WebElement field = driver.findElement(By.id(fieldId));
+        field.clear();
+        field.sendKeys(value);
+    }
 }
src/test/java/selenium/content/image/ImageCreatePage.java (2)

6-15: Add JavaDoc documentation for better clarity.

Similar to ImageEditPage, adding JavaDoc comments would improve maintainability and documentation.

+/**
+ * Page Object representing the Image Create page.
+ * This class provides methods to interact with UI elements on the image creation page.
+ */
 public class ImageCreatePage {
     
     private WebDriver driver;
 
+    /**
+     * Constructor that initializes the page object and verifies that the browser
+     * is on the correct page by checking for the presence of the imageCreatePage element.
+     * 
+     * @param driver The WebDriver instance to use for browser interaction
+     */
     public ImageCreatePage(WebDriver driver) {
         this.driver = driver;
 
         driver.findElement(By.id("imageCreatePage"));
     }
 }

6-15: Consider adding form interaction methods and exploring a base class pattern.

The page object is currently minimal. Consider adding methods for form interactions similar to what was suggested for ImageEditPage. Since ImageEditPage and ImageCreatePage share a similar structure, you might also consider extracting common functionality to a base class.

 public class ImageCreatePage {
     
     private WebDriver driver;
 
     public ImageCreatePage(WebDriver driver) {
         this.driver = driver;
 
         driver.findElement(By.id("imageCreatePage"));
     }
+    
+    /**
+     * Fills the form with test data and submits it
+     */
+    public void fillAndSubmitForm() {
+        // Find form fields and populate them with test data
+        WebElement titleField = driver.findElement(By.id("title"));
+        titleField.clear();
+        titleField.sendKeys("Test Image " + System.currentTimeMillis());
+        
+        // Submit the form
+        WebElement submitButton = driver.findElement(By.id("submitButton"));
+        submitButton.click();
+    }
 }
src/test/java/selenium/content/image/ImageTest.java (1)

19-36: Extract configuration to improve maintainability.

The URL and WebDriver configuration could be extracted to make the tests more maintainable. Consider using a property file or constants class to store the base URL and browser configuration.

 @BeforeEach
 public void setUp() { 
     log.info("setUp");

     ChromeOptions chromeOptions = new ChromeOptions();

     // Read "headless" property set on the command line: 
     //    mvn clean verify -P regression-test-ui -D headless=true
     String headlessSystemProperty = System.getProperty("headless");
     log.info("headlessSystemProperty: \"" + headlessSystemProperty + "\"");
     if ("true".equals(headlessSystemProperty)) {
         chromeOptions.addArguments("headless");
     }
     
     driver = new ChromeDriver(chromeOptions);

-    driver.get(DomainHelper.getBaseUrl() + "/content");
+    // Navigate to the content page
+    String baseUrl = DomainHelper.getBaseUrl();
+    String contentUrl = baseUrl + "/content";
+    log.info("Navigating to content URL: {}", contentUrl);
+    driver.get(contentUrl);
+    
+    // Set an implicit wait to handle potential timing issues
+    driver.manage().timeouts().implicitlyWait(10, java.util.concurrent.TimeUnit.SECONDS);
 }
src/test/java/selenium/content/image/ImageListPage.java (3)

9-17: Add JavaDoc comments for better documentation.

Adding class and method-level JavaDoc comments would improve maintainability and help other developers understand the purpose of this class.

+/**
+ * Page Object representing the Image List page.
+ * This class provides methods to interact with UI elements on the image list page,
+ * such as clicking on random images or the create button.
+ */
 public class ImageListPage {
     
     private WebDriver driver;
 
+    /**
+     * Constructor that initializes the page object and verifies that the browser
+     * is on the correct page by checking for the presence of the imageListPage element.
+     * 
+     * @param driver The WebDriver instance to use for browser interaction
+     */
     public ImageListPage(WebDriver driver) {
         this.driver = driver;
 
         driver.findElement(By.id("imageListPage"));
     }

26-29: Add documentation for the pressCreateButton method.

Add JavaDoc comment for the pressCreateButton() method to improve code documentation.

+/**
+ * Clicks on the create button to navigate to the image creation page.
+ */
 public void pressCreateButton() {
     WebElement button = driver.findElement(By.id("createButton"));
     button.click();
 }

9-30: Consider adding methods for additional page interactions.

The current implementation covers basic navigation but could be extended with methods to interact with other elements that might exist on the list page, such as pagination, filtering, or searching.

 public class ImageListPage {
     
     private WebDriver driver;

     public ImageListPage(WebDriver driver) {
         this.driver = driver;

         driver.findElement(By.id("imageListPage"));
     }

     public void pressRandomImage() {
         List<WebElement> links = driver.findElements(By.className("editLink"));
         int randomIndex = (int) (Math.random() * links.size());
         WebElement randomLink = links.get(randomIndex);
         randomLink.click();
     }

     public void pressCreateButton() {
         WebElement button = driver.findElement(By.id("createButton"));
         button.click();
     }
+    
+    /**
+     * Returns the number of images in the list.
+     * 
+     * @return the number of images displayed on the current page
+     */
+    public int getNumberOfImages() {
+        List<WebElement> images = driver.findElements(By.className("editLink"));
+        return images.size();
+    }
+    
+    /**
+     * Performs a search using the search input field.
+     * 
+     * @param searchTerm the term to search for
+     * @return this ImageListPage to allow method chaining
+     */
+    public ImageListPage search(String searchTerm) {
+        WebElement searchInput = driver.findElement(By.id("searchInput"));
+        searchInput.clear();
+        searchInput.sendKeys(searchTerm);
+        
+        WebElement searchButton = driver.findElement(By.id("searchButton"));
+        searchButton.click();
+        
+        // Wait for the page to reload
+        driver.findElement(By.id("imageListPage"));
+        
+        return this;
+    }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7e49f0b and 853ddc3.

📒 Files selected for processing (8)
  • pom-dependency-tree.txt (1 hunks)
  • src/main/webapp/WEB-INF/jsp/content/main.jsp (1 hunks)
  • src/main/webapp/WEB-INF/jsp/content/multimedia/image/list.jsp (1 hunks)
  • src/test/java/selenium/content/MainContentPage.java (1 hunks)
  • src/test/java/selenium/content/image/ImageCreatePage.java (1 hunks)
  • src/test/java/selenium/content/image/ImageEditPage.java (1 hunks)
  • src/test/java/selenium/content/image/ImageListPage.java (1 hunks)
  • src/test/java/selenium/content/image/ImageTest.java (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/test/java/selenium/content/image/ImageTest.java (1)
src/test/java/selenium/content/MainContentPage.java (1)
  • MainContentPage (7-51)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test_ui_localhost
  • GitHub Check: test_ui
  • GitHub Check: test_ui
  • GitHub Check: test_ui
  • GitHub Check: test_ui
🔇 Additional comments (4)
src/main/webapp/WEB-INF/jsp/content/main.jsp (1)

98-98: LGTM! Added ID attribute for Selenium test support.

The addition of id="imageListLink" to the image list anchor element follows the same pattern used for other navigation links in this file, providing a stable selector for UI testing.

src/main/webapp/WEB-INF/jsp/content/multimedia/image/list.jsp (1)

72-72: LGTM! Added ID attribute for Selenium test support.

The addition of id="createButton" to the image creation anchor element provides a reliable selector for UI tests, following good practices for testable UI components.

pom-dependency-tree.txt (1)

1-1: LGTM! Version increment.

The project version has been incremented from 2.5.102-SNAPSHOT to 2.5.103-SNAPSHOT, which is appropriate for the UI test coverage improvements being made.

src/test/java/selenium/content/MainContentPage.java (1)

47-50: LGTM! New method for image list navigation.

The new pressImageListLink() method follows the established pattern of other navigation methods in this class, providing a clean abstraction for clicking the image list link in UI tests.

Comment thread src/test/java/selenium/content/image/ImageTest.java
Comment thread src/test/java/selenium/content/image/ImageTest.java
Comment on lines +19 to +24
public void pressRandomImage() {
List<WebElement> links = driver.findElements(By.className("editLink"));
int randomIndex = (int) (Math.random() * links.size());
WebElement randomLink = links.get(randomIndex);
randomLink.click();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add error handling for empty lists.

The pressRandomImage() method assumes that there's at least one edit link on the page. Add error handling for the case when no edit links are found to prevent test failures in unexpected ways.

+/**
+ * Clicks on a random image's edit link.
+ * 
+ * @throws IllegalStateException if no edit links are found on the page
+ */
 public void pressRandomImage() {
     List<WebElement> links = driver.findElements(By.className("editLink"));
+    if (links.isEmpty()) {
+        throw new IllegalStateException("No edit links found on the page. The page might be empty or the selector might be incorrect.");
+    }
     int randomIndex = (int) (Math.random() * links.size());
     WebElement randomLink = links.get(randomIndex);
     randomLink.click();
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
public void pressRandomImage() {
List<WebElement> links = driver.findElements(By.className("editLink"));
int randomIndex = (int) (Math.random() * links.size());
WebElement randomLink = links.get(randomIndex);
randomLink.click();
}
/**
* Clicks on a random image's edit link.
*
* @throws IllegalStateException if no edit links are found on the page
*/
public void pressRandomImage() {
List<WebElement> links = driver.findElements(By.className("editLink"));
if (links.isEmpty()) {
throw new IllegalStateException("No edit links found on the page. The page might be empty or the selector might be incorrect.");
}
int randomIndex = (int) (Math.random() * links.size());
WebElement randomLink = links.get(randomIndex);
randomLink.click();
}

@jo-elimu jo-elimu merged commit 62ac11b into main Apr 25, 2025
12 of 17 checks passed
@jo-elimu jo-elimu deleted the 2037-improve-ui-test-coverage branch April 25, 2025 06:27
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
src/test/java/selenium/content/storybook/StoryBookTest.java (4)

19-36: Well-structured setup with configurable headless mode

The setup method properly initializes the WebDriver with flexible headless mode configuration through system properties. This allows tests to run in both UI and headless modes, which is useful for different testing scenarios.

Consider adding a try-catch block to handle potential WebDriver initialization failures.

@BeforeEach
public void setUp() { 
    log.info("setUp");

    ChromeOptions chromeOptions = new ChromeOptions();

    // Read "headless" property set on the command line: 
    //    mvn clean verify -P regression-test-ui -D headless=true
    String headlessSystemProperty = System.getProperty("headless");
    log.info("headlessSystemProperty: \"" + headlessSystemProperty + "\"");
    if ("true".equals(headlessSystemProperty)) {
        chromeOptions.addArguments("headless");
    }
    
+   try {
        driver = new ChromeDriver(chromeOptions);
        driver.get(DomainHelper.getBaseUrl() + "/content");
+   } catch (Exception e) {
+       log.error("Failed to initialize WebDriver: " + e.getMessage(), e);
+       throw e;
+   }
}

38-43: Good resource cleanup in tearDown method

The tearDown method properly quits the WebDriver, which is essential to release resources and prevent memory leaks. Consider adding a null check and try-catch to make the teardown more robust.

@AfterEach
public void tearDown() {
    log.info("tearDown");

+   if (driver != null) {
+       try {
            driver.quit();
+       } catch (Exception e) {
+           log.warn("Error while quitting WebDriver: " + e.getMessage());
+       }
+   }
}

45-57: Good use of Page Object Pattern but lacks explicit assertions

The test follows the Page Object Pattern, which is a best practice for UI testing. However, it relies on implicit assertions (the constructor of the page object classes throws an exception if elements aren't found) rather than explicit assertions.

Consider adding explicit assertions to make the test intent clearer.

@Test
public void testRandomStoryBookEditPage() {
    log.info("testRandomStoryBookEditPage");
    
    MainContentPage mainContentPage = new MainContentPage(driver);
    mainContentPage.pressStoryBookListLink();

    StoryBookListPage storyBookListPage = new StoryBookListPage(driver);
    storyBookListPage.pressRandomStoryBook();
    log.info("driver.getCurrentUrl(): " + driver.getCurrentUrl());

    StoryBookEditPage storyBookEditPage = new StoryBookEditPage(driver);
+   
+   // Add explicit assertion to verify we're on the edit page
+   String currentUrl = driver.getCurrentUrl();
+   assertTrue(currentUrl.contains("/edit"), "URL should contain '/edit' path segment");
+   assertTrue(storyBookEditPage.isPageLoaded(), "Edit page should be fully loaded");
}

59-70: Similar feedback for CreatePage test

Similar to the previous test, this one follows good practices but lacks explicit assertions. Consider adding assertions to verify we're on the create page.

@Test
public void testStoryBookCreatePage() {
    log.info("testStoryBookCreatePage");

    MainContentPage mainContentPage = new MainContentPage(driver);
    mainContentPage.pressStoryBookListLink();

    StoryBookListPage storyBookListPage = new StoryBookListPage(driver);
    storyBookListPage.pressCreateButton();

    StoryBookCreatePage storyBookCreatePage = new StoryBookCreatePage(driver);
+   
+   // Add explicit assertion to verify we're on the create page
+   String currentUrl = driver.getCurrentUrl();
+   assertTrue(currentUrl.contains("/create"), "URL should contain '/create' path segment");
+   assertTrue(storyBookCreatePage.isPageLoaded(), "Create page should be fully loaded");
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 853ddc3 and 267d40b.

⛔ Files ignored due to path filters (5)
  • .github/workflows/maven-regression-tests-ENG.yml is excluded by !**/*.yml
  • .github/workflows/maven-regression-tests-HIN.yml is excluded by !**/*.yml
  • .github/workflows/maven-regression-tests-TGL.yml is excluded by !**/*.yml
  • .github/workflows/maven-regression-tests-THA.yml is excluded by !**/*.yml
  • .github/workflows/maven-regression-tests.yml is excluded by !**/*.yml
📒 Files selected for processing (7)
  • src/main/webapp/WEB-INF/jsp/content/main.jsp (2 hunks)
  • src/main/webapp/WEB-INF/jsp/content/storybook/list.jsp (6 hunks)
  • src/test/java/selenium/content/MainContentPage.java (1 hunks)
  • src/test/java/selenium/content/storybook/StoryBookCreatePage.java (1 hunks)
  • src/test/java/selenium/content/storybook/StoryBookEditPage.java (1 hunks)
  • src/test/java/selenium/content/storybook/StoryBookListPage.java (1 hunks)
  • src/test/java/selenium/content/storybook/StoryBookTest.java (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/main/webapp/WEB-INF/jsp/content/main.jsp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/java/selenium/content/MainContentPage.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/test/java/selenium/content/storybook/StoryBookTest.java (1)
src/test/java/selenium/content/MainContentPage.java (1)
  • MainContentPage (7-56)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: test_ui
  • GitHub Check: test_ui
  • GitHub Check: test_ui
  • GitHub Check: build (ubuntu-latest, 17)
  • GitHub Check: build (windows-latest, 21)
  • GitHub Check: build (windows-latest, 17)
  • GitHub Check: build (ubuntu-latest, 21)
  • GitHub Check: test_rest
  • GitHub Check: test_rest
🔇 Additional comments (9)
src/main/webapp/WEB-INF/jsp/content/storybook/list.jsp (2)

39-39: Good addition of consistent class attributes for test automation.

Adding the class="editLink" attribute to anchor tags across all storybook levels provides consistent selectors for Selenium tests. This matches the pattern used in other list pages and enables reliable element selection.

Also applies to: 87-87, 135-135, 183-183, 229-229


264-264: Well-implemented ID for the create button.

Adding id="createButton" to the floating action button follows the same pattern used in other content pages, enabling consistent test automation approaches across different content types.

src/test/java/selenium/content/storybook/StoryBookEditPage.java (1)

1-15: Page object implementation follows good practices.

The StoryBookEditPage class correctly implements the page object pattern for Selenium testing by:

  • Receiving the WebDriver instance via constructor
  • Verifying page load by checking for the presence of a specific page identifier
  • Encapsulating the page's functionality

Consider extending this class with methods to interact with specific elements on the edit page in future improvements.

src/test/java/selenium/content/storybook/StoryBookCreatePage.java (1)

1-15: Page object follows consistent pattern.

The StoryBookCreatePage implementation maintains consistency with other page objects and follows good practices:

  • Proper constructor initialization
  • Page verification via element presence
  • Clean separation of concerns

As the test coverage expands, consider adding methods to interact with form fields and submission controls.

src/test/java/selenium/content/storybook/StoryBookListPage.java (3)

1-17: Page object properly initializes and verifies page load.

The implementation correctly:

  • Encapsulates the WebDriver instance
  • Verifies page load by checking for a specific element ID
  • Follows standard page object pattern practices

19-24: Random selection method enhances test robustness.

The pressRandomStoryBook() method effectively:

  • Finds all edit links using the newly added CSS class
  • Randomly selects one to click
  • Avoids hard-coding specific elements, making tests more resilient to content changes

This approach allows tests to work regardless of how many storybooks are present in the system.


26-29: Create button interaction is properly implemented.

The pressCreateButton() method correctly:

  • Finds the element using the ID added to the JSP file
  • Performs the click operation

This implementation maintains consistency with interaction patterns in other content type page objects.

src/test/java/selenium/content/storybook/StoryBookTest.java (2)

1-13: Good package organization and imports

The package structure and imports are appropriate for UI testing with Selenium. Organizing the tests in a selenium.content.storybook package maintains consistency with other UI test classes in the project.


14-18: Lombok's @slf4j usage is appropriate

Using Lombok's @Slf4j annotation to create a logger field reduces boilerplate code, which is good practice. The WebDriver is properly declared as a class field to be used across test methods.

Comment on lines +1 to +71
package selenium.content.storybook;

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 lombok.extern.slf4j.Slf4j;
import selenium.content.MainContentPage;
import selenium.util.DomainHelper;

@Slf4j
public class StoryBookTest {

private WebDriver driver;

@BeforeEach
public void setUp() {
log.info("setUp");

ChromeOptions chromeOptions = new ChromeOptions();

// Read "headless" property set on the command line:
// mvn clean verify -P regression-test-ui -D headless=true
String headlessSystemProperty = System.getProperty("headless");
log.info("headlessSystemProperty: \"" + headlessSystemProperty + "\"");
if ("true".equals(headlessSystemProperty)) {
chromeOptions.addArguments("headless");
}

driver = new ChromeDriver(chromeOptions);

driver.get(DomainHelper.getBaseUrl() + "/content");
}

@AfterEach
public void tearDown() {
log.info("tearDown");

driver.quit();
}

@Test
public void testRandomStoryBookEditPage() {
log.info("testRandomStoryBookEditPage");

MainContentPage mainContentPage = new MainContentPage(driver);
mainContentPage.pressStoryBookListLink();

StoryBookListPage storyBookListPage = new StoryBookListPage(driver);
storyBookListPage.pressRandomStoryBook();
log.info("driver.getCurrentUrl(): " + driver.getCurrentUrl());

StoryBookEditPage storyBookEditPage = new StoryBookEditPage(driver);
}

@Test
public void testStoryBookCreatePage() {
log.info("testStoryBookCreatePage");

MainContentPage mainContentPage = new MainContentPage(driver);
mainContentPage.pressStoryBookListLink();

StoryBookListPage storyBookListPage = new StoryBookListPage(driver);
storyBookListPage.pressCreateButton();

StoryBookCreatePage storyBookCreatePage = new StoryBookCreatePage(driver);
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Consider adding timeout handling and more comprehensive tests

The current tests cover basic navigation, which is a good starting point. Consider enhancing these tests in the future with:

  1. Explicit waits for elements to be visible/clickable to handle timing issues
  2. Testing form submission and validation
  3. Verifying data persistence after create/edit operations

Also, you might want to add tests for error conditions and edge cases.


🏁 Script executed:

#!/bin/bash
# Checking for WebDriverWait or other wait mechanism usage in existing tests

echo "Searching for WebDriverWait usage in existing Selenium tests:"
rg -A 2 "WebDriverWait" --type java src/test/java/selenium/

echo "Searching for ExpectedConditions usage in existing Selenium tests:"
rg -A 2 "ExpectedConditions" --type java src/test/java/selenium/

echo "Checking StoryBook page object classes for validation methods:"
fd "StoryBook.*Page\.java" src/test/java/

Length of output: 839


Enhance Selenium tests with explicit waits and expanded coverage

After verification, there is currently no use of WebDriverWait or ExpectedConditions in your Selenium tests, and the StoryBook page objects don’t expose any built-in validation or wait helpers. To improve test stability and coverage, please:

  • Introduce explicit waits before interacting with or asserting element state
    – Use WebDriverWait + ExpectedConditions in StoryBookTest.java
    – Consider helper methods in each page object (e.g. waitForVisible(), waitForClickable()) in
    • StoryBookListPage.java
    • StoryBookCreatePage.java
    • StoryBookEditPage.java
  • Expand tests to cover form submission and validation
    – Fill in fields on the create/edit pages, submit, and assert success or validation error messages
  • Verify data persistence after create/edit
    – After creating or editing, navigate back or reload and assert that the entered data is present
  • Add tests for error conditions and edge cases
    – Invalid inputs, required-field omissions, navigation failures, etc.

These additions will make your UI tests more robust and catch regressions earlier.

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.

Improve UI test coverage

1 participant