Skip to content

steadhac/healenium-selenium-demo

Repository files navigation

Healenium Self-Healing Selenium Framework

License: MIT Java Selenium Healenium TestNG

Self-healing test automation framework with Healenium integration. Demonstrates AI-powered locator healing to reduce test maintenance.


Complete Guide: From Manual Testing to Automation Mastery

🗺️ Architecture Diagram

flowchart TD
    A[TestRunner] -->|Runs| B[TestNG_Tests]
    B --> C[PageObjects]
    C --> D[WebDriver_Selenium]
    D --> E[WebApp_Under_Test]
    D --> F[Healenium_Proxy]
    F -->|Heals_Locators| D
    F --> G[Healenium_Backend]
    G --> H[DockerCompose]
Loading

📋 Table of Contents

  1. What is Test Automation?
  2. Prerequisites
  3. Project Setup
  4. Understanding the Project Structure
  5. Key Concepts Explained
  6. Running Your First Test
  7. Understanding the Code
  8. Creating Your Own Tests
  9. Best Practices
  10. Troubleshooting

🤔 What is Test Automation?

Manual Testing: You manually open the browser, navigate to the website, click buttons, enter text, and verify results.

Automated Testing: You write code (scripts) that automatically opens the browser, performs actions, and verifies results without your intervention.

Why Automate?

  • Save time on repetitive tests
  • Run tests overnight or on multiple browsers
  • Consistent test execution
  • Quick feedback on code changes

📦 Prerequisites

Required Software (Install in this order):

  1. Java JDK 11 or higher

  2. Maven (Build Tool)

  3. IDE (Integrated Development Environment)

  4. Google Chrome Browser

    • Most tests use Chrome (already installed on most systems)

🚀 Project Setup

Step 1: Open the Project in IDE

For IntelliJ IDEA:

  1. Open IntelliJ IDEA
  2. Click "Open"
  3. Navigate to selenium-testng-automation-framework folder
  4. Click "Open"
  5. Wait for Maven to download dependencies (check progress bar at bottom)

For Eclipse:

  1. Open Eclipse
  2. File → Import → Maven → Existing Maven Projects
  3. Browse to selenium-testng-automation-framework folder
  4. Click "Finish"

Step 2: Download Dependencies

Maven will automatically download all required libraries (Selenium, TestNG, etc.) based on the pom.xml file.

To manually trigger download:

  • IntelliJ: Right-click pom.xml → Maven → Reload Project
  • Eclipse: Right-click project → Maven → Update Project

📁 Understanding the Project Structure

selenium-testng-automation-framework/
│
├── src/
│   ├── main/java/
│   │   ├── pages/              # Page Object Model classes
│   │   │   ├── LoginPage.java      # Login page elements & actions
│   │   │   ├── HomePage.java       # Home page elements & actions
│   │   │   └── ProductPage.java    # Product page elements & actions
│   │   │
│   │   └── utils/              # Utility/Helper classes
│   │       ├── DriverManager.java   # Browser setup & management
│   │       ├── WaitHelper.java      # Waiting mechanisms
│   │       └── ConfigReader.java    # Read configuration files
│   │
│   └── test/
│       ├── java/
│       │   ├── base/
│       │   │   └── BaseTest.java    # Parent class for all tests
│       │   │
│       │   └── tests/           # Test classes
│       │       ├── LoginTest.java
│       │       ├── HomePageTest.java
│       │       └── DataDrivenLoginTest.java
│       │
│       └── resources/
│           └── config.properties    # Configuration settings
│
├── pom.xml                     # Maven dependencies & build config
├── testng.xml                  # TestNG suite configuration
└── screenshots/                # Auto-generated test screenshots

What Each Folder Contains:

  • pages/: Represents web pages. Each class contains elements and actions for one page.
  • utils/: Helper classes used across the project.
  • base/: Common setup code that all tests inherit.
  • tests/: Your actual test cases.
  • resources/: Configuration files (URLs, credentials, browser settings).

🎓 Key Concepts Explained

1. Page Object Model (POM)

Think of it like this:

  • Each web page in your application = One Java class
  • Each element on the page (button, textbox) = One variable in the class
  • Each action on the page (click, type) = One method in the class

Example:

// LoginPage.java
@FindBy(id = "username")
WebElement usernameField;  // This finds the username textbox

public void enterUsername(String username) {
    usernameField.sendKeys(username);  // This types into it
}

Benefits:

  • If a button ID changes, you only update it in ONE place
  • Tests remain clean and readable
  • Easy to maintain

2. TestNG Annotations

Annotations are special markers that tell TestNG what to do with your methods.

@BeforeMethod  // Runs BEFORE each test (setup)
@Test          // This is a test case
@AfterMethod   // Runs AFTER each test (cleanup)
@DataProvider  // Provides multiple test data

Execution Order:

  1. @BeforeMethod → Setup (open browser, navigate to site)
  2. @Test → Your actual test
  3. @AfterMethod → Cleanup (close browser, save screenshot)

3. WebDriver

WebDriver is the "robot" that controls the browser.

WebDriver driver = new ChromeDriver();  // Creates Chrome browser instance
driver.get("https://example.com");      // Opens website
driver.findElement(By.id("login")).click();  // Clicks element
driver.quit();                          // Closes browser

4. Locators (How to find elements)

Locator Example Use Case
id @FindBy(id = "username") Fastest, most reliable (if available)
name @FindBy(name = "email") Good alternative to id
className @FindBy(className = "btn-primary") For elements with specific CSS class
linkText @FindBy(linkText = "Forgot Password?") For links with exact text
xpath @FindBy(xpath = "//button[@type='submit']") Most flexible, can find anything
cssSelector @FindBy(css = ".login-button") Faster than xpath

5. Assertions (Verifying Results)

Assertions check if expected result matches actual result.

// Check if login was successful
Assert.assertTrue(homePage.isUserLoggedIn(), "Login failed!");

// Check if URL contains "dashboard"
Assert.assertTrue(driver.getCurrentUrl().contains("dashboard"));

// Check if text matches
Assert.assertEquals(actualText, "Welcome", "Text doesn't match!");

If assertion fails → Test fails → Screenshot is captured


▶️ Running Your First Test

Method 1: Run via IDE

IntelliJ IDEA:

  1. Open LoginTest.java
  2. Right-click on class name or green arrow next to class
  3. Click "Run 'LoginTest'"

To run single test method:

  • Right-click on specific @Test method → Run

Method 2: Run via TestNG XML

  1. Right-click on testng.xml
  2. Click "Run 'testng.xml'"
  3. This runs ALL tests in the suite

Method 3: Run via Maven Command

Open terminal in project folder and run:

mvn clean test

What to Expect:

  1. Chrome browser will open automatically
  2. Browser navigates to the test website
  3. Actions happen automatically (typing, clicking)
  4. Browser closes
  5. See results in console or TestNG report

📖 Understanding the Code

Example: LoginTest.java

@Test(priority = 1, description = "Verify login with valid credentials")
public void testValidLogin() {
    // 1. Create page object instance
    LoginPage loginPage = new LoginPage(driver);
    
    // 2. Perform actions
    loginPage.login(config.getUsername(), config.getPassword());
    
    // 3. Verify result
    String currentUrl = driver.getCurrentUrl();
    Assert.assertTrue(currentUrl.contains("secure"), 
        "Login failed - User not redirected to secure page");
}

Breaking it down:

  1. @Test: Marks this as a test case

    • priority = 1: Run this test first
    • description: Explains what test does
  2. Create Page Object:

    LoginPage loginPage = new LoginPage(driver);
    • Creates instance of LoginPage
    • Passes driver so it knows which browser to control
  3. Perform Action:

    loginPage.login(username, password);
    • Calls the login method from LoginPage class
    • Enters username & password, clicks login button
  4. Verify Result:

    Assert.assertTrue(currentUrl.contains("secure"), "Error message");
    • Checks if URL contains "secure" (meaning login succeeded)
    • If not, test fails with error message

✍️ Creating Your Own Tests

Step-by-Step Guide

Step 1: Create a New Test Class

  1. Right-click on tests folder
  2. New → Java Class
  3. Name it: YourFeatureTest.java
package tests;

import base.BaseTest;
import org.testng.Assert;
import org.testng.annotations.Test;
import pages.LoginPage;

public class MyFirstTest extends BaseTest {
    
    @Test
    public void testLogin() {
        // Your test code here
    }
}

Important:

  • Always extend BaseTest (gives you browser setup)
  • Use @Test annotation
  • Write descriptive method names

Step 2: Write Test Steps

Think about your manual test steps, then convert to code:

Manual Steps:

  1. Go to login page
  2. Enter username: "tomsmith"
  3. Enter password: "SuperSecretPassword!"
  4. Click Login button
  5. Verify user reaches home page

Automated Steps:

@Test
public void testSuccessfulLogin() {
    // Step 1: Browser already opens via BaseTest
    
    // Step 2-4: Use page object
    LoginPage loginPage = new LoginPage(driver);
    loginPage.enterUsername("tomsmith");
    loginPage.enterPassword("SuperSecretPassword!");
    loginPage.clickLoginButton();
    
    // Step 5: Verify
    String url = driver.getCurrentUrl();
    Assert.assertTrue(url.contains("secure"), "Login failed");
}

Step 3: Add to TestNG Suite

Open testng.xml and add your test:

<test name="My New Tests">
    <classes>
        <class name="tests.MyFirstTest"/>
    </classes>
</test>

✅ Best Practices for Beginners

1. Write Clear Test Names

Good: testLoginWithValidCredentials()
❌ Bad: test1()

2. One Test = One Scenario

Don't try to test everything in one test. Keep tests focused.

Good: Separate tests for valid login, invalid login, empty fieldsBad: One giant test that tests all login scenarios

3. Use Assertions

Always verify your test results.

@Test
public void testLogin() {
    loginPage.login("user", "pass");
    // Missing assertion - How do you know it worked?
}

// Better:
@Test
public void testLogin() {
    loginPage.login("user", "pass");
    Assert.assertTrue(homePage.isDisplayed(), "Login failed");
}

4. Add Waits When Needed

If elements aren't found, add wait time:

Thread.sleep(2000);  // Wait 2 seconds (simple but not recommended)

// Better: Use WaitHelper
WaitHelper wait = new WaitHelper(driver);
wait.waitForElementVisible(element);

5. Use Configuration File

Don't hardcode URLs or credentials in tests. Use config.properties:

// ❌ Bad
driver.get("https://example.com");

// ✅ Good
driver.get(config.getUrl());

6. Meaningful Assertion Messages

// ❌ Bad
Assert.assertTrue(result);

// ✅ Good
Assert.assertTrue(result, "Login button is not clickable");

🐛 Troubleshooting

Common Issues & Solutions

1. "Cannot find Chrome driver"

Solution: WebDriverManager should handle this automatically. If not:

  • Make sure Chrome is installed
  • Check internet connection (downloads driver)

2. "Element not found"

Causes:

  • Element hasn't loaded yet → Add wait
  • Wrong locator → Use browser DevTools to find correct locator
  • Element is in iframe → Switch to iframe first

Solution:

// Add wait before finding element
Thread.sleep(2000);
// Or use explicit wait
WaitHelper wait = new WaitHelper(driver);
wait.waitForElementVisible(element);

3. "Tests are failing randomly"

Cause: Timing issues (elements not loaded)

Solution:

  • Add implicit wait in BaseTest
  • Use explicit waits for critical elements
  • Avoid using fixed Thread.sleep()

4. "Java version error"

Solution:

  • Check Java version: java -version
  • Make sure JDK 11+ is installed
  • Update pom.xml if using different Java version

5. "Dependencies not downloading"

Solution:

  • Check internet connection
  • Right-click pom.xml → Maven → Reload Project
  • Delete .m2 folder and rebuild

🎯 Next Steps

Practice Exercises:

  1. Beginner:

    • Modify testng.xml to run only LoginTest
    • Change browser from Chrome to Firefox in config.properties
    • Add a new assertion to existing test
  2. Intermediate:

    • Create a new Page Object for "Product Page"
    • Write 3 new test cases for product search
    • Implement data-driven testing with 5 test data sets
  3. Advanced:

    • Add Excel file reading for test data
    • Implement TestNG listeners for custom reporting
    • Integrate with CI/CD (GitHub Actions)
    • Add parallel test execution

🐛 What If Tests Fail?

Don't worry! This is normal and part of learning automation.

📖 See DEBUGGING_GUIDE.md for a complete step-by-step tutorial on:

  • How to read error messages
  • How to inspect elements with browser DevTools
  • How to find correct locators
  • How to fix failing tests
  • Hands-on exercises

The debugging guide teaches you the most important skill in automation: troubleshooting!


🔧 Self-Healing with Healenium (Advanced Feature)

Production-grade resilience pattern!

This project uses Healenium for automatic locator healing when web elements change.

Benefits:

  • ✅ Tests auto-recover when locators change
  • ✅ Reduces test maintenance
  • ✅ Shows advanced Selenium skills
  • ✅ Industry best practice

How it works:

// Healenium automatically finds alternative locators when original fails
@FindBy(id = "login")
WebElement loginButton;  // If ID changes, Healenium finds it by other attributes

Setup: See infra/docker-compose.yml to run Healenium backend services.


🏋️ Practice & Improve

📚 EXERCISES.md - Learn by doing!

  • 20+ hands-on exercises from beginner to expert
  • Complete solutions with explanations
  • Gradually detailed hints (3 levels)
  • Exercise 6: Implement self-healing locators!
  • Progress tracking checklist
  • Challenge projects for mastery

📚 Additional Resources

Project Documentation

External Resources


🤝 Getting Help

  • Check browser console for JavaScript errors
  • Use browser DevTools (F12) to inspect elements
  • Read error messages carefully - they often tell you what's wrong
  • Google the error message - others have likely faced same issue

📝 Summary

What You've Learned:

  • ✅ How to set up a Selenium project
  • ✅ Page Object Model pattern
  • ✅ Writing TestNG tests
  • ✅ Running automated tests
  • ✅ Best practices for maintainable tests

Remember:

  • Start small - automate simple scenarios first
  • Practice regularly - automation is a skill that improves with practice
  • Don't try to automate everything - focus on stable, repetitive tests
  • Keep learning - automation tools evolve constantly

Welcome to Test Automation! 🎉


🎨 Writing Clean Code

This project follows clean code principles to ensure maintainable, readable test automation code.

Key Principles Applied:

  • Meaningful Names: All classes, methods, and variables have descriptive names
  • Single Responsibility: Each class/method does one thing well
  • DRY (Don't Repeat Yourself): Reusable page objects and utilities
  • Small Functions: Methods are short and focused
  • No Magic Numbers: Constants used for timeouts and waits
  • Clear Assertions: Every assertion has a descriptive failure message
  • Consistent Formatting: Uniform code style throughout

Learn More:

📖 See CLEAN_CODE_GUIDE.md for a comprehensive guide on:

  • What is clean code and why it matters
  • 10 essential clean code principles with examples
  • Before/after code comparisons
  • Common code smells and how to fix them
  • Practical refactoring exercises
  • Clean code checklist

Good code is like a good joke - it needs no explanation!


👤 Author

Carolina Steadham


⭐ Star this repo if you find it helpful!

Made with ❤️ and Python

About

Self-healing Selenium test automation framework with Healenium integration

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors