testcontainers 9.8.0 → 9.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +1 -1
  2. package/dist/package.json +7 -3
  3. package/dist/src/docker/client/docker-client-config.d.ts +2 -4
  4. package/dist/src/docker/client/docker-client-config.js +5 -2
  5. package/dist/src/docker/client/docker-client.js +39 -27
  6. package/dist/src/docker/functions/container/create-container.d.ts +1 -0
  7. package/dist/src/docker/functions/container/create-container.js +1 -0
  8. package/dist/src/docker/functions/container/get-container-archive.d.ts +10 -0
  9. package/dist/src/docker/functions/container/get-container-archive.js +23 -0
  10. package/dist/src/generic-container/generic-container.d.ts +1 -0
  11. package/dist/src/generic-container/generic-container.js +4 -0
  12. package/dist/src/generic-container/started-generic-container.d.ts +6 -2
  13. package/dist/src/generic-container/started-generic-container.js +41 -6
  14. package/dist/src/generic-container/stopped-generic-container.d.ts +6 -0
  15. package/dist/src/generic-container/stopped-generic-container.js +14 -0
  16. package/dist/src/images.js +1 -1
  17. package/dist/src/index.d.ts +2 -0
  18. package/dist/src/index.js +10 -1
  19. package/dist/src/modules/abstract-started-container.d.ts +6 -2
  20. package/dist/src/modules/abstract-started-container.js +13 -0
  21. package/dist/src/modules/abstract-stopped-container.d.ts +8 -0
  22. package/dist/src/modules/abstract-stopped-container.js +15 -0
  23. package/dist/src/modules/kafka/kafka-container.js +6 -1
  24. package/dist/src/modules/mysql/mysql-container.d.ts +1 -0
  25. package/dist/src/modules/mysql/mysql-container.js +9 -0
  26. package/dist/src/modules/selenium/selenium-container.d.ts +38 -0
  27. package/dist/src/modules/selenium/selenium-container.js +158 -0
  28. package/dist/src/test-container.d.ts +10 -2
  29. package/package.json +7 -3
package/README.md CHANGED
@@ -24,4 +24,4 @@ See [contributors](https://github.com/testcontainers/testcontainers-node/graphs/
24
24
 
25
25
  ----
26
26
 
27
- Join our [Slack workspace](https://slack.testcontainers.org/) | [Testcontainers OSS](https://www.testcontainers.org/) | [Testcontainers Cloud](https://www.testcontainers.cloud/)
27
+ Join our [Slack workspace](https://slack.testcontainers.org/) | [Testcontainers OSS](https://java.testcontainers.org/) | [Testcontainers Cloud](https://www.testcontainers.cloud/)
package/dist/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "testcontainers",
3
3
  "author": "Cristian Greco",
4
- "version": "9.8.0",
4
+ "version": "9.9.0",
5
5
  "main": "dist/src/index",
6
6
  "types": "dist/src/index",
7
7
  "keywords": [
@@ -43,13 +43,14 @@
43
43
  "async-lock": "^1.4.0",
44
44
  "byline": "^5.0.0",
45
45
  "debug": "^4.3.4",
46
- "docker-compose": "^0.23.19",
46
+ "docker-compose": "^0.24.1",
47
47
  "dockerode": "^3.3.5",
48
48
  "get-port": "^5.1.1",
49
49
  "node-fetch": "^2.6.9",
50
50
  "properties-reader": "^2.2.0",
51
51
  "ssh-remote-port-forward": "^1.0.4",
52
- "tar-fs": "^2.1.1"
52
+ "tar-fs": "^2.1.1",
53
+ "tmp": "^0.2.1"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@elastic/elasticsearch": "^7.17.0",
@@ -61,7 +62,9 @@
61
62
  "@types/node-fetch": "^2.6.3",
62
63
  "@types/pg": "^8.6.6",
63
64
  "@types/properties-reader": "^2.1.1",
65
+ "@types/selenium-webdriver": "^4.1.14",
64
66
  "@types/tar-fs": "^2.0.1",
67
+ "@types/tmp": "^0.2.3",
65
68
  "@typescript-eslint/eslint-plugin": "^5.59.1",
66
69
  "@typescript-eslint/parser": "^5.59.1",
67
70
  "arangojs": "^8.2.1",
@@ -80,6 +83,7 @@
80
83
  "pg": "^8.10.0",
81
84
  "prettier": "^2.8.8",
82
85
  "rimraf": "^3.0.2",
86
+ "selenium-webdriver": "^4.9.2",
83
87
  "ts-jest": "^29.1.0",
84
88
  "ts-node": "^10.9.1",
85
89
  "typescript": "^4.9.5",
@@ -1,11 +1,9 @@
1
1
  /// <reference types="node" />
2
- /// <reference types="node" />
3
- /// <reference types="node" />
4
- /// <reference types="node" />
5
2
  export type DockerClientConfig = {
6
3
  tcHost?: string;
7
4
  dockerHost?: string;
8
5
  dockerTlsVerify?: string;
9
6
  dockerCertPath?: string;
10
7
  };
11
- export declare const getDockerClientConfig: (env?: NodeJS.ProcessEnv) => Promise<DockerClientConfig>;
8
+ export type GetDockerClientConfig = (env?: NodeJS.ProcessEnv) => Promise<DockerClientConfig>;
9
+ export declare const getDockerClientConfig: GetDockerClientConfig;
@@ -19,9 +19,12 @@ const os_1 = require("os");
19
19
  const fs_1 = require("fs");
20
20
  const promises_1 = require("fs/promises");
21
21
  const properties_reader_1 = __importDefault(require("properties-reader"));
22
+ let dockerClientConfig;
22
23
  const getDockerClientConfig = (env = process.env) => __awaiter(void 0, void 0, void 0, function* () {
23
- const dockerClientConfig = Object.assign(Object.assign({}, (yield loadFromFile())), loadFromEnv(env));
24
- logDockerClientConfig(dockerClientConfig);
24
+ if (!dockerClientConfig) {
25
+ dockerClientConfig = Object.assign(Object.assign({}, (yield loadFromFile())), loadFromEnv(env));
26
+ logDockerClientConfig(dockerClientConfig);
27
+ }
25
28
  return dockerClientConfig;
26
29
  });
27
30
  exports.getDockerClientConfig = getDockerClientConfig;
@@ -35,40 +35,52 @@ function getDockerClient() {
35
35
  new npipe_socket_strategy_1.NpipeSocketStrategy(),
36
36
  ];
37
37
  for (const strategy of strategies) {
38
- if (strategy.init) {
39
- yield strategy.init();
40
- }
41
- if (strategy.isApplicable()) {
42
- logger_1.log.debug(`Found Docker client strategy "${strategy.getName()}"`);
43
- const { uri, dockerode, composeEnvironment, allowUserOverrides } = yield strategy.getDockerClient();
44
- logger_1.log.debug(`Testing Docker client strategy "${uri}"...`);
45
- if (yield isDockerDaemonReachable(dockerode)) {
46
- const info = yield (0, system_info_1.getSystemInfo)(dockerode);
47
- const containerRuntime = uri.includes("podman.sock") ? "podman" : "docker";
48
- const host = yield (0, resolve_host_1.resolveHost)(dockerode, containerRuntime, info.dockerInfo.indexServerAddress, uri, allowUserOverrides);
49
- const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
50
- dockerClient = {
51
- uri,
52
- containerRuntime,
53
- host,
54
- hostIps,
55
- dockerode,
56
- info,
57
- composeEnvironment,
58
- allowUserOverrides,
59
- };
38
+ try {
39
+ const dockerClient = yield tryToCreateDockerClient(strategy);
40
+ if (dockerClient) {
60
41
  logDockerClient(strategy.getName(), dockerClient);
61
42
  return dockerClient;
62
43
  }
63
- else {
64
- logger_1.log.warn(`Docker client strategy "${strategy.getName()}" is not working`);
65
- }
44
+ }
45
+ catch (err) {
46
+ logger_1.log.warn(`Docker client strategy "${strategy.getName()}" threw: "${err}"`);
66
47
  }
67
48
  }
68
49
  throw new Error("No Docker client strategy found");
69
50
  });
70
51
  }
71
52
  exports.getDockerClient = getDockerClient;
53
+ function tryToCreateDockerClient(strategy) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ if (strategy.init) {
56
+ yield strategy.init();
57
+ }
58
+ if (strategy.isApplicable()) {
59
+ const { uri, dockerode, composeEnvironment, allowUserOverrides } = yield strategy.getDockerClient();
60
+ logger_1.log.debug(`Testing Docker client strategy "${strategy.getName()}" with URI "${uri}"...`);
61
+ if (yield isDockerDaemonReachable(dockerode)) {
62
+ const info = yield (0, system_info_1.getSystemInfo)(dockerode);
63
+ const containerRuntime = uri.includes("podman.sock") ? "podman" : "docker";
64
+ const host = yield (0, resolve_host_1.resolveHost)(dockerode, containerRuntime, info.dockerInfo.indexServerAddress, uri, allowUserOverrides);
65
+ const hostIps = yield (0, lookup_host_ips_1.lookupHostIps)(host);
66
+ dockerClient = {
67
+ uri,
68
+ containerRuntime,
69
+ host,
70
+ hostIps,
71
+ dockerode,
72
+ info,
73
+ composeEnvironment,
74
+ allowUserOverrides,
75
+ };
76
+ return dockerClient;
77
+ }
78
+ else {
79
+ logger_1.log.warn(`Docker client strategy "${strategy.getName()}" does not work`);
80
+ }
81
+ }
82
+ });
83
+ }
72
84
  function isDockerDaemonReachable(dockerode) {
73
85
  return __awaiter(this, void 0, void 0, function* () {
74
86
  try {
@@ -76,7 +88,7 @@ function isDockerDaemonReachable(dockerode) {
76
88
  return (yield (0, stream_utils_1.streamToString)(stream_1.Readable.from(response))) === "OK";
77
89
  }
78
90
  catch (err) {
79
- logger_1.log.warn(`Docker daemon is not reachable: ${err}`);
91
+ logger_1.log.warn(`Docker daemon is not reachable: "${err}"`);
80
92
  return false;
81
93
  }
82
94
  });
@@ -86,5 +98,5 @@ function logDockerClient(strategyName, { host, hostIps }) {
86
98
  return;
87
99
  }
88
100
  const formattedHostIps = hostIps.map((hostIp) => hostIp.address).join(", ");
89
- logger_1.log.info(`Using Docker client strategy "${strategyName}", Docker host "${host}" (${formattedHostIps})`);
101
+ logger_1.log.info(`Docker client strategy "${strategyName}" works, ${host} (${formattedHostIps})`);
90
102
  }
@@ -26,5 +26,6 @@ export type CreateContainerOptions = {
26
26
  user?: string;
27
27
  workingDir?: string;
28
28
  resourcesQuota?: ResourcesQuota;
29
+ sharedMemorySize?: number;
29
30
  };
30
31
  export declare const createContainer: (options: CreateContainerOptions) => Promise<Dockerode.Container>;
@@ -45,6 +45,7 @@ const createContainer = (options) => __awaiter(void 0, void 0, void 0, function*
45
45
  CapDrop: options.droppedCapabilities,
46
46
  Memory: (_a = options.resourcesQuota) === null || _a === void 0 ? void 0 : _a.memory,
47
47
  NanoCpus: (_b = options.resourcesQuota) === null || _b === void 0 ? void 0 : _b.cpu,
48
+ ShmSize: options.sharedMemorySize,
48
49
  },
49
50
  });
50
51
  logger_1.log.info(`Created container for image "${options.imageName}"`, { containerId: container.id });
@@ -0,0 +1,10 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import Dockerode from "dockerode";
6
+ export type GetContainerArchiveOptions = {
7
+ container: Dockerode.Container;
8
+ path: string;
9
+ };
10
+ export declare const getContainerArchive: (options: GetContainerArchiveOptions) => Promise<NodeJS.ReadableStream>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getContainerArchive = void 0;
13
+ const logger_1 = require("../../../logger");
14
+ const getContainerArchive = (options) => __awaiter(void 0, void 0, void 0, function* () {
15
+ try {
16
+ return yield options.container.getArchive({ path: options.path });
17
+ }
18
+ catch (err) {
19
+ logger_1.log.error(`Failed to get archive from container: ${err}`, { containerId: options.container.id });
20
+ throw err;
21
+ }
22
+ });
23
+ exports.getContainerArchive = getContainerArchive;
@@ -68,5 +68,6 @@ export declare class GenericContainer implements TestContainer {
68
68
  protected getTarToCopy(): archiver.Archiver;
69
69
  withWorkingDir(workingDir: string): this;
70
70
  withResourcesQuota({ memory, cpu }: ResourcesQuota): this;
71
+ withSharedMemorySize(bytes: number): this;
71
72
  withLogConsumer(logConsumer: (stream: Readable) => unknown): this;
72
73
  }
@@ -314,6 +314,10 @@ class GenericContainer {
314
314
  this.opts.resourcesQuota = { memory: ram, cpu: cpuQuota };
315
315
  return this;
316
316
  }
317
+ withSharedMemorySize(bytes) {
318
+ this.opts.sharedMemorySize = bytes;
319
+ return this;
320
+ }
317
321
  withLogConsumer(logConsumer) {
318
322
  this.logConsumer = logConsumer;
319
323
  return this;
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { RestartOptions, StartedTestContainer, StopOptions, StoppedTestContainer } from "../test-container";
3
4
  import Dockerode from "dockerode";
4
- import { ExecResult, Labels } from "../docker/types";
5
+ import { ContentToCopy, ExecResult, FileToCopy, Labels } from "../docker/types";
5
6
  import { InspectResult } from "../docker/functions/container/inspect-container";
6
7
  import { BoundPorts } from "../bound-ports";
7
8
  import { Readable } from "stream";
@@ -30,6 +31,9 @@ export declare class StartedGenericContainer implements StartedTestContainer {
30
31
  getNetworkNames(): string[];
31
32
  getNetworkId(networkName: string): string;
32
33
  getIpAddress(networkName: string): string;
33
- exec(command: string[]): Promise<ExecResult>;
34
+ copyFilesToContainer(filesToCopy: FileToCopy[]): Promise<void>;
35
+ copyContentToContainer(contentsToCopy: ContentToCopy[]): Promise<void>;
36
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
37
+ exec(command: string | string[]): Promise<ExecResult>;
34
38
  logs(): Promise<Readable>;
35
39
  }
@@ -25,6 +25,9 @@ const restart_container_1 = require("../docker/functions/container/restart-conta
25
25
  const wait_for_container_1 = require("../wait-for-container");
26
26
  const docker_client_1 = require("../docker/client/docker-client");
27
27
  const async_lock_1 = __importDefault(require("async-lock"));
28
+ const get_container_archive_1 = require("../docker/functions/container/get-container-archive");
29
+ const archiver_1 = __importDefault(require("archiver"));
30
+ const put_container_archive_1 = require("../docker/functions/container/put-container-archive");
28
31
  class StartedGenericContainer {
29
32
  constructor(container, host, inspectResult, boundPorts, name, waitStrategy) {
30
33
  this.container = container;
@@ -70,14 +73,16 @@ class StartedGenericContainer {
70
73
  if (this.containerIsStopping) {
71
74
  yield this.containerIsStopping();
72
75
  }
73
- const resolvedOptions = Object.assign({ timeout: 0, removeVolumes: true }, options);
76
+ const resolvedOptions = Object.assign({ remove: true, timeout: 0, removeVolumes: true }, options);
74
77
  yield (0, stop_container_1.stopContainer)(this.container, { timeout: resolvedOptions.timeout });
75
- yield (0, remove_container_1.removeContainer)(this.container, { removeVolumes: resolvedOptions.removeVolumes });
78
+ if (resolvedOptions.remove) {
79
+ yield (0, remove_container_1.removeContainer)(this.container, { removeVolumes: resolvedOptions.removeVolumes });
80
+ }
76
81
  logger_1.log.info(`Stopped container`, { containerId: this.container.id });
77
82
  if (this.containerIsStopped) {
78
83
  yield this.containerIsStopped();
79
84
  }
80
- return new stopped_generic_container_1.StoppedGenericContainer();
85
+ return new stopped_generic_container_1.StoppedGenericContainer(this.container);
81
86
  });
82
87
  }
83
88
  getHost() {
@@ -107,12 +112,42 @@ class StartedGenericContainer {
107
112
  getIpAddress(networkName) {
108
113
  return this.inspectResult.networkSettings[networkName].ipAddress;
109
114
  }
115
+ copyFilesToContainer(filesToCopy) {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ logger_1.log.debug(`Copying files to container...`, { containerId: this.container.id });
118
+ const tar = (0, archiver_1.default)("tar");
119
+ filesToCopy.forEach(({ source, target }) => tar.file(source, { name: target }));
120
+ tar.finalize();
121
+ yield (0, put_container_archive_1.putContainerArchive)({ container: this.container, stream: tar, containerPath: "/" });
122
+ logger_1.log.debug(`Copied files to container`, { containerId: this.container.id });
123
+ });
124
+ }
125
+ copyContentToContainer(contentsToCopy) {
126
+ return __awaiter(this, void 0, void 0, function* () {
127
+ logger_1.log.debug(`Copying content to container...`, { containerId: this.container.id });
128
+ const tar = (0, archiver_1.default)("tar");
129
+ contentsToCopy.forEach(({ content, target }) => tar.append(content, { name: target }));
130
+ tar.finalize();
131
+ yield (0, put_container_archive_1.putContainerArchive)({ container: this.container, stream: tar, containerPath: "/" });
132
+ logger_1.log.debug(`Copied content to container`, { containerId: this.container.id });
133
+ });
134
+ }
135
+ copyArchiveFromContainer(path) {
136
+ return __awaiter(this, void 0, void 0, function* () {
137
+ logger_1.log.debug(`Copying archive "${path}" from container...`, { containerId: this.container.id });
138
+ const stream = yield (0, get_container_archive_1.getContainerArchive)({ container: this.container, path: path });
139
+ logger_1.log.debug(`Copied archive "${path}" from container`, { containerId: this.container.id });
140
+ return stream;
141
+ });
142
+ }
110
143
  exec(command) {
111
144
  return __awaiter(this, void 0, void 0, function* () {
112
145
  const { dockerode, containerRuntime } = yield (0, docker_client_1.getDockerClient)();
113
- logger_1.log.debug(`Executing command "${command.join(" ")}"...`, { containerId: this.container.id });
114
- const output = yield (0, exec_container_1.execContainer)(dockerode, containerRuntime, this.container, command);
115
- logger_1.log.debug(`Executed command "${command.join(" ")}"...`, { containerId: this.container.id });
146
+ const commandArr = Array.isArray(command) ? command : command.split(" ");
147
+ const commandStr = commandArr.join(" ");
148
+ logger_1.log.debug(`Executing command "${commandStr}"...`, { containerId: this.container.id });
149
+ const output = yield (0, exec_container_1.execContainer)(dockerode, containerRuntime, this.container, commandArr);
150
+ logger_1.log.debug(`Executed command "${commandStr}"...`, { containerId: this.container.id });
116
151
  return output;
117
152
  });
118
153
  }
@@ -1,3 +1,9 @@
1
+ /// <reference types="node" />
1
2
  import { StoppedTestContainer } from "../test-container";
3
+ import Dockerode from "dockerode";
2
4
  export declare class StoppedGenericContainer implements StoppedTestContainer {
5
+ private readonly container;
6
+ constructor(container: Dockerode.Container);
7
+ getId(): string;
8
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
3
9
  }
@@ -1,6 +1,20 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.StoppedGenericContainer = void 0;
4
+ const get_container_archive_1 = require("../docker/functions/container/get-container-archive");
5
+ const logger_1 = require("../logger");
4
6
  class StoppedGenericContainer {
7
+ constructor(container) {
8
+ this.container = container;
9
+ }
10
+ getId() {
11
+ return this.container.id;
12
+ }
13
+ copyArchiveFromContainer(path) {
14
+ logger_1.log.debug(`Copying archive "${path}" from container...`, { containerId: this.container.id });
15
+ const stream = (0, get_container_archive_1.getContainerArchive)({ container: this.container, path: path });
16
+ logger_1.log.debug(`Copied archive "${path}" from container`, { containerId: this.container.id });
17
+ return stream;
18
+ }
5
19
  }
6
20
  exports.StoppedGenericContainer = StoppedGenericContainer;
@@ -2,5 +2,5 @@
2
2
  var _a, _b;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.SSHD_IMAGE = exports.REAPER_IMAGE = void 0;
5
- exports.REAPER_IMAGE = (_a = process.env["RYUK_CONTAINER_IMAGE"]) !== null && _a !== void 0 ? _a : "testcontainers/ryuk:0.4.0";
5
+ exports.REAPER_IMAGE = (_a = process.env["RYUK_CONTAINER_IMAGE"]) !== null && _a !== void 0 ? _a : "testcontainers/ryuk:0.5.1";
6
6
  exports.SSHD_IMAGE = (_b = process.env["SSHD_CONTAINER_IMAGE"]) !== null && _b !== void 0 ? _b : "testcontainers/sshd:1.1.0";
@@ -12,6 +12,7 @@ export { StartupCheckStrategy, StartupStatus } from "./wait-strategy/startup-che
12
12
  export { PullPolicy, DefaultPullPolicy, AlwaysPullPolicy } from "./pull-policy";
13
13
  export { InspectResult } from "./docker/functions/container/inspect-container";
14
14
  export { AbstractStartedContainer } from "./modules/abstract-started-container";
15
+ export { AbstractStoppedContainer } from "./modules/abstract-stopped-container";
15
16
  export { PostgreSqlContainer, StartedPostgreSqlContainer } from "./modules/postgresql/postgresql-container";
16
17
  export { KafkaContainer, StartedKafkaContainer } from "./modules/kafka/kafka-container";
17
18
  export { Neo4jContainer, StartedNeo4jContainer } from "./modules/neo4j/neo4j-container";
@@ -20,3 +21,4 @@ export { ElasticsearchContainer, StartedElasticsearchContainer } from "./modules
20
21
  export { MySqlContainer, StartedMySqlContainer } from "./modules/mysql/mysql-container";
21
22
  export { NatsContainer, StartedNatsContainer, NatsConnectionOptions, NatsTlsOptions, } from "./modules/nats/nats-container";
22
23
  export { MongoDBContainer, StartedMongoDBContainer } from "./modules/mongodb/mongodb-container";
24
+ export { SeleniumContainer, SeleniumRecordingContainer, StartedSeleniumContainer, StartedSeleniumRecordingContainer, StoppedSeleniumContainer, StoppedSeleniumRecordingContainer, } from "./modules/selenium/selenium-container";
package/dist/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StartedMongoDBContainer = exports.MongoDBContainer = exports.StartedNatsContainer = exports.NatsContainer = exports.StartedMySqlContainer = exports.MySqlContainer = exports.StartedElasticsearchContainer = exports.ElasticsearchContainer = exports.StartedArangoContainer = exports.ArangoDBContainer = exports.StartedNeo4jContainer = exports.Neo4jContainer = exports.StartedKafkaContainer = exports.KafkaContainer = exports.StartedPostgreSqlContainer = exports.PostgreSqlContainer = exports.AbstractStartedContainer = exports.AlwaysPullPolicy = exports.DefaultPullPolicy = exports.StartupCheckStrategy = exports.Wait = exports.StoppedNetwork = exports.StartedNetwork = exports.Network = exports.DownedDockerComposeEnvironment = exports.StoppedDockerComposeEnvironment = exports.StartedDockerComposeEnvironment = exports.DockerComposeEnvironment = exports.TestContainers = exports.GenericContainerBuilder = exports.GenericContainer = void 0;
3
+ exports.StoppedSeleniumRecordingContainer = exports.StoppedSeleniumContainer = exports.StartedSeleniumRecordingContainer = exports.StartedSeleniumContainer = exports.SeleniumRecordingContainer = exports.SeleniumContainer = exports.StartedMongoDBContainer = exports.MongoDBContainer = exports.StartedNatsContainer = exports.NatsContainer = exports.StartedMySqlContainer = exports.MySqlContainer = exports.StartedElasticsearchContainer = exports.ElasticsearchContainer = exports.StartedArangoContainer = exports.ArangoDBContainer = exports.StartedNeo4jContainer = exports.Neo4jContainer = exports.StartedKafkaContainer = exports.KafkaContainer = exports.StartedPostgreSqlContainer = exports.PostgreSqlContainer = exports.AbstractStoppedContainer = exports.AbstractStartedContainer = exports.AlwaysPullPolicy = exports.DefaultPullPolicy = exports.StartupCheckStrategy = exports.Wait = exports.StoppedNetwork = exports.StartedNetwork = exports.Network = exports.DownedDockerComposeEnvironment = exports.StoppedDockerComposeEnvironment = exports.StartedDockerComposeEnvironment = exports.DockerComposeEnvironment = exports.TestContainers = exports.GenericContainerBuilder = exports.GenericContainer = void 0;
4
4
  var generic_container_1 = require("./generic-container/generic-container");
5
5
  Object.defineProperty(exports, "GenericContainer", { enumerable: true, get: function () { return generic_container_1.GenericContainer; } });
6
6
  var generic_container_builder_1 = require("./generic-container/generic-container-builder");
@@ -28,6 +28,8 @@ Object.defineProperty(exports, "DefaultPullPolicy", { enumerable: true, get: fun
28
28
  Object.defineProperty(exports, "AlwaysPullPolicy", { enumerable: true, get: function () { return pull_policy_1.AlwaysPullPolicy; } });
29
29
  var abstract_started_container_1 = require("./modules/abstract-started-container");
30
30
  Object.defineProperty(exports, "AbstractStartedContainer", { enumerable: true, get: function () { return abstract_started_container_1.AbstractStartedContainer; } });
31
+ var abstract_stopped_container_1 = require("./modules/abstract-stopped-container");
32
+ Object.defineProperty(exports, "AbstractStoppedContainer", { enumerable: true, get: function () { return abstract_stopped_container_1.AbstractStoppedContainer; } });
31
33
  var postgresql_container_1 = require("./modules/postgresql/postgresql-container");
32
34
  Object.defineProperty(exports, "PostgreSqlContainer", { enumerable: true, get: function () { return postgresql_container_1.PostgreSqlContainer; } });
33
35
  Object.defineProperty(exports, "StartedPostgreSqlContainer", { enumerable: true, get: function () { return postgresql_container_1.StartedPostgreSqlContainer; } });
@@ -52,3 +54,10 @@ Object.defineProperty(exports, "StartedNatsContainer", { enumerable: true, get:
52
54
  var mongodb_container_1 = require("./modules/mongodb/mongodb-container");
53
55
  Object.defineProperty(exports, "MongoDBContainer", { enumerable: true, get: function () { return mongodb_container_1.MongoDBContainer; } });
54
56
  Object.defineProperty(exports, "StartedMongoDBContainer", { enumerable: true, get: function () { return mongodb_container_1.StartedMongoDBContainer; } });
57
+ var selenium_container_1 = require("./modules/selenium/selenium-container");
58
+ Object.defineProperty(exports, "SeleniumContainer", { enumerable: true, get: function () { return selenium_container_1.SeleniumContainer; } });
59
+ Object.defineProperty(exports, "SeleniumRecordingContainer", { enumerable: true, get: function () { return selenium_container_1.SeleniumRecordingContainer; } });
60
+ Object.defineProperty(exports, "StartedSeleniumContainer", { enumerable: true, get: function () { return selenium_container_1.StartedSeleniumContainer; } });
61
+ Object.defineProperty(exports, "StartedSeleniumRecordingContainer", { enumerable: true, get: function () { return selenium_container_1.StartedSeleniumRecordingContainer; } });
62
+ Object.defineProperty(exports, "StoppedSeleniumContainer", { enumerable: true, get: function () { return selenium_container_1.StoppedSeleniumContainer; } });
63
+ Object.defineProperty(exports, "StoppedSeleniumRecordingContainer", { enumerable: true, get: function () { return selenium_container_1.StoppedSeleniumRecordingContainer; } });
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { RestartOptions, StartedTestContainer, StopOptions, StoppedTestContainer } from "../test-container";
3
- import { ExecResult, Labels } from "../docker/types";
4
+ import { ContentToCopy, ExecResult, FileToCopy, Labels } from "../docker/types";
4
5
  import { Readable } from "stream";
5
6
  export declare class AbstractStartedContainer implements StartedTestContainer {
6
7
  protected readonly startedTestContainer: StartedTestContainer;
@@ -18,6 +19,9 @@ export declare class AbstractStartedContainer implements StartedTestContainer {
18
19
  getNetworkNames(): string[];
19
20
  getNetworkId(networkName: string): string;
20
21
  getIpAddress(networkName: string): string;
21
- exec(command: string[]): Promise<ExecResult>;
22
+ copyFilesToContainer(filesToCopy: FileToCopy[]): Promise<void>;
23
+ copyContentToContainer(contentsToCopy: ContentToCopy[]): Promise<void>;
24
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
25
+ exec(command: string | string[]): Promise<ExecResult>;
22
26
  logs(): Promise<Readable>;
23
27
  }
@@ -58,6 +58,19 @@ class AbstractStartedContainer {
58
58
  getIpAddress(networkName) {
59
59
  return this.startedTestContainer.getIpAddress(networkName);
60
60
  }
61
+ copyFilesToContainer(filesToCopy) {
62
+ return __awaiter(this, void 0, void 0, function* () {
63
+ return this.startedTestContainer.copyFilesToContainer(filesToCopy);
64
+ });
65
+ }
66
+ copyContentToContainer(contentsToCopy) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ return this.startedTestContainer.copyContentToContainer(contentsToCopy);
69
+ });
70
+ }
71
+ copyArchiveFromContainer(path) {
72
+ return this.startedTestContainer.copyArchiveFromContainer(path);
73
+ }
61
74
  exec(command) {
62
75
  return this.startedTestContainer.exec(command);
63
76
  }
@@ -0,0 +1,8 @@
1
+ /// <reference types="node" />
2
+ import { StoppedTestContainer } from "../test-container";
3
+ export declare class AbstractStoppedContainer implements StoppedTestContainer {
4
+ protected readonly stoppedTestContainer: StoppedTestContainer;
5
+ constructor(stoppedTestContainer: StoppedTestContainer);
6
+ getId(): string;
7
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
8
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractStoppedContainer = void 0;
4
+ class AbstractStoppedContainer {
5
+ constructor(stoppedTestContainer) {
6
+ this.stoppedTestContainer = stoppedTestContainer;
7
+ }
8
+ getId() {
9
+ return this.stoppedTestContainer.getId();
10
+ }
11
+ copyArchiveFromContainer(path) {
12
+ return this.stoppedTestContainer.copyArchiveFromContainer(path);
13
+ }
14
+ }
15
+ exports.AbstractStoppedContainer = AbstractStoppedContainer;
@@ -122,7 +122,12 @@ class KafkaContainer extends generic_container_1.GenericContainer {
122
122
  const brokerAdvertisedListener = `BROKER://${inspectResult.hostname}:${KAFKA_BROKER_PORT}`;
123
123
  let bootstrapServers = `PLAINTEXT://${container.getHost()}:${container.getMappedPort(KAFKA_PORT)}`;
124
124
  if (this.saslSslConfig) {
125
- bootstrapServers = `${bootstrapServers},SECURE://${container.getHost()}:${container.getMappedPort(this.saslSslConfig.port)}`;
125
+ if (this.networkMode) {
126
+ bootstrapServers = `${bootstrapServers},SECURE://${inspectResult.hostname}:${this.saslSslConfig.port}`;
127
+ }
128
+ else {
129
+ bootstrapServers = `${bootstrapServers},SECURE://${container.getHost()}:${container.getMappedPort(this.saslSslConfig.port)}`;
130
+ }
126
131
  }
127
132
  const { output, exitCode } = yield container.exec([
128
133
  "kafka-configs",
@@ -25,5 +25,6 @@ export declare class StartedMySqlContainer extends AbstractStartedContainer {
25
25
  getUsername(): string;
26
26
  getUserPassword(): string;
27
27
  getRootPassword(): string;
28
+ getConnectionUri(isRoot?: boolean): string;
28
29
  executeQuery(query: string, additionalFlags?: string[]): Promise<string>;
29
30
  }
@@ -79,6 +79,15 @@ class StartedMySqlContainer extends abstract_started_container_1.AbstractStarted
79
79
  getRootPassword() {
80
80
  return this.rootPassword;
81
81
  }
82
+ getConnectionUri(isRoot = false) {
83
+ const url = new URL("", "mysql://");
84
+ url.hostname = this.getHost();
85
+ url.port = this.getPort().toString();
86
+ url.pathname = this.getDatabase();
87
+ url.username = isRoot ? "root" : this.getUsername();
88
+ url.password = isRoot ? this.getRootPassword() : this.getUserPassword();
89
+ return url.toString();
90
+ }
82
91
  executeQuery(query, additionalFlags = []) {
83
92
  return __awaiter(this, void 0, void 0, function* () {
84
93
  const result = yield this.startedTestContainer.exec([
@@ -0,0 +1,38 @@
1
+ import { GenericContainer } from "../../generic-container/generic-container";
2
+ import { AbstractStartedContainer } from "../abstract-started-container";
3
+ import { StartedTestContainer, StopOptions, StoppedTestContainer } from "../../test-container";
4
+ import { AbstractStoppedContainer } from "../abstract-stopped-container";
5
+ import { StartedNetwork } from "../../network";
6
+ export declare const SELENIUM_VIDEO_IMAGE = "selenium/video:ffmpeg-4.3.1-20230508";
7
+ export declare class SeleniumContainer extends GenericContainer {
8
+ constructor(image?: string);
9
+ protected beforeContainerStarted(): Promise<void>;
10
+ withRecording(): SeleniumRecordingContainer;
11
+ start(): Promise<StartedSeleniumContainer>;
12
+ }
13
+ export declare class StartedSeleniumContainer extends AbstractStartedContainer {
14
+ private readonly serverUrl;
15
+ constructor(startedTestContainer: StartedTestContainer);
16
+ getServerUrl(): string;
17
+ stop(options?: Partial<StopOptions>): Promise<StoppedSeleniumContainer>;
18
+ }
19
+ export declare class StoppedSeleniumContainer extends AbstractStoppedContainer {
20
+ private readonly stoppedSeleniumContainer;
21
+ constructor(stoppedSeleniumContainer: StoppedTestContainer);
22
+ }
23
+ export declare class SeleniumRecordingContainer extends SeleniumContainer {
24
+ constructor(image: string);
25
+ start(): Promise<StartedSeleniumRecordingContainer>;
26
+ }
27
+ export declare class StartedSeleniumRecordingContainer extends StartedSeleniumContainer {
28
+ private readonly startedFfmpegContainer;
29
+ private readonly network;
30
+ constructor(startedSeleniumContainer: StartedTestContainer, startedFfmpegContainer: StartedTestContainer, network: StartedNetwork);
31
+ stop(options?: Partial<StopOptions>): Promise<StoppedSeleniumRecordingContainer>;
32
+ }
33
+ export declare class StoppedSeleniumRecordingContainer extends StoppedSeleniumContainer {
34
+ private readonly stoppedFfmpegContainer;
35
+ constructor(stoppedSeleniumContainer: StoppedTestContainer, stoppedFfmpegContainer: StoppedTestContainer);
36
+ saveRecording(target: string): Promise<void>;
37
+ private extractTarStreamToDest;
38
+ }
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.StoppedSeleniumRecordingContainer = exports.StartedSeleniumRecordingContainer = exports.SeleniumRecordingContainer = exports.StoppedSeleniumContainer = exports.StartedSeleniumContainer = exports.SeleniumContainer = exports.SELENIUM_VIDEO_IMAGE = void 0;
16
+ const generic_container_1 = require("../../generic-container/generic-container");
17
+ const abstract_started_container_1 = require("../abstract-started-container");
18
+ const wait_1 = require("../../wait-strategy/wait");
19
+ const abstract_stopped_container_1 = require("../abstract-stopped-container");
20
+ const network_1 = require("../../network");
21
+ const logger_1 = require("../../logger");
22
+ const promises_1 = require("fs/promises");
23
+ const tmp_1 = __importDefault(require("tmp"));
24
+ const tar_fs_1 = __importDefault(require("tar-fs"));
25
+ const path_1 = __importDefault(require("path"));
26
+ const SELENIUM_PORT = 4444;
27
+ const VNC_PORT = 5900;
28
+ const SELENIUM_NETWORK_ALIAS = "selenium";
29
+ exports.SELENIUM_VIDEO_IMAGE = "selenium/video:ffmpeg-4.3.1-20230508";
30
+ class SeleniumContainer extends generic_container_1.GenericContainer {
31
+ constructor(image = "selenium/standalone-chrome:112.0") {
32
+ super(image);
33
+ }
34
+ beforeContainerStarted() {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ this.withExposedPorts(SELENIUM_PORT, VNC_PORT)
37
+ .withSharedMemorySize(2 * 1024 * 1024 * 1024)
38
+ .withWaitStrategy(wait_1.Wait.forHttp("/wd/hub/status", SELENIUM_PORT).forResponsePredicate((response) => {
39
+ try {
40
+ return JSON.parse(response).value.ready;
41
+ }
42
+ catch (_a) {
43
+ return false;
44
+ }
45
+ }));
46
+ });
47
+ }
48
+ withRecording() {
49
+ return new SeleniumRecordingContainer(this.image);
50
+ }
51
+ start() {
52
+ const _super = Object.create(null, {
53
+ start: { get: () => super.start }
54
+ });
55
+ return __awaiter(this, void 0, void 0, function* () {
56
+ return new StartedSeleniumContainer(yield _super.start.call(this));
57
+ });
58
+ }
59
+ }
60
+ exports.SeleniumContainer = SeleniumContainer;
61
+ class StartedSeleniumContainer extends abstract_started_container_1.AbstractStartedContainer {
62
+ constructor(startedTestContainer) {
63
+ super(startedTestContainer);
64
+ this.serverUrl = `http://${this.getHost()}:${this.getMappedPort(4444)}/wd/hub`;
65
+ }
66
+ getServerUrl() {
67
+ return this.serverUrl;
68
+ }
69
+ stop(options) {
70
+ const _super = Object.create(null, {
71
+ stop: { get: () => super.stop }
72
+ });
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ return new StoppedSeleniumContainer(yield _super.stop.call(this, options));
75
+ });
76
+ }
77
+ }
78
+ exports.StartedSeleniumContainer = StartedSeleniumContainer;
79
+ class StoppedSeleniumContainer extends abstract_stopped_container_1.AbstractStoppedContainer {
80
+ constructor(stoppedSeleniumContainer) {
81
+ super(stoppedSeleniumContainer);
82
+ this.stoppedSeleniumContainer = stoppedSeleniumContainer;
83
+ }
84
+ }
85
+ exports.StoppedSeleniumContainer = StoppedSeleniumContainer;
86
+ class SeleniumRecordingContainer extends SeleniumContainer {
87
+ constructor(image) {
88
+ super(image);
89
+ }
90
+ start() {
91
+ const _super = Object.create(null, {
92
+ start: { get: () => super.start }
93
+ });
94
+ return __awaiter(this, void 0, void 0, function* () {
95
+ const network = yield new network_1.Network().start();
96
+ this.withNetwork(network);
97
+ this.withNetworkAliases(SELENIUM_NETWORK_ALIAS);
98
+ const startedSeleniumContainer = yield _super.start.call(this);
99
+ const startedFfmpegContainer = yield new generic_container_1.GenericContainer(exports.SELENIUM_VIDEO_IMAGE)
100
+ .withNetwork(network)
101
+ .withEnvironment({ DISPLAY_CONTAINER_NAME: SELENIUM_NETWORK_ALIAS })
102
+ .withWaitStrategy(wait_1.Wait.forLogMessage(/.*video-recording entered RUNNING state.*/))
103
+ .start();
104
+ return new StartedSeleniumRecordingContainer(startedSeleniumContainer, startedFfmpegContainer, network);
105
+ });
106
+ }
107
+ }
108
+ exports.SeleniumRecordingContainer = SeleniumRecordingContainer;
109
+ class StartedSeleniumRecordingContainer extends StartedSeleniumContainer {
110
+ constructor(startedSeleniumContainer, startedFfmpegContainer, network) {
111
+ super(startedSeleniumContainer);
112
+ this.startedFfmpegContainer = startedFfmpegContainer;
113
+ this.network = network;
114
+ }
115
+ stop(options) {
116
+ const _super = Object.create(null, {
117
+ stop: { get: () => super.stop }
118
+ });
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const stoppedSeleniumContainer = yield _super.stop.call(this, options);
121
+ const stoppedFfmpegContainer = yield this.startedFfmpegContainer.stop({ remove: false, timeout: 60000 });
122
+ yield this.network.stop();
123
+ return new StoppedSeleniumRecordingContainer(stoppedSeleniumContainer, stoppedFfmpegContainer);
124
+ });
125
+ }
126
+ }
127
+ exports.StartedSeleniumRecordingContainer = StartedSeleniumRecordingContainer;
128
+ class StoppedSeleniumRecordingContainer extends StoppedSeleniumContainer {
129
+ constructor(stoppedSeleniumContainer, stoppedFfmpegContainer) {
130
+ super(stoppedSeleniumContainer);
131
+ this.stoppedFfmpegContainer = stoppedFfmpegContainer;
132
+ }
133
+ saveRecording(target) {
134
+ return __awaiter(this, void 0, void 0, function* () {
135
+ const ffmpegContainerId = this.stoppedFfmpegContainer.getId();
136
+ logger_1.log.debug("Extracting archive from container...", { containerId: ffmpegContainerId });
137
+ const archiveStream = yield this.stoppedFfmpegContainer.copyArchiveFromContainer("/videos/video.mp4");
138
+ logger_1.log.debug("Extracted archive from container", { containerId: ffmpegContainerId });
139
+ logger_1.log.debug("Unpacking archive...", { containerId: ffmpegContainerId });
140
+ const destinationDir = tmp_1.default.dirSync({ keep: false });
141
+ yield this.extractTarStreamToDest(archiveStream, destinationDir.name);
142
+ logger_1.log.debug("Unpacked archive", { containerId: ffmpegContainerId });
143
+ const videoFile = path_1.default.resolve(destinationDir.name, "video.mp4");
144
+ yield (0, promises_1.copyFile)(videoFile, target);
145
+ logger_1.log.debug(`Extracted video to "${target}"`, { containerId: ffmpegContainerId });
146
+ });
147
+ }
148
+ extractTarStreamToDest(tarStream, dest) {
149
+ return __awaiter(this, void 0, void 0, function* () {
150
+ yield new Promise((resolve) => {
151
+ const destination = tar_fs_1.default.extract(dest);
152
+ tarStream.pipe(destination);
153
+ destination.on("finish", resolve);
154
+ });
155
+ });
156
+ }
157
+ }
158
+ exports.StoppedSeleniumRecordingContainer = StoppedSeleniumRecordingContainer;
@@ -1,9 +1,10 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { PortWithOptionalBinding } from "./port";
3
4
  import { PullPolicy } from "./pull-policy";
4
5
  import { WaitStrategy } from "./wait-strategy/wait-strategy";
5
6
  import { Readable } from "stream";
6
- import { ExecResult, ExtraHost, TmpFs, Labels, Ulimits, BindMount, FileToCopy, ContentToCopy, Environment, ResourcesQuota } from "./docker/types";
7
+ import { BindMount, ContentToCopy, Environment, ExecResult, ExtraHost, FileToCopy, Labels, ResourcesQuota, TmpFs, Ulimits } from "./docker/types";
7
8
  import { StartedNetwork } from "./network";
8
9
  export interface TestContainer {
9
10
  start(): Promise<StartedTestContainer>;
@@ -30,6 +31,7 @@ export interface TestContainer {
30
31
  withCopyContentToContainer(contentsToCopy: ContentToCopy[]): this;
31
32
  withWorkingDir(workingDir: string): this;
32
33
  withResourcesQuota(resourcesQuota: ResourcesQuota): this;
34
+ withSharedMemorySize(bytes: number): this;
33
35
  withLogConsumer(logConsumer: (stream: Readable) => unknown): this;
34
36
  }
35
37
  export interface RestartOptions {
@@ -37,6 +39,7 @@ export interface RestartOptions {
37
39
  }
38
40
  export interface StopOptions {
39
41
  timeout: number;
42
+ remove: boolean;
40
43
  removeVolumes: boolean;
41
44
  }
42
45
  export interface DockerComposeDownOptions {
@@ -55,8 +58,13 @@ export interface StartedTestContainer {
55
58
  getNetworkNames(): string[];
56
59
  getNetworkId(networkName: string): string;
57
60
  getIpAddress(networkName: string): string;
58
- exec(command: string[]): Promise<ExecResult>;
61
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
62
+ copyFilesToContainer(filesToCopy: FileToCopy[]): Promise<void>;
63
+ copyContentToContainer(contentsToCopy: ContentToCopy[]): Promise<void>;
64
+ exec(command: string | string[]): Promise<ExecResult>;
59
65
  logs(): Promise<Readable>;
60
66
  }
61
67
  export interface StoppedTestContainer {
68
+ getId(): string;
69
+ copyArchiveFromContainer(path: string): Promise<NodeJS.ReadableStream>;
62
70
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "testcontainers",
3
3
  "author": "Cristian Greco",
4
- "version": "9.8.0",
4
+ "version": "9.9.0",
5
5
  "main": "dist/src/index",
6
6
  "types": "dist/src/index",
7
7
  "keywords": [
@@ -43,13 +43,14 @@
43
43
  "async-lock": "^1.4.0",
44
44
  "byline": "^5.0.0",
45
45
  "debug": "^4.3.4",
46
- "docker-compose": "^0.23.19",
46
+ "docker-compose": "^0.24.1",
47
47
  "dockerode": "^3.3.5",
48
48
  "get-port": "^5.1.1",
49
49
  "node-fetch": "^2.6.9",
50
50
  "properties-reader": "^2.2.0",
51
51
  "ssh-remote-port-forward": "^1.0.4",
52
- "tar-fs": "^2.1.1"
52
+ "tar-fs": "^2.1.1",
53
+ "tmp": "^0.2.1"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@elastic/elasticsearch": "^7.17.0",
@@ -61,7 +62,9 @@
61
62
  "@types/node-fetch": "^2.6.3",
62
63
  "@types/pg": "^8.6.6",
63
64
  "@types/properties-reader": "^2.1.1",
65
+ "@types/selenium-webdriver": "^4.1.14",
64
66
  "@types/tar-fs": "^2.0.1",
67
+ "@types/tmp": "^0.2.3",
65
68
  "@typescript-eslint/eslint-plugin": "^5.59.1",
66
69
  "@typescript-eslint/parser": "^5.59.1",
67
70
  "arangojs": "^8.2.1",
@@ -80,6 +83,7 @@
80
83
  "pg": "^8.10.0",
81
84
  "prettier": "^2.8.8",
82
85
  "rimraf": "^3.0.2",
86
+ "selenium-webdriver": "^4.9.2",
83
87
  "ts-jest": "^29.1.0",
84
88
  "ts-node": "^10.9.1",
85
89
  "typescript": "^4.9.5",