Video Reporter

Create a video screen capture of your tests and enhance your Allure reporting easily!
This is a WebdriverIO reporter that generates videos of your test executions. If you use it in combination with the Allure Reporter, then the test cases automatically get decorated with the videos as well (see example project).
As this reporter is using the WebDriver screenshot command (takeScreenshot) to render the video it supports all environments including mobile environments.
In a WebDriver BiDi session, the reporter uses the WebDriver BiDi screenshot command (browsingContextCaptureScreenshot): in Chrome, a WebDriver screenshot at the start of a WebDriver BiDi navigation can make the test wait 10 seconds.
In a WebDriver BiDi session, some commands use WebDriver BiDi instead of a WebDriver endpoint: url (with an http or https URL), back, forward, refresh and actions. The reporter also takes a frame for these commands. execute in a BiDi session gives no frame (WebdriverIO also uses the same BiDi command inside many other commands).
setViewport, emulate, and the element commands that run a script (for example clearValue or selectByIndex on
the browsing context that newWindow() returns) give no frame either. Use
screenshotIntervalSecs to get frames between commands.
In a WebDriver BiDi session, a frame can show the page a short time after its command: when a command starts a navigation (for example a click on a link), its frame can show the next page. When the BiDi session has no screenshot command (for example with Appium), the reporter takes WebDriver classic screenshots.
In a multi-remote session, the reporter records the first browser instance, and only the commands of that instance take a frame.
In a WebDriver BiDi session, when a test works in another tab or window (for example the browsing context that
newWindow() returns), the reporter takes the frames of that tab or window. If that screenshot fails, for
example right after the tab opens, the frame shows the main window. A frame that the reporter starts when the
session ends (after the last step of the last test of a spec file, or at reloadSession()) shows the page of the
frame before it.
That said, taking a screenshot after almost every command can slow down your tests. In a WebDriver BiDi session, the next command waits for the screenshot of the last frame (about 50 to 70 ms in Chrome), so that each frame shows the page of its command. Also, note that the videos don't include alert-boxes and popups.
In Safari, the frame of a click can show the page from before the click
(WebKit bug 328312). In Safari on iOS, the frame of a navigation
(url) can also show the page before it.
Alertsโ
In a WebDriver classic session, a screenshot while an alert (alert(), confirm(), prompt()) is open makes the
driver handle the alert as unhandledPromptBehavior
says. With the default, Chrome and Firefox close the alert, and the next getAlertText() or acceptAlert() of the test
fails with no such alert. Set unhandledPromptBehavior: 'ignore' in the capabilities of the tests that use alerts:
capabilities: [{
browserName: 'chrome',
'wdio:enforceWebDriverClassic': true,
unhandledPromptBehavior: 'ignore'
}]
In Safari, a screenshot while an alert is open gets no answer, and the session stops
(WebKit bug 328310). Add the command that opens the alert to
excludedActions, for example click.
In a WebDriver BiDi session, use dialog events to handle alerts: the
reporter takes its screenshots without closing them.
Installation
Install ffmpegโ
The reporter makes the videos with ffmpeg. WebdriverIO does not install ffmpeg. Install it on each machine that runs the tests, also on the CI machines:
# macOS (Homebrew)
brew install ffmpeg
# Ubuntu, Debian
sudo apt-get update && sudo apt-get install -y ffmpeg
# Windows (winget or Chocolatey)
winget install --id Gyan.FFmpeg -e
choco install ffmpeg -y
For other systems, see ffmpeg.org/download.html. Then make sure that ffmpeg starts:
ffmpeg -version
The reporter uses the first of these that is set:
- the
ffmpegPathoption - the
FFMPEG_PATHenvironment variable ffmpegon thePATH(ffmpeg.exeon Windows)
When ffmpegPath or FFMPEG_PATH is set to a file that is not an executable, the reporter does not try the next one.
When it does not find ffmpeg, the reporter logs a warning and makes no video. The tests run as usual.
The default video format webm uses the VP9 encoder (libvpx-vp9). The mp4 format needs a ffmpeg with the H.264
encoder (libx264). The packages above have both. ffmpeg has its own license (LGPL or GPL, depending on the build):
you install it from your own source, under the license of that source.
In GitHub Actions, add a step before the tests:
- name: Install ffmpeg
shell: bash
run: |
if [ "$RUNNER_OS" = "Linux" ]; then sudo apt-get update && sudo apt-get install -y ffmpeg; fi
if [ "$RUNNER_OS" = "macOS" ]; then brew install ffmpeg; fi
if [ "$RUNNER_OS" = "Windows" ]; then choco install ffmpeg -y --no-progress; fi
In a Docker image based on Debian or Ubuntu, add RUN apt-get update && apt-get install -y ffmpeg.
Install the reporterโ
npm install @wdio/video-reporter --save-dev
Then add the reporter to your configuration:
reporters: [
['video', {
saveAllVideos: false, // If true, also saves videos for successful test cases
videoSlowdownMultiplier: 3, // Higher to get slower videos, lower for faster videos [Value 1-100]
}],
],
Usage
With Allure Reporterโ
Adding the Allure reporter as well automatically updates the reports with videos. Set
disableWebdriverScreenshotsReporting: true in the Allure options: each frame of the video is a WebDriver
screenshot, and without this option Allure attaches each frame to the test as a "Screenshot".
reporters: [
['video', {
saveAllVideos: false, // If true, also saves videos for successful test cases
videoSlowdownMultiplier: 3, // Higher to get slower videos, lower for faster videos [Value 1-100]
}],
['allure', {
outputDir: './_results_/allure-raw',
disableWebdriverStepsReporting: true,
disableWebdriverScreenshotsReporting: true,
}],
],
With wdio-html-nice-reporterโ
The HTML nice reporter adds the videos to its report without more configuration. Use the same outputDir for both
reporters:
reporters: [
['video', {
saveAllVideos: false, // If true, also saves videos for successful test cases
videoSlowdownMultiplier: 3, // Higher to get slower videos, lower for faster videos [Value 1-100]
outputDir: './reports/html-reports/',
}],
['html-nice', {
outputDir: './reports/html-reports/',
filename: 'report.html',
reportTitle: 'Test Report Title',
linkScreenshots: true,
// must be false to use the video
useOnAfterCommandForScreenshot: false,
}],
],
Configuration
Most users may want to set these configurations:
saveAllVideosโ
Set to true to save videos for passing tests.
Type: boolean
Default: false
rawPathโ
The folder for the screenshots of the videos (one folder for each test), in outputDir. It can also
be an absolute path. The reporter does not remove the screenshots, also of the tests that get no video.
Type: string
Default: .video-reporter-screenshots
filenamePrefixSourceโ
The start of the video file names. With test, the title of the test (with Cucumber, the name of the scenario).
With suite, the titles of the suites (describe blocks, with Cucumber also the name of the feature), without the
title of the test.
Type: 'suite' | 'test'
Default: test
videoSlowdownMultiplierโ
A number from 1 to 100, also with decimals (for example 1.5). Increase it if the videos play too fast.
Type: number
Default: 3
videoScaleโ
Scaling of video. See https://trac.ffmpeg.org/wiki/Scaling.
Type: string
Default: '1200:trunc(ow/a/2)*2'
videoRenderTimeoutโ
Maximum time to wait for a video to finish rendering (in ms). It is also the longest time for one screenshot: after it, the frame shows the "not available" image.
The runner waits for the reporters only reporterSyncTimeout
(default 5000). When you increase videoRenderTimeout, set reporterSyncTimeout to a larger value, else the worker can
end before the videos are rendered. The reporter logs a warning when videoRenderTimeout is larger.
Type: number
Default: 5000
outputDirโ
If it's not set, it uses outputDir. If that is not set
either, it uses _results_.
Type: string
Default: the WebdriverIO outputDir, else _results_
maxTestNameCharactersโ
The longest file name of a video, without the extension (the name also has the worker, the browser and the date). A
longer name keeps its start and its end, with -- between them.
Type: number
Default: 250
snapshotCommandsโ
Which commands should result in a screenshot: the last part of the WebDriver endpoint, for example click for
/session/:sessionId/element/:elementId/click. A GET command only reads the page, so it gives no screenshot (for
example getUrl for url, or getSize for rect), except with recordAllActions. In a WebDriver BiDi session,
url, back, forward, refresh and actions also stand for their WebDriver BiDi commands.
Type: string[]
Default: ['url', 'back', 'forward', 'refresh', 'sync', 'maximize', 'minimize', 'fullscreen', 'rect', 'click', 'value', 'clear', 'accept', 'dismiss', 'actions', 'orientation']
excludedActionsโ
Commands that give no screenshot, with the names of snapshotCommands. recordAllActions
ignores this option.
Type: string[]
Default: []
recordAllActionsโ
Take a screenshot after every command, also GET commands, and ignore snapshotCommands and excludedActions
(not recommended: it makes the tests slower).
Type: boolean
Default: false
screenshotIntervalSecsโ
Also take a screenshot at this interval (in seconds, minimum 0.5) while a test runs. 0 takes none.
Type: number
Default: 0
videoFormatโ
Video format (container) to be used. Supported formats: mp4, webm. For another value, the reporter logs a warning
and uses webm.
Type: 'webm' | 'mp4'
Default: webm
ffmpegPathโ
Path of the ffmpeg executable, or a command name that the reporter finds on the PATH. If it is not set, the
reporter uses the FFMPEG_PATH environment variable (the same values), then ffmpeg on the PATH. See Install ffmpeg.
Type: string
onlyRecordLastFailureโ
With specFileRetries, record only the last attempt of
a spec file. The attempts before it make no video.
Type: boolean
Default: false
Cucumber Supportโ
If you are using the Allure reporter with Cucumber, add useCucumberStepReporter: true to Allure option in wdio.conf.js file, a typical configuration would look like this:
reporters: [
['video', {
saveAllVideos: false, // If true, also saves videos for successful test cases
videoSlowdownMultiplier: 3, // Higher to get slower videos, lower for faster videos [Value 1-100]
}],
['allure', {
outputDir: './_results_/allure-raw',
disableWebdriverStepsReporting: true,
disableWebdriverScreenshotsReporting: true,
useCucumberStepReporter: true
}],
],
With cucumberOpts.scenarioLevelReporter: true, the reporter also makes one video for each scenario.
Appium Supportโ
When the capabilities have no browserName, the reporter uses the device name that the Appium session returns and
platformName in the video file names, for example IPHONE17-IOS. UiAutomator2 returns the device id, for example
EMULATOR-5554-ANDROID. With Allure, it also adds deviceName and browserVersion as arguments of the test.
capabilities: [{
platformName: 'Android',
'appium:deviceName': 'Pixel 7',
'appium:automationName': 'UiAutomator2',
// ...
}],
Example
The video reporter e2e test of this repository uses the video and the Allure reporters.
Older WebdriverIO Versions
This package supports WebdriverIO v10 and later. For WebdriverIO v9, use the community package
wdio-video-reporter. That package installs ffmpeg
itself; this one uses the ffmpeg that you install. To move from that package to this one, see the
v10 migration guide.
Thanks
Thanks to Johnson E for fixing Cucumber support which a lot of users have asked for.