Playwright records a trace of everything. Cypress saves a screenshot and video automatically. Selenium saves nothing at all, ever, unless you write the code.
That is the trade-off for a library rather than a framework, and it means a failed run on a build server tells you only what you arranged to be told. Here is the minimum worth arranging.
A screenshot on failure. This is the highest-value thing you can add, and it is a few lines in an afterEach:
afterEach(async function () {
if (this.currentTest.state === 'failed') {
const image = await driver.takeScreenshot();
const name = this.currentTest.title.replace(/\s+/g, '-');
fs.writeFileSync(`screenshots/${name}.png`, image, 'base64');
}
});
takeScreenshot returns base64 text, so you decode it when writing the file. One image answers most questions: was the page blank, was there an error banner, was a dialog covering the button.
The browser console log. Often more useful than the screenshot, because it shows JavaScript errors from the app itself:
const logs = await driver.manage().logs().get('browser');
logs.forEach((entry) => console.log(entry.level.name, entry.message));
A page that half-rendered usually has a red console error explaining why. Note this works in Chromium browsers and is inconsistent elsewhere, which is typical of Selenium's cross-browser reality.
The page source at the moment of failure:
const html = await driver.getPageSource();
Bulky, and occasionally the only thing that shows an element was present but hidden.
A report from your test runner. Since the runner is yours, so is the report. Mocha with mochawesome gives an HTML report; mocha-junit-reporter gives JUnit XML for a CI dashboard. Java teams use Allure or ExtentReports, which are more capable than anything in the JavaScript world and are worth naming in an interview.
Three habits.
Attach screenshots to the report, not just to a folder. A report that links its evidence is used. A folder of PNGs on a build server is not.
Upload artifacts from CI. They are written on a machine that gets destroyed. Every CI system can keep them as build artifacts, and skipping that step means collecting evidence and throwing it away.
Name tests after behaviour. A report full of "test1" and "works correctly" is useless. Named properly, the report reads as a list of what your application does, useful even to people who never open the code.
Remember this: Selenium records nothing by default. A screenshot and the console log in an afterEach hook is the cheapest useful thing you will ever add to a suite.
Reference: Logging.