Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8b2be7a
Update CHANGELOG.md
AB-xdev Feb 24, 2026
b4e85c5
Merge pull request #259 from xdev-software/master
AB-xdev Feb 24, 2026
bd6498d
Update lycheeverse/lychee-action digest to 8646ba3
xdev-renovate Feb 26, 2026
8b6624e
Update lycheeverse/lychee-action digest to 8646ba3
xdev-renovate Feb 26, 2026
a53730b
Update actions/upload-artifact action to v7
xdev-renovate Feb 27, 2026
0dd98aa
Update actions/upload-artifact action to v7
xdev-renovate Feb 27, 2026
0dcf9cf
Update dependency com.puppycrawl.tools:checkstyle to v13.3.0
xdev-renovate Mar 1, 2026
77e37f9
Update dependency net.sourceforge.pmd:pmd-core to v7.22.0 [SECURITY]
xdev-renovate Mar 2, 2026
961291c
Update dependency net.sourceforge.pmd:pmd-java to v7.22.0
xdev-renovate Mar 2, 2026
116c98b
Merge pull request #254 from xdev-software/renovate/com.puppycrawl.to…
AB-xdev Mar 2, 2026
1502f77
Merge pull request #252 from xdev-software/renovate/actions-upload-ar…
AB-xdev Mar 2, 2026
f3b4dc8
Merge pull request #251 from xdev-software/renovate/lycheeverse-lyche…
AB-xdev Mar 2, 2026
7c63532
Merge pull request #253 from xdev-software/renovate/net.sourceforge.pmd
AB-xdev Mar 2, 2026
4a8ede9
Merge pull request #255 from xdev-software/renovate/maven-net.sourcef…
AB-xdev Mar 2, 2026
a06462c
Merge pull request #12 from xdev-software/renovate/lycheeverse-lychee…
AB-xdev Mar 2, 2026
6f9b5b3
Create report-gha-workflow-security-problems.yml
AB-xdev Mar 2, 2026
1fa1c4e
Merge branch 'master' into update-from-template-xdev-software/base-te…
xdev-gh-bot Mar 2, 2026
b24ea85
Merge branch 'master' into update-from-template-xdev-software/java-te…
xdev-gh-bot Mar 2, 2026
38929be
Merge remote-tracking branch 'origin/update-from-template' into develop
AB-xdev Mar 5, 2026
832f375
Merge pull request #261 from xdev-software/renovate/actions-upload-ar…
AB-xdev Mar 5, 2026
49e1e42
Change default format to `.mkv` and fixate version
AB-xdev Mar 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/broken-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

- name: Link Checker
id: lychee
uses: lycheeverse/lychee-action@a8c4c7cb88f0c7386610c35eb25108e448569cb0 # v2
uses: lycheeverse/lychee-action@8646ba30535128ac92d33dfc9133794bfdd9b411 # v2
with:
fail: false # Don't fail on broken links, create an issue instead

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/check-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:

- name: Upload report
if: always()
uses: actions/upload-artifact@v6
uses: actions/upload-artifact@v7
with:
name: pmd-report
if-no-files-found: ignore
Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/report-gha-workflow-security-problems.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Report workflow security problems

on:
workflow_dispatch:
push:
branches: [ develop ]
paths:
- '.github/workflows/**'

permissions:
issues: write

jobs:
prt:
runs-on: ubuntu-latest
timeout-minutes: 15
# Only run this in our repos (Prevent notification spam by forks)
if: ${{ github.repository_owner == 'xdev-software' }}
steps:
- uses: actions/checkout@v6

- name: Check
id: check
run: |
grep -l 'pull_request_target:' --exclude report-gha-workflow-security-problems.yml *.yml > reported.txt && exit 1 || exit 0
working-directory: .github/workflows

- name: Find already existing issue
id: find-issue
if: ${{ !cancelled() }}
run: |
echo "number=$(gh issue list -l 'bug' -l 'automated' -L 1 -S 'in:title "Incorrectly configure GHA workflow (prt)"' -s 'open' --json 'number' --jq '.[].number')" >> $GITHUB_OUTPUT
env:
GH_TOKEN: ${{ github.token }}

- name: Close issue if everything is fine
if: ${{ success() && steps.find-issue.outputs.number != '' }}
run: gh issue close -r 'not planned' ${{ steps.find-issue.outputs.number }}
env:
GH_TOKEN: ${{ github.token }}

- name: Create report
if: ${{ failure() && steps.check.conclusion == 'failure' }}
run: |
echo 'Detected usage of `pull_request_target`. This event is dangerous and MUST NOT BE USED AT ALL COST!' > reported.md
echo '' >> reported.md
echo '/cc @xdev-software/gha-workflow-security' >> reported.md
echo '' >> reported.md
echo '```' >> reported.md
cat .github/workflows/reported.txt >> reported.md
echo '```' >> reported.md
cat reported.md

- name: Create Issue From File
if: ${{ failure() && steps.check.conclusion == 'failure' }}
uses: peter-evans/create-issue-from-file@fca9117c27cdc29c6c4db3b86c48e4115a786710 # v6
with:
issue-number: ${{ steps.find-issue.outputs.number }}
title: 'Incorrectly configure GHA workflow (prt)'
content-filepath: ./reported.md
labels: bug, automated
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 2.0.0
_Major version bump due to default video container format change_
* Pinned recorder container to `selenium/video:ffmpeg-8.0-20260202` because the currently latest version of the container is not shutting down properly
* Changed default video container format to `mkv`
* This format allows to play the videos even when they are incomplete
* Update default Selenium version to `4.41.0`
* Updated dependencies

# 1.5.3
* Improve error message when browser name can't be matched
* Updated dependencies

# 1.5.2
* Updated dependencies

Expand Down
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A re-implementation of [Testcontainer Selenium/WebDriver](https://java.testconta
* No VNC Server started in the browser container (unless explicitly stated) → Saves memory
* Uses [Selenium's implementation](https://github.com/SeleniumHQ/docker-selenium/tree/trunk/Video) and isn't [based](https://github.com/testcontainers/vnc-recorder) on [some python code from 2010](https://pypi.org/project/vnc2flv/#history)
* Way more customization options for e.g. ``framerate``, ``codec``, ``preset`` ...
* Uses ``mp4`` as default recording format (wider support in comparison to ``flv``)
* Uses ``mkv`` as default recording format (wider support in comparison to ``flv``)
* [Renders while saving the video](https://github.com/SeleniumHQ/docker-selenium/blob/4c572afd1173b5bd49fa2def3b54ea552fccee85/Video/video.sh#L126) (not when finished which takes additional time)
* Stops the recorder before saving the file so that there is no way that [it runs forever](https://github.com/testcontainers/testcontainers-java/discussions/6229).
* Automatically tries to select a alternative Selenium version for the docker image if it [doesn't exist](https://github.com/SeleniumHQ/docker-selenium/issues/1979).
Expand All @@ -25,6 +25,13 @@ Usage is very similar to [Testcontainers default implementation](https://java.te
Make sure to remove the original Testcontainer Webdrivers dependency to avert any mix ups while using the library.
For more information take a look at [our demo](./testcontainers-selenium-demo/src/main/java/software/xdev/Application.java).

### Why are videos recorded as `.mkv` and how can I open them?

In version 2 `.mp4` was replaced with `.mkv` as the default video container format.<br/>
This was done because `.mp4` requires finalization as otherwise the file/container will be consider corrupt. `.mkv` has no such problems.

[Most video players](https://en.wikipedia.org/wiki/Matroska#Support) (including browsers) can play `.mkv` files out of the box.

## Installation
[Installation guide for the latest release](https://github.com/xdev-software/testcontainers-selenium/releases/latest#Installation)

Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>software.xdev</groupId>
<artifactId>testcontainers-selenium-root</artifactId>
<version>1.5.4-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>pom</packaging>

<organization>
Expand Down Expand Up @@ -45,7 +45,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>13.2.0</version>
<version>13.3.0</version>
</dependency>
</dependencies>
<configuration>
Expand Down Expand Up @@ -83,12 +83,12 @@
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-core</artifactId>
<version>7.21.0</version>
<version>7.22.0</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-java</artifactId>
<version>7.21.0</version>
<version>7.22.0</version>
</dependency>
</dependencies>
</plugin>
Expand Down
4 changes: 2 additions & 2 deletions testcontainers-selenium-demo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
<parent>
<groupId>software.xdev</groupId>
<artifactId>testcontainers-selenium-root</artifactId>
<version>1.5.4-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
</parent>

<artifactId>testcontainers-selenium-demo</artifactId>
<version>1.5.4-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<organization>
Expand Down
8 changes: 4 additions & 4 deletions testcontainers-selenium/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>software.xdev</groupId>
<artifactId>testcontainers-selenium</artifactId>
<version>1.5.4-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>jar</packaging>

<name>testcontainers-selenium</name>
Expand Down Expand Up @@ -320,7 +320,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>13.2.0</version>
<version>13.3.0</version>
</dependency>
</dependencies>
<configuration>
Expand Down Expand Up @@ -358,12 +358,12 @@
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-core</artifactId>
<version>7.21.0</version>
<version>7.22.0</version>
</dependency>
<dependency>
<groupId>net.sourceforge.pmd</groupId>
<artifactId>pmd-java</artifactId>
<version>7.21.0</version>
<version>7.22.0</version>
</dependency>
</dependencies>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public final class SeleniumUtils
private static final Logger LOG = LoggerFactory.getLogger(SeleniumUtils.class);

// as of 2026-01
public static final String DEFAULT_SELENIUM_VERSION = "4.40.0";
public static final String DEFAULT_SELENIUM_VERSION = "4.41.0";
private static String cachedVersion;

private SeleniumUtils()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
@SuppressWarnings("java:S2160")
public class SeleniumRecordingContainer extends RecordingContainer<SeleniumRecordingContainer>
{
public static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("selenium/video");
public static final DockerImageName DEFAULT_IMAGE =
// Workaround https://github.com/SeleniumHQ/docker-selenium/issues/3093
// As of 2026-03 the latest version of the container is not shutting down properly
DockerImageName.parse("selenium/video:ffmpeg-8.0-20260202");

// https://github.com/SeleniumHQ/docker-selenium/blob/033f77c02dde9d61d1a4d44be7526ef689244606/Video/Dockerfile#L103-L110
public static final String ENV_DISPLAY_CONTAINER_NAME = "DISPLAY_CONTAINER_NAME";
Expand All @@ -47,7 +50,7 @@ public class SeleniumRecordingContainer extends RecordingContainer<SeleniumRecor
protected String displayContainerName;
protected String videoFileName;
protected boolean resolutionConfigured;
protected String fileExtension = "mp4";
protected String fileExtension = "mkv";

public SeleniumRecordingContainer(final BrowserWebDriverContainer<?> target)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public String getFilesystemFriendlyName()
final String recordedFileName = recorded.getFileName().toString();

Assertions.assertAll(
() -> Assertions.assertTrue(recordedFileName.endsWith(".mp4")),
() -> Assertions.assertTrue(recordedFileName.endsWith(".mkv")),
() -> Assertions.assertTrue(recordedFileName.startsWith("PASSED-")),
() -> Assertions.assertTrue(Files.size(recorded) > 0));
}
Expand Down