Skip to content

Commit 081d9c8

Browse files
Selenium
1 parent 46552e1 commit 081d9c8

File tree

3 files changed

+62
-99
lines changed

3 files changed

+62
-99
lines changed

docs/modules/selenium.md

Lines changed: 18 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
# Selenium Module
2-
3-
[Selenium](https://www.selenium.dev/) If you want to create robust, browser-based regression automation suites and tests, scale and
4-
distribute scripts across many environments, then you want to use Selenium WebDriver, a
5-
collection of language specific bindings to drive a browser - the way it is meant to be driven.
1+
# Selenium
62

73
## Install
84

@@ -12,69 +8,28 @@ npm install @testcontainers/selenium --save-dev
128

139
## Examples
1410

15-
Spin up a Chrome web browser and navigate to a URL:
16-
17-
```js
18-
const { SeleniumContainer } = require("@testcontainers/selenium");
19-
20-
const container = await new SeleniumContainer("selenium/standalone-chrome:112.0")
21-
.start();
22-
23-
const driver = await new Builder()
24-
.forBrowser(Browser.CHROME)
25-
.usingServer(container.getServerUrl())
26-
.build();
27-
28-
await driver.get("https://testcontainers.com");
29-
await driver.quit();
30-
```
31-
32-
You can use any Selenium supported web browser by providing the appropriate image and driver configuration, for example:
33-
34-
```js
35-
const container = await new SeleniumContainer("selenium/standalone-edge:112.0")
36-
.start();
11+
These examples use the following libraries:
3712

38-
const driver = await new Builder()
39-
.forBrowser(Browser.EDGE)
40-
...
41-
.build();
42-
```
43-
44-
A video recording of the browser session can be enabled and saved to disk once the container has been stopped:
45-
46-
```js
47-
const container = await new SeleniumContainer("selenium/standalone-chrome:112.0")
48-
.withRecording()
49-
.start();
50-
...
51-
52-
const stoppedContainer = await container.stop();
53-
await stoppedContainer.saveRecording("/tmp/videos/recording.mp4");
54-
```
55-
56-
## Troubleshooting
13+
- [selenium-webdriver](https://www.npmjs.com/package/selenium-webdriver)
5714

58-
### ARM architecture
15+
npm install selenium-webdriver
16+
npm install @types/selenium-webdriver --save-dev
5917

60-
Selenium images are not available for ARM architectures. Luckily, there are equivalent, ARM compatible images available via [Seleniarm](https://hub.docker.com/u/seleniarm):
18+
Choose an image from the container registry and substitute `IMAGE`:
6119

62-
```
63-
seleniarm/standalone-chromium:112.0
64-
seleniarm/standalone-firefox:112.0
65-
```
20+
- [AMD Standalone Chrome](https://hub.docker.com/r/selenium/standalone-chrome)
21+
- [AMD Standalone Firefox](https://hub.docker.com/r/selenium/standalone-firefox)
22+
- [ARM Standalone Chromium](https://hub.docker.com/r/seleniarm/standalone-chromium)
23+
- [ARM Standalone Firefox](https://hub.docker.com/r/seleniarm/standalone-firefox)
6624

67-
```js
68-
const { SeleniumContainer } = require("@testcontainers/selenium");
25+
### Navigate to a page
6926

70-
const container = await new SeleniumContainer("seleniarm/standalone-chromium:112.0")
71-
.start();
27+
<!--codeinclude-->
28+
[](../../packages/modules/selenium/src/selenium-container.test.ts) inside_block:seleniumExample
29+
<!--/codeinclude-->
7230

73-
const driver = await new Builder()
74-
.forBrowser(Browser.CHROME)
75-
.usingServer(container.getServerUrl())
76-
.build();
31+
### Record a video
7732

78-
await driver.get("https://testcontainers.com");
79-
await driver.quit();
80-
```
33+
<!--codeinclude-->
34+
[](../../packages/modules/selenium/src/selenium-container.test.ts) inside_block:seleniumVideoExample
35+
<!--/codeinclude-->
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
1-
FROM selenium/standalone-chrome:138.0
1+
FROM selenium/standalone-chrome:112.0
2+
FROM seleniarm/standalone-chromium:112.0
3+
FROM selenium/standalone-firefox:112.0
4+
FROM seleniarm/standalone-firefox:112.0

packages/modules/selenium/src/selenium-container.test.ts

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,47 @@ import path from "path";
22
import { Browser, Builder } from "selenium-webdriver";
33
import { GenericContainer } from "testcontainers";
44
import tmp from "tmp";
5+
import { getImage } from "../../../testcontainers/src/utils/test-helper";
56
import { SELENIUM_VIDEO_IMAGE, SeleniumContainer } from "./selenium-container";
67

7-
describe("SeleniumContainer", { timeout: 180_000 }, () => {
8-
const browsers = [
9-
["CHROME", process.arch === "arm64" ? `seleniarm/standalone-chromium:112.0` : `selenium/standalone-chrome:112.0`],
10-
["FIREFOX", process.arch === "arm64" ? `seleniarm/standalone-firefox:112.0` : `selenium/standalone-firefox:112.0`],
11-
] as const;
12-
13-
browsers.forEach(async ([browser, image]) => {
14-
it(`should work for ${browser}`, async () => {
15-
await using container = await new SeleniumContainer(image).start();
16-
const driver = await new Builder().forBrowser(Browser[browser]).usingServer(container.getServerUrl()).build();
17-
18-
await driver.get("https://testcontainers.com");
19-
expect(await driver.getTitle()).toEqual("Testcontainers");
20-
21-
await driver.quit();
22-
});
23-
24-
it(`should record video and save to disk for ${browser}`, async () => {
25-
const container = await new SeleniumContainer(image).withRecording().start();
26-
const driver = await new Builder().forBrowser(Browser[browser]).usingServer(container.getServerUrl()).build();
27-
await driver.get("https://testcontainers.com");
28-
await driver.quit();
29-
const stoppedContainer = await container.stop();
30-
31-
const videoFilePath = tmp.fileSync({ keep: false, prefix: `video-${browser}`, postfix: ".mp4" }).name;
32-
const videoFileName = path.basename(videoFilePath);
33-
await stoppedContainer.saveRecording(videoFilePath);
34-
35-
await using ffmpegContainer = await new GenericContainer(SELENIUM_VIDEO_IMAGE)
36-
.withCommand(["sleep", "infinity"])
37-
.start();
38-
await ffmpegContainer.copyFilesToContainer([{ source: videoFilePath, target: `/tmp/${videoFileName}` }]);
39-
const { exitCode } = await ffmpegContainer.exec(["ffprobe", `/tmp/${videoFileName}`]);
40-
expect(exitCode).toBe(0);
41-
});
8+
const browsers = [
9+
["CHROME", process.arch === "arm64" ? getImage(__dirname, 1) : getImage(__dirname, 0)],
10+
["FIREFOX", process.arch === "arm64" ? getImage(__dirname, 3) : getImage(__dirname, 2)],
11+
] as const;
12+
13+
describe.for(browsers)("SeleniumContainer", { timeout: 30_000 }, ([browser, image]) => {
14+
it(`should work for ${browser}`, async () => {
15+
// seleniumExample {
16+
await using container = await new SeleniumContainer(image).start();
17+
18+
const driver = await new Builder().forBrowser(Browser[browser]).usingServer(container.getServerUrl()).build();
19+
await driver.get("https://testcontainers.com");
20+
expect(await driver.getTitle()).toEqual("Testcontainers");
21+
22+
await driver.quit();
23+
// }
24+
});
25+
26+
it(`should record video and save to disk for ${browser}`, async () => {
27+
// seleniumVideoExample {
28+
const container = await new SeleniumContainer(image).withRecording().start();
29+
30+
const driver = await new Builder().forBrowser(Browser[browser]).usingServer(container.getServerUrl()).build();
31+
await driver.get("https://testcontainers.com");
32+
33+
await driver.quit();
34+
const stoppedContainer = await container.stop();
35+
36+
const videoFilePath = tmp.fileSync({ keep: false, prefix: `video-${browser}`, postfix: ".mp4" }).name;
37+
const videoFileName = path.basename(videoFilePath);
38+
await stoppedContainer.saveRecording(videoFilePath);
39+
40+
await using ffmpegContainer = await new GenericContainer(SELENIUM_VIDEO_IMAGE)
41+
.withCommand(["sleep", "infinity"])
42+
.start();
43+
await ffmpegContainer.copyFilesToContainer([{ source: videoFilePath, target: `/tmp/${videoFileName}` }]);
44+
const { exitCode } = await ffmpegContainer.exec(["ffprobe", `/tmp/${videoFileName}`]);
45+
expect(exitCode).toBe(0);
46+
// }
4247
});
4348
});

0 commit comments

Comments
 (0)