Run your Selenium tests through TestNG, then open the generated index.html in the output directory supplied to TestNG. If Maven Surefire launches the suite, its TestNG integration adds HTML and XML listeners automatically; the exact report directory is determined by your Surefire and project configuration.
What TestNG generates
Reporting belongs to TestNG and its build integrations, not to Selenium WebDriver. A direct TestNG run creates an index.html file in the directory specified when SuiteRunner starts. That page links to additional HTML and text files containing the run results.
When Maven Surefire runs TestNG, Surefire attaches basic HTML and XML listeners by default. Treat the Maven build output and your Surefire configuration as the source of truth for the actual location rather than assuming that the standalone TestNG directory is used.
Choose the output you need
| Need | Use | When it is produced |
|---|---|---|
| Browser-readable summary | Built-in TestNG HTML, including index.html |
After a direct TestNG run, or through the HTML listener used by Surefire |
| Structured build result | Surefire’s XML output or TestNG’s XMLReporter |
During the configured TestNG/Maven execution |
| Live events | ITestListener |
As tests start, pass, fail, or skip |
| One complete custom report | IReporter |
After every suite has finished |
Check Java and TestNG compatibility
Match the TestNG release to the JDK used by the project. The official TestNG compatibility guidance says releases through 7.5 require JDK 8, while TestNG 7.6.0 and later require JDK 11 or newer. The current documentation identifies TestNG 7.9.0 and shows a JDK 11 Maven example.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minute#1 Best Overall
| TestNG release | JDK requirement stated by TestNG |
|---|---|
| Through 7.5 | JDK 8 |
| 7.6.0 and later | JDK 11 or newer |
Confirm the JDK selected by your IDE, Maven, and CI runner; it is common for an IDE to use a different Java installation from the command line.
Build a minimal Selenium/TestNG project
1. Add TestNG to Maven
Use a test-scoped dependency. This example follows the 7.9.0/JDK 11 combination documented by TestNG; select another release when your JDK or organization requires it.
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>example</groupId>
<artifactId>selenium-testng-reports</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.release>11</maven.compiler.release>
</properties>
<dependencies>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>YOUR_SELENIUM_VERSION</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Replace YOUR_SELENIUM_VERSION with the Selenium version already approved for your project. Keeping Selenium and reporting dependencies separate makes it clear that TestNG is producing the report.
2. Create a Selenium test
package example;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class HomePageTest {
private WebDriver driver;
@BeforeMethod
public void startBrowser() {
driver = new ChromeDriver();
}
@Test
public void titleContainsExample() {
driver.get("https://example.com");
Reporter.log("Loaded " + driver.getCurrentUrl(), true);
Assert.assertTrue(driver.getTitle().contains("Example"));
}
@AfterMethod
public void stopBrowser() {
if (driver != null) {
driver.quit();
}
}
}
Reporter.log messages are included in generated HTML reports. Keep messages short and diagnostic, and never put passwords, session tokens, authorization headers, or sensitive page content into them.
Free tools Windows power users keep installed
One-click scans. No signup required.
Rank #2
3. Define the suite
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Selenium suite">
<test name="Smoke tests">
<classes>
<class name="example.HomePageTest"/>
</classes>
</test>
</suite>
Run the suite and find the report
Maven Surefire
- Save the suite as
testng.xml(or use the suite path configured in your POM). - Run
mvn clean testfrom the project directory. - Read the Maven build output and inspect the report directory configured by Surefire. Surefire’s TestNG integration creates HTML and XML results through its listeners, but the path can change with plugin version and configuration.
On a Unix-like shell, search the build output when you do not know the configured location:
find . -type f ( -name 'index.html' -o -name '*.xml' ) -print
In PowerShell, use:
Get-ChildItem -Recurse -File | Where-Object { $_.Name -eq 'index.html' -or $_.Extension -eq '.xml' }
Direct TestNG execution
Run the suite with your existing TestNG launcher or IDE configuration and specify an output directory when launching SuiteRunner. Open the resulting index.html; its links lead to the other HTML and text result files. If the page is not where expected, inspect the launch configuration for the output-directory argument instead of searching only Maven’s directories.
Use listeners for live diagnostics
Implement ITestListener when an action must happen while the run is in progress—for example, logging a failure immediately, sending a notification, or collecting a screenshot path from a Selenium failure handler.
package example;
import org.testng.ITestListener;
import org.testng.ITestResult;
import org.testng.Reporter;
public class RunListener implements ITestListener {
@Override
public void onTestStart(ITestResult result) {
Reporter.log("START " + result.getMethod().getQualifiedName(), true);
}
@Override
public void onTestSuccess(ITestResult result) {
Reporter.log("PASS " + result.getMethod().getQualifiedName(), true);
}
@Override
public void onTestFailure(ITestResult result) {
Reporter.log("FAIL " + result.getMethod().getQualifiedName()
+ ": " + result.getThrowable(), true);
}
@Override
public void onTestSkipped(ITestResult result) {
Reporter.log("SKIP " + result.getMethod().getQualifiedName(), true);
}
}
Register it either on a test class:
import org.testng.annotations.Listeners;
@Listeners(example.RunListener.class)
public class HomePageTest {
// tests
}
or in testng.xml:
<suite name="Selenium suite">
<listeners>
<listener class-name="example.RunListener"/>
</listeners>
<test name="Smoke tests">
<classes>
<class name="example.HomePageTest"/>
</classes>
</test>
</suite>
Build a post-run report with IReporter
Use IReporter when the report needs the final state of every suite. TestNG calls generateReport after all suites complete and supplies the suite results plus the output directory.
Rank #3
package example;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import org.testng.IReporter;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestContext;
import org.testng.xml.XmlSuite;
public class SummaryReporter implements IReporter {
@Override
public void generateReport(List<XmlSuite> xmlSuites,
List<ISuite> suites,
String outputDirectory) {
Path file = Paths.get(outputDirectory, "summary.html");
try {
Files.createDirectories(file.getParent());
try (PrintWriter out = new PrintWriter(Files.newBufferedWriter(file))) {
out.println("<html><body><h1>TestNG summary</h1>");
for (ISuite suite : suites) {
out.println("<h2>" + suite.getName() + "</h2>");
for (Map.Entry<String, ISuiteResult> entry
: suite.getResults().entrySet()) {
ITestContext context = entry.getValue().getTestContext();
out.printf("<p>%s: passed=%d, failed=%d, skipped=%d</p>%n",
entry.getKey(),
context.getPassedTests().size(),
context.getFailedTests().size(),
context.getSkippedTests().size());
}
}
out.println("</body></html>");
}
} catch (IOException e) {
throw new IllegalStateException("Cannot write " + file, e);
}
}
}
Register this class with @Listeners or the <listeners> block shown above. A reporter is not a replacement for a live listener: it cannot observe an event before the suite has finished.
Generate TestNG-specific XML
TestNG’s XMLReporter is useful when another system needs TestNG-specific information that a JUnit-style result does not contain. Its documented settings cover:
- the output directory;
- file fragmentation level;
- stack-trace detail and output method;
- group attributes;
- result attributes; and
- dependency information.
When using the TestNG command-line reporter option, provide the reporter class followed by its colon-separated properties. For example:
java -cp "YOUR_TESTNG_CLASSPATH" org.testng.TestNG
-d reports/testng
-reporter org.testng.reporters.XMLReporter:outputDirectory=reports/testng/xml:fileFragmentationLevel=1
Use the property names supported by the TestNG version in your build, and keep the command-line or build-task configuration consistent with the runner that actually executes the tests. If Maven is the execution path, configure the reporter through Surefire rather than assuming a standalone command-line output directory.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Rank #4
Troubleshoot missing or incomplete reports
| Symptom | Likely cause | Fix |
|---|---|---|
No index.html after a direct run |
The launcher did not specify the output directory, or you are checking a different directory. | Inspect the SuiteRunner launch configuration, run again with an explicit output directory, and open the index.html created there. |
| Maven creates files, but not where expected | Surefire version or configuration changed the report location. | Read the Maven log, inspect the Surefire configuration, and search the build tree for index.html and XML files. |
| Tests run but custom callbacks never fire | The listener/reporter class was not registered, or the configured class name is wrong. | Use @Listeners or a fully qualified class name in testng.xml; verify the class is on the test classpath. |
| Custom report is empty | The implementation expects events during execution but was written as an IReporter, or it reads the wrong suite result. |
Use ITestListener for live state; in IReporter, iterate the supplied ISuite and ISuiteResult objects. |
| XML lacks the fields a downstream tool needs | The default XML is not the TestNG-specific format required by that tool. | Use XMLReporter and configure result, group, stack-trace, fragmentation, and dependency options for your TestNG release. |
| Browser test fails before reporting code runs | WebDriver startup, a driver binary, or the page under test failed independently of reporting. | Separate browser setup failures from report generation; keep an @AfterMethod cleanup guard and use listener logging to record the failure context. |
| Build fails before TestNG starts | The JDK and TestNG versions are incompatible. | Check the JDK actually used by Maven/CI and select a TestNG release compatible with it: through 7.5 for JDK 8, or 7.6.0 and later for JDK 11+. |
Reliability, performance, and security practices
- Keep report generation out of the test’s critical path where possible. Lightweight listener logging has less impact than collecting large page sources or screenshots for every step.
- For parallel suites, include the test method, thread, and URL in diagnostic messages so failures can be distinguished without changing the framework’s result files.
- Archive the exact HTML/XML directory produced by the same build as the test results; copying only
index.htmlcan break its relative links. - Do not publish reports containing credentials, authorization headers, session identifiers, personal data, or unrestricted page source.
- Use a post-run
IReporterfor a stable artifact and anITestListenerfor immediate notifications; combining them is valid when each has a separate purpose.
Or skip the browser setup
If your goal is to capture a clean image or PDF of a web page involved in a Selenium workflow, ScreenshotNeo provides a website screenshot API and MCP server. It accepts one GET request and can return PNG, JPEG, WebP, or PDF. Cookie/consent banners, newsletter popups, and chat widgets are removed before capture; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.
See the ScreenshotNeo API documentation for all options. A basic cURL request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The equivalent Python request is:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo also has an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Its Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Start with the free ScreenshotNeo account.
FAQ
Does Selenium WebDriver create the TestNG report?
No. WebDriver drives the browser; TestNG or the Maven runner produces the report artifacts.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Can I use both a listener and a reporter?
Yes. Register both when you need live failure handling and a final consolidated artifact; give each one a distinct responsibility.
Best Value
Is TestNG XML the same as JUnit XML?
No. TestNG’s XMLReporter is intended to preserve TestNG-specific details, so consumers should be configured for the format they receive.
Frequently Asked Questions
Does Selenium WebDriver create the TestNG report?
No. WebDriver drives the browser; TestNG or the Maven runner produces the report artifacts.
Can I use both a listener and a reporter?
Yes. Register both when you need live failure handling and a final consolidated artifact; give each one a distinct responsibility.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Is TestNG XML the same as JUnit XML?
No. TestNG’s XMLReporter is intended to preserve TestNG-specific details, so consumers should be configured for the format they receive.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

