Selenium + TestNG + Log4j Automation Framework Documentation
1. Project Overview
This framework automates web application testing using:
Selenium WebDriver
TestNG
Log4j 2
Apache POI for Excel
TestNG Listeners for screenshots
Features:
POM design for maintainable page classes
Centralized configuration ([Link])
Data-driven tests using Excel
Thread-safe WebDriver for parallel execution
Log4j logging for debugging & reporting
Screenshots on test failures
2. Project Structure
src
├─ main/java/com/alchemist/generic
│ ├─ [Link]
│ ├─ [Link]
│ ├─ [Link]
│ └─ [Link]
├─ main/java/com/alchemist/pompages
│ └─ [Link]
├─ test/java/com/alchemist/scripts
│ └─ [Link]
resources
│ ├─ [Link]
│ └─ [Link]
screenshots
logs
[Link]
[Link]
3. Configuration Files
3.1 [Link]
URL=[Link]
ImplicitTimeOut=10
3.2 [Link]
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:[Link]} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="FileLogger" fileName="logs/[Link]">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="FileLogger"/>
</Root>
</Loggers>
</Configuration>
4. [Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class BaseTest implements IAutoConstant {
protected static final Logger log = [Link]([Link]);
public static WebDriver driver;
static {
[Link](CHROME_KEY, CHROME_VALUE);
[Link](GECKO_KEY, GECKO_VALUE);
[Link]("Browser drivers set successfully.");
}
@BeforeMethod
public void openApp() {
driver = new ChromeDriver();
[Link]("Chrome browser launched.");
String url = [Link](CONFIG_PATH, "URL");
[Link](url);
[Link]("Navigated to URL: " + url);
int timeOutPeriod = [Link]([Link](CONFIG_PATH, "ImplicitTimeOut"));
[Link]().timeouts().implicitlyWait([Link](timeOutPeriod));
[Link]("Implicit wait set to " + timeOutPeriod + " seconds.");
}
@AfterMethod(alwaysRun = true)
public void closeApplication() {
try {
if (driver != null) {
[Link]();
[Link]("Browser closed successfully.");
}
} catch (Exception e) {
[Link]("Error while closing browser", e);
}
}
public void takeScreenshot(String testname) {
try {
Date date = new Date();
String currentDate = [Link]().replaceAll(":", "_");
File destDir = new File(".\\screenshots\\" + currentDate);
if (![Link]()) [Link]();
TakesScreenshot ts = (TakesScreenshot) driver;
File src = [Link]([Link]);
File dest = new File(destDir, testname + "_screenshot.png");
[Link](src, dest);
[Link]("Screenshot captured for test: " + testname + " at " + [Link]());
} catch (IOException e) {
[Link]("Failed to capture screenshot for test: " + testname, e);
}
}
}
5. [Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class TestNgListeners implements ITestListener {
private static final Logger log = [Link]([Link]);
@Override
public void onTestStart(ITestResult result) {
[Link]("===== Test Started: " + [Link]() + " =====");
}
@Override
public void onTestSuccess(ITestResult result) {
[Link]("===== Test Passed: " + [Link]() + " =====");
}
@Override
public void onTestFailure(ITestResult result) {
[Link]("===== Test Failed: " + [Link]() + " =====");
BaseTest base = (BaseTest) [Link]();
[Link]([Link]());
[Link]("Screenshot captured for failed test: " + [Link]());
}
@Override
public void onTestSkipped(ITestResult result) {
[Link]("===== Test Skipped: " + [Link]() + " =====");
}
@Override
public void onTestFailedWithTimeout(ITestResult result) {
onTestFailure(result);
}
@Override
public void onStart(ITestContext context) {
[Link]("===== Test Suite Started: " + [Link]() + " =====");
}
@Override
public void onFinish(ITestContext context) {
[Link]("===== Test Suite Finished: " + [Link]() + " =====");
}
}
6. [Link]
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
public class TestLogin extends BaseTest {
private static final Logger log = [Link]([Link]);
@Test
public void testLogin() {
[Link]("====== Starting Test: testLogin ======");
try {
LoginPage loginPage = new LoginPage(driver);
String uname = [Link](EXCEL_PATH, "ValidLogin", 1, 0);
String password = [Link](EXCEL_PATH, "ValidLogin", 1, 1);
String expectedTitle = [Link](EXCEL_PATH, "ValidLogin", 1, 2);
[Link]("Logging in with username: " + uname);
[Link](uname);
[Link]("Entered username.");
[Link](password);
[Link]("Entered password.");
[Link]();
[Link]("Clicked on Login button.");
String actualTitle = [Link]();
[Link]("Actual page title: " + actualTitle);
[Link](actualTitle, expectedTitle);
[Link]("Login test passed.");
} catch (Exception e) {
[Link]("Exception occurred during login test", e);
takeScreenshot("testLogin");
throw e;
}
[Link]("====== Ending Test: testLogin ======");
}
}
7. [Link]
<suite name="Suite">
<listeners>
<listener class-name="[Link]