diff --git a/.github/workflows/broken-links.yml b/.github/workflows/broken-links.yml
index 2675c8b..5b50d06 100644
--- a/.github/workflows/broken-links.yml
+++ b/.github/workflows/broken-links.yml
@@ -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
diff --git a/.github/workflows/check-build.yml b/.github/workflows/check-build.yml
index 0763305..7ba6049 100644
--- a/.github/workflows/check-build.yml
+++ b/.github/workflows/check-build.yml
@@ -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
diff --git a/.github/workflows/report-gha-workflow-security-problems.yml b/.github/workflows/report-gha-workflow-security-problems.yml
new file mode 100644
index 0000000..b17aa53
--- /dev/null
+++ b/.github/workflows/report-gha-workflow-security-problems.yml
@@ -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
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b8c9ef9..4ad8d9e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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
diff --git a/README.md b/README.md
index fde3770..900c6f7 100644
--- a/README.md
+++ b/README.md
@@ -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).
@@ -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.
+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)
diff --git a/pom.xml b/pom.xml
index 1c9e9dd..c5c37df 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
software.xdev
testcontainers-selenium-root
- 1.5.4-SNAPSHOT
+ 2.0.0-SNAPSHOT
pom
@@ -45,7 +45,7 @@
com.puppycrawl.tools
checkstyle
- 13.2.0
+ 13.3.0
@@ -83,12 +83,12 @@
net.sourceforge.pmd
pmd-core
- 7.21.0
+ 7.22.0
net.sourceforge.pmd
pmd-java
- 7.21.0
+ 7.22.0
diff --git a/testcontainers-selenium-demo/pom.xml b/testcontainers-selenium-demo/pom.xml
index 277ef93..131cc91 100644
--- a/testcontainers-selenium-demo/pom.xml
+++ b/testcontainers-selenium-demo/pom.xml
@@ -7,11 +7,11 @@
software.xdev
testcontainers-selenium-root
- 1.5.4-SNAPSHOT
+ 2.0.0-SNAPSHOT
testcontainers-selenium-demo
- 1.5.4-SNAPSHOT
+ 2.0.0-SNAPSHOT
jar
diff --git a/testcontainers-selenium/pom.xml b/testcontainers-selenium/pom.xml
index a819ab2..8499fe8 100644
--- a/testcontainers-selenium/pom.xml
+++ b/testcontainers-selenium/pom.xml
@@ -6,7 +6,7 @@
software.xdev
testcontainers-selenium
- 1.5.4-SNAPSHOT
+ 2.0.0-SNAPSHOT
jar
testcontainers-selenium
@@ -320,7 +320,7 @@
com.puppycrawl.tools
checkstyle
- 13.2.0
+ 13.3.0
@@ -358,12 +358,12 @@
net.sourceforge.pmd
pmd-core
- 7.21.0
+ 7.22.0
net.sourceforge.pmd
pmd-java
- 7.21.0
+ 7.22.0
diff --git a/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/browser/SeleniumUtils.java b/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/browser/SeleniumUtils.java
index 29cf665..376c8f7 100644
--- a/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/browser/SeleniumUtils.java
+++ b/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/browser/SeleniumUtils.java
@@ -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()
diff --git a/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/recorder/SeleniumRecordingContainer.java b/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/recorder/SeleniumRecordingContainer.java
index d13e116..a3d8732 100644
--- a/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/recorder/SeleniumRecordingContainer.java
+++ b/testcontainers-selenium/src/main/java/software/xdev/testcontainers/selenium/containers/recorder/SeleniumRecordingContainer.java
@@ -31,7 +31,10 @@
@SuppressWarnings("java:S2160")
public class SeleniumRecordingContainer extends RecordingContainer
{
- 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";
@@ -47,7 +50,7 @@ public class SeleniumRecordingContainer extends RecordingContainer target)
{
diff --git a/testcontainers-selenium/src/test/java/software/xdev/testcontainers/selenium/SimpleContainerTest.java b/testcontainers-selenium/src/test/java/software/xdev/testcontainers/selenium/SimpleContainerTest.java
index 56eabd7..726144a 100644
--- a/testcontainers-selenium/src/test/java/software/xdev/testcontainers/selenium/SimpleContainerTest.java
+++ b/testcontainers-selenium/src/test/java/software/xdev/testcontainers/selenium/SimpleContainerTest.java
@@ -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));
}