A robust test automation framework built with Selenium WebDriver, TestNG, and Docker Selenium Grid, optimized for Apple Silicon (ARM64).
- Page Object Model (POM) design pattern
- Docker Selenium Grid with ARM64 support
- Parallel test execution with thread safety
- Comprehensive reporting with Extent Reports
- Automated screenshot capture on test failures
- Full test execution video recording
- Smart retry mechanism for flaky tests
- Cross-browser testing (Chrome, Firefox, Safari*)
- Enhanced wait utilities with custom conditions
- Structured logging with Log4j2
- Data-driven testing support (Excel, CSV, JSON)
- Environment-specific configuration
- API testing integration
- Custom annotations for test management
- CI/CD ready configuration
- Java 11
- Selenium WebDriver 4.28.1
- TestNG 7.10.2
- Extent Reports 5.1.2
- Log4j2
- Docker & Docker Compose
- Maven
- Java 11 or higher
- Maven 3.8+
- Docker Desktop for Mac (Apple Silicon)
- TestNG Configuration (
testng.xml): xml
-
Start Docker containers: bash:README.md docker-compose up -d
-
Verify Grid is running:
- Grid Console: http://localhost:4444/ui
- Chrome Node: http://localhost:6900 (VNC password: secret)
- Firefox Node: http://localhost:6902 (VNC password: secret)
-
Run all tests: bash:README.md mvn clean test
-
Run specific test suite: bash:README.md mvn clean test -DsuiteXmlFile=testng.xml
-
Run with specific browser: bash:README.md mvn clean test -Dbrowser=chrome
-
Run tests in parallel: bash:README.md mvn clean test -Dthreads=3
selenium-framework/ ├── src/ │ ├── main/ │ │ └── java/ │ │ └── com/framework/ │ │ ├── base/ │ │ │ ├── BasePage.java │ │ │ └── BaseTest.java │ │ ├── config/ │ │ │ ├── Configuration.java │ │ │ └── DriverFactory.java │ │ ├── pages/ │ │ │ ├── LoginPage.java │ │ │ └── HomePage.java │ │ ├── utils/ │ │ │ ├── DriverUtils.java │ │ │ ├── WaitUtil.java │ │ │ ├── ScreenshotUtil.java │ │ │ ├── ExcelUtil.java │ │ │ └── APIUtil.java │ │ └── listeners/ │ │ ├── TestListener.java │ │ └── RetryAnalyzer.java │ └── test/ │ └── java/ │ └── com/tests/ │ ├── LoginTest.java │ └── HomePageTest.java ├── resources/ │ ├── config.properties │ ├── log4j2.xml │ └── testdata/ │ ├── testdata.xlsx │ └── api-payloads/ ├── docker-compose.yaml ├── pom.xml ├── testng.xml └── README.md
java public class LoginPage extends BasePage { @FindBy(id = "username") private WebElement usernameInput; @FindBy(id = "password") private WebElement passwordInput; @FindBy(id = "login-btn") private WebElement loginButton; public LoginPage(WebDriver driver) { super(driver); PageFactory.initElements(driver, this); } public HomePage login(String username, String password) { waitUtil.waitForElementVisible(usernameInput); usernameInput.sendKeys(username); passwordInput.sendKeys(password); loginButton.click(); return new HomePage(driver); } }
java @Test(dataProvider = "loginData") public void testLogin(String username, String password, String expectedTitle) { LoginPage loginPage = new LoginPage(driver); HomePage homePage = loginPage.login(username, password); Assert.assertEquals(homePage.getTitle(), expectedTitle); }
- HTML Reports:
test-output/ExtentReport/TestReport.html - Screenshots:
test-output/screenshots/[date]/[timestamp]/ - Videos:
test-output/videos/ - Logs:
logs/automation.log
Test Report ├── Dashboard │ ├── Test Summary │ └── Category Summary ├── Tests │ ├── Login Tests │ │ ├── Valid Login Test │ │ └── Invalid Login Test │ └── Home Page Tests └── Media ├── Screenshots └── Videos
yaml version: '3' services: selenium-hub: image: seleniarm/hub:4.16.1 container_name: selenium-hub ports: "4444:4444" "4443:4443" chrome: image: seleniarm/node-chromium:4.16.1 shm_size: 2gb depends_on: selenium-hub environment: SE_EVENT_BUS_HOST=selenium-hub SE_EVENT_BUS_PUBLISH_PORT=4442 SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ports: "6900:5900" firefox: image: seleniarm/node-firefox:4.16.1 shm_size: 2gb depends_on: selenium-hub environment: SE_EVENT_BUS_HOST=selenium-hub SE_EVENT_BUS_PUBLISH_PORT=4442 SE_EVENT_BUS_SUBSCRIBE_PORT=4443 ports: "6902:5900"
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE.md file for details