testcafe 1.13.0 → 1.14.2
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.
- package/CHANGELOG.md +88 -10
- package/LICENSE +21 -21
- package/README.md +52 -48
- package/bin/testcafe-with-v8-flag-filter.js +0 -0
- package/lib/api/exportable-lib/index.js +50 -50
- package/lib/api/request-hooks/assert-type.js +7 -7
- package/lib/api/request-hooks/hook-method-names.js +11 -0
- package/lib/api/request-hooks/hook.js +33 -39
- package/lib/api/request-hooks/interfaces.js +3 -3
- package/lib/api/request-hooks/request-logger.js +113 -111
- package/lib/api/request-hooks/request-mock/create-request-mock.js +12 -0
- package/lib/api/request-hooks/request-mock/index.js +46 -0
- package/lib/api/request-hooks/request-mock.js +47 -48
- package/lib/api/structure/base-unit.js +11 -11
- package/lib/api/structure/fixture.js +75 -75
- package/lib/api/structure/interfaces.js +2 -2
- package/lib/api/structure/test-file.js +31 -31
- package/lib/api/structure/test-timeout.js +9 -9
- package/lib/api/structure/test.js +85 -85
- package/lib/api/structure/testing-unit.js +89 -89
- package/lib/api/structure/unit-type.js +9 -9
- package/lib/api/test-controller/assertion.js +88 -88
- package/lib/api/test-controller/execution-context.js +82 -82
- package/lib/api/test-controller/index.js +359 -319
- package/lib/api/test-controller/proxy.js +28 -28
- package/lib/api/test-page-url.js +60 -60
- package/lib/api/test-run-tracker.js +68 -68
- package/lib/api/wrap-test-function.js +49 -49
- package/lib/assertions/executor.js +74 -74
- package/lib/assertions/get-fn.js +46 -46
- package/lib/assertions/type.js +20 -20
- package/lib/assets/content-types.js +9 -9
- package/lib/assets/injectables.js +18 -18
- package/lib/browser/connection/command.js +10 -10
- package/lib/browser/connection/error-hints.js +9 -9
- package/lib/browser/connection/gateway.js +159 -159
- package/lib/browser/connection/get-hints.js +33 -33
- package/lib/browser/connection/heartbeat-status.js +8 -8
- package/lib/browser/connection/index.js +328 -328
- package/lib/browser/connection/remotes-queue.js +46 -46
- package/lib/browser/connection/service-routes.js +12 -12
- package/lib/browser/connection/status.js +12 -12
- package/lib/browser/interfaces.js +2 -2
- package/lib/browser/provider/built-in/dedicated/base.js +80 -80
- package/lib/browser/provider/built-in/dedicated/chrome/browser-client.js +204 -204
- package/lib/browser/provider/built-in/dedicated/chrome/build-chrome-args.js +17 -17
- package/lib/browser/provider/built-in/dedicated/chrome/config.js +110 -110
- package/lib/browser/provider/built-in/dedicated/chrome/create-temp-profile.js +45 -45
- package/lib/browser/provider/built-in/dedicated/chrome/elapsed-upperbounds.js +15 -15
- package/lib/browser/provider/built-in/dedicated/chrome/index.js +102 -102
- package/lib/browser/provider/built-in/dedicated/chrome/interfaces.js +2 -2
- package/lib/browser/provider/built-in/dedicated/chrome/local-chrome.js +24 -24
- package/lib/browser/provider/built-in/dedicated/chrome/runtime-info.js +29 -29
- package/lib/browser/provider/built-in/dedicated/edge/index.js +10 -10
- package/lib/browser/provider/built-in/dedicated/edge/runtime-info.js +29 -29
- package/lib/browser/provider/built-in/dedicated/firefox/config.js +33 -33
- package/lib/browser/provider/built-in/dedicated/firefox/create-temp-profile.js +78 -78
- package/lib/browser/provider/built-in/dedicated/firefox/index.js +73 -73
- package/lib/browser/provider/built-in/dedicated/firefox/local-firefox.js +36 -36
- package/lib/browser/provider/built-in/dedicated/firefox/marionette-client/commands.js +13 -13
- package/lib/browser/provider/built-in/dedicated/firefox/marionette-client/index.js +200 -200
- package/lib/browser/provider/built-in/dedicated/firefox/runtime-info.js +17 -17
- package/lib/browser/provider/built-in/index.js +21 -21
- package/lib/browser/provider/built-in/locally-installed.js +30 -30
- package/lib/browser/provider/built-in/path.js +47 -47
- package/lib/browser/provider/built-in/remote.js +58 -58
- package/lib/browser/provider/index.js +303 -303
- package/lib/browser/provider/parse-provider-name.js +16 -16
- package/lib/browser/provider/plugin-host.js +121 -121
- package/lib/browser/provider/pool.js +115 -115
- package/lib/browser/provider/utils/argument-parsing.js +74 -74
- package/lib/browser/provider/utils/browser-starter.js +34 -34
- package/lib/browser/provider/utils/client-functions.js +24 -24
- package/lib/browser/provider/utils/get-maximized-headless-window-size.js +9 -9
- package/lib/cli/argument-parser.js +284 -279
- package/lib/cli/authentication-helper.js +35 -35
- package/lib/cli/cli.js +134 -134
- package/lib/cli/correct-browsers-and-sources.js +40 -40
- package/lib/cli/index.js +19 -19
- package/lib/cli/log.js +43 -43
- package/lib/cli/remotes-wizard.js +36 -36
- package/lib/cli/termination-handler.js +38 -38
- package/lib/client/automation/index.js +144 -46
- package/lib/client/automation/index.min.js +1 -1
- package/lib/client/browser/idle-page/index.html.mustache +35 -35
- package/lib/client/browser/idle-page/logo.svg +86 -86
- package/lib/client/browser/service-worker.js +4 -6
- package/lib/client/core/index.js +19 -13
- package/lib/client/core/index.min.js +1 -1
- package/lib/client/driver/index.js +1807 -451
- package/lib/client/driver/index.min.js +1 -1
- package/lib/client/driver/internal-properties.js +9 -9
- package/lib/client/test-run/iframe.js.mustache +17 -17
- package/lib/client/test-run/index.js.mustache +51 -51
- package/lib/client/ui/index.js +14 -12
- package/lib/client/ui/index.min.js +1 -1
- package/lib/client/ui/sprite.svg +42 -42
- package/lib/client-functions/builder-symbol.js +4 -4
- package/lib/client-functions/client-function-builder.js +156 -135
- package/lib/client-functions/replicator.js +61 -61
- package/lib/client-functions/return-single-prop-mode.js +8 -8
- package/lib/client-functions/selector-api-execution-mode.js +22 -0
- package/lib/client-functions/selectors/add-api.js +646 -588
- package/lib/client-functions/selectors/create-snapshot-methods.js +13 -13
- package/lib/client-functions/selectors/prepare-api-args.js +20 -20
- package/lib/client-functions/selectors/selector-attribute-filter.js +22 -22
- package/lib/client-functions/selectors/selector-builder.js +154 -150
- package/lib/client-functions/selectors/selector-text-filter.js +43 -43
- package/lib/client-functions/selectors/snapshot-properties.js +48 -48
- package/lib/client-functions/types.js +18 -18
- package/lib/compiler/babel/format-babel-produced-code.js +10 -10
- package/lib/compiler/babel/get-base-babel-options.js +11 -11
- package/lib/compiler/babel/load-libs.js +64 -62
- package/lib/compiler/babel/preset-stage-2.js +19 -19
- package/lib/compiler/compile-client-function.js +73 -73
- package/lib/compiler/compilers.js +33 -33
- package/lib/compiler/index.js +92 -92
- package/lib/compiler/interfaces.js +2 -2
- package/lib/compiler/test-file/api-based.js +146 -146
- package/lib/compiler/test-file/base.js +36 -36
- package/lib/compiler/test-file/exportble-lib-path.js +5 -5
- package/lib/compiler/test-file/formats/coffeescript/compiler.js +38 -38
- package/lib/compiler/test-file/formats/coffeescript/get-test-list.js +29 -29
- package/lib/compiler/test-file/formats/es-next/compiler.js +43 -43
- package/lib/compiler/test-file/formats/es-next/get-test-list.js +166 -166
- package/lib/compiler/test-file/formats/es-next/is-flow-code.js +7 -7
- package/lib/compiler/test-file/formats/raw.js +85 -85
- package/lib/compiler/test-file/formats/typescript/compiler.js +135 -135
- package/lib/compiler/test-file/formats/typescript/get-test-list.js +185 -185
- package/lib/compiler/test-file/test-file-parser-base.js +214 -214
- package/lib/configuration/configuration-base.js +165 -165
- package/lib/configuration/constants.js +9 -9
- package/lib/configuration/customizable-compilers.js +7 -7
- package/lib/configuration/default-values.js +51 -51
- package/lib/configuration/interfaces.js +3 -3
- package/lib/configuration/option-names.js +53 -53
- package/lib/configuration/option-source.js +9 -9
- package/lib/configuration/option.js +14 -14
- package/lib/configuration/quarantine-option-names.js +10 -0
- package/lib/configuration/run-option-names.js +26 -26
- package/lib/configuration/screenshot-option-names.js +10 -10
- package/lib/configuration/testcafe-configuration.js +164 -165
- package/lib/configuration/types.js +2 -2
- package/lib/configuration/typescript-configuration.js +62 -62
- package/lib/custom-client-scripts/assert-type.js +7 -7
- package/lib/custom-client-scripts/client-script-init.js +3 -3
- package/lib/custom-client-scripts/client-script.js +107 -108
- package/lib/custom-client-scripts/get-code.js +11 -11
- package/lib/custom-client-scripts/get-url.js +6 -6
- package/lib/custom-client-scripts/load.js +15 -15
- package/lib/custom-client-scripts/problematic-scripts.js +2 -2
- package/lib/custom-client-scripts/routing.js +36 -36
- package/lib/custom-client-scripts/utils.js +60 -60
- package/lib/embedding-utils.js +83 -83
- package/lib/errors/create-stack-filter.js +18 -18
- package/lib/errors/error-list.js +26 -26
- package/lib/errors/get-callsite.js +31 -31
- package/lib/errors/internal-modules-prefix.js +8 -8
- package/lib/errors/is-internal-stack-frame.js +46 -46
- package/lib/errors/process-test-fn-error.js +37 -37
- package/lib/errors/runtime/index.js +123 -123
- package/lib/errors/runtime/templates.js +116 -114
- package/lib/errors/runtime/type-assertions.js +112 -112
- package/lib/errors/stack-cleaning-hook.js +64 -64
- package/lib/errors/test-run/formattable-adapter.js +59 -59
- package/lib/errors/test-run/index.js +302 -302
- package/lib/errors/test-run/render-error-template.js +31 -31
- package/lib/errors/test-run/templates.js +93 -95
- package/lib/errors/test-run/utils.js +90 -85
- package/lib/errors/types.js +157 -155
- package/lib/index.js +81 -81
- package/lib/live/bootstrapper.js +44 -44
- package/lib/live/controller.js +107 -107
- package/lib/live/file-watcher/index.js +67 -67
- package/lib/live/file-watcher/modules-graph.js +58 -58
- package/lib/live/keyboard-observer.js +76 -76
- package/lib/live/logger/index.js +64 -64
- package/lib/live/test-run-controller.js +96 -96
- package/lib/live/test-run-state.js +6 -6
- package/lib/live/test-run.js +56 -56
- package/lib/live/test-runner.js +168 -168
- package/lib/load-assets.js +29 -29
- package/lib/notifications/add-rendered-warning.js +16 -16
- package/lib/notifications/debug-logger.js +78 -78
- package/lib/notifications/deprecated.js +24 -24
- package/lib/notifications/information-message.js +12 -12
- package/lib/notifications/warning-log.js +32 -31
- package/lib/notifications/warning-message.js +48 -48
- package/lib/reporter/command/command-formatter.js +120 -109
- package/lib/reporter/command/format-command.js +8 -8
- package/lib/reporter/command/interfaces.js +2 -2
- package/lib/reporter/index.js +319 -314
- package/lib/reporter/interfaces.js +2 -2
- package/lib/reporter/plugin-host.js +136 -137
- package/lib/reporter/plugin-methods.js +12 -12
- package/lib/role/index.js +74 -74
- package/lib/role/marker-symbol.js +7 -7
- package/lib/role/phase.js +9 -9
- package/lib/runner/bootstrapper.js +272 -272
- package/lib/runner/browser-job-result.js +9 -9
- package/lib/runner/browser-job.js +153 -123
- package/lib/runner/browser-set.js +114 -114
- package/lib/runner/fixture-hook-controller.js +85 -85
- package/lib/runner/index.js +450 -442
- package/lib/runner/interfaces.js +3 -3
- package/lib/runner/reporter-stream-controller.js +28 -28
- package/lib/runner/task/index.js +152 -133
- package/lib/runner/task/phase.js +9 -9
- package/lib/runner/test-run-controller.js +166 -185
- package/lib/runner/tested-app.js +73 -72
- package/lib/screenshots/capturer.js +141 -141
- package/lib/screenshots/constants.js +11 -11
- package/lib/screenshots/crop.js +111 -111
- package/lib/screenshots/default-extension.js +4 -4
- package/lib/screenshots/index.js +67 -67
- package/lib/screenshots/utils.js +39 -39
- package/lib/services/compiler/host.js +190 -106
- package/lib/services/compiler/io.js +9 -9
- package/lib/services/compiler/protocol.js +17 -16
- package/lib/services/compiler/service.js +225 -106
- package/lib/services/compiler/test-run-proxy.js +111 -73
- package/lib/services/interfaces.js +3 -0
- package/lib/services/process-title.js +8 -8
- package/lib/services/serialization/prepare-options.js +17 -17
- package/lib/services/serialization/replicator/create-replicator.js +27 -0
- package/lib/services/serialization/replicator/custom-error-transform.js +28 -0
- package/lib/services/serialization/test-structure.js +93 -77
- package/lib/services/utils/ipc/interfaces.js +30 -30
- package/lib/services/utils/ipc/io.js +108 -108
- package/lib/services/utils/ipc/message.js +76 -73
- package/lib/services/utils/ipc/packet.js +55 -55
- package/lib/services/utils/ipc/proxy.js +110 -118
- package/lib/services/utils/ipc/transport.js +64 -64
- package/lib/shared/errors/index.js +382 -382
- package/lib/shared/node-modules-folder-name.js +4 -4
- package/lib/test-run/bookmark.js +90 -90
- package/lib/test-run/browser-console-messages.js +73 -73
- package/lib/test-run/browser-manipulation-queue.js +92 -92
- package/lib/test-run/client-messages.js +9 -9
- package/lib/test-run/commands/actions.js +486 -425
- package/lib/test-run/commands/assertion.js +45 -45
- package/lib/test-run/commands/base.js +14 -14
- package/lib/test-run/commands/browser-manipulation.js +95 -95
- package/lib/test-run/commands/from-object.js +82 -82
- package/lib/test-run/commands/observation.js +61 -61
- package/lib/test-run/commands/options.js +231 -215
- package/lib/test-run/commands/service.js +54 -48
- package/lib/test-run/commands/type.js +65 -60
- package/lib/test-run/commands/utils.js +87 -87
- package/lib/test-run/commands/validations/argument.js +90 -90
- package/lib/test-run/commands/validations/factories.js +47 -47
- package/lib/test-run/commands/validations/initializers.js +44 -44
- package/lib/test-run/debug-log.js +32 -32
- package/lib/test-run/execute-js-expression.js +74 -74
- package/lib/test-run/index.js +823 -752
- package/lib/test-run/marker-symbol.js +7 -7
- package/lib/test-run/observed-callsites-storage.js +17 -17
- package/lib/test-run/phase.js +16 -16
- package/lib/test-run/session-controller.js +104 -104
- package/lib/testcafe.js +119 -114
- package/lib/utils/assignable.js +39 -39
- package/lib/utils/async-event-emitter.js +28 -28
- package/lib/utils/async-queue.js +14 -14
- package/lib/utils/browser-connection-timeouts.js +19 -19
- package/lib/utils/callsite.js +17 -17
- package/lib/utils/check-file-path.js +31 -31
- package/lib/utils/check-url.js +51 -51
- package/lib/utils/convert-to-best-fit-type.js +16 -16
- package/lib/utils/correct-file-path.js +21 -21
- package/lib/utils/define-lazy-property.js +13 -13
- package/lib/utils/delay.js +6 -6
- package/lib/utils/delegated-api.js +44 -44
- package/lib/utils/detect-display.js +6 -6
- package/lib/utils/detect-ffmpeg.js +44 -44
- package/lib/utils/diff/colors.js +29 -29
- package/lib/utils/diff/index.js +53 -53
- package/lib/utils/diff/util.js +24 -22
- package/lib/utils/diff.js +29 -29
- package/lib/utils/escape-user-agent.js +10 -10
- package/lib/utils/flag-list.js +17 -17
- package/lib/utils/get-any-key.js +8 -8
- package/lib/utils/get-browser.js +8 -8
- package/lib/utils/get-common-path.js +34 -34
- package/lib/utils/get-filter-fn.js +40 -40
- package/lib/utils/get-options/base.js +36 -36
- package/lib/utils/get-options/compiler.js +33 -33
- package/lib/utils/get-options/grep.js +15 -15
- package/lib/utils/get-options/index.js +21 -19
- package/lib/utils/get-options/meta.js +22 -22
- package/lib/utils/get-options/quarantine.js +92 -0
- package/lib/utils/get-options/screenshot.js +17 -17
- package/lib/utils/get-options/ssl.js +45 -45
- package/lib/utils/get-options/video.js +10 -10
- package/lib/utils/get-viewport-width.js +18 -18
- package/lib/utils/guard-time-execution.js +10 -10
- package/lib/utils/handle-errors.js +74 -74
- package/lib/utils/handle-tag-args.js +8 -8
- package/lib/utils/http.js +30 -30
- package/lib/utils/is-localhost.js +11 -11
- package/lib/utils/is-password-input.js +11 -0
- package/lib/utils/is-repl.js +12 -0
- package/lib/utils/is-window-in-iframe.js +6 -6
- package/lib/utils/limit-number.js +10 -10
- package/lib/utils/make-reg-exp.js +7 -7
- package/lib/utils/moment-loader.js +20 -20
- package/lib/utils/parse-file-list.js +71 -71
- package/lib/utils/parse-user-agent.js +55 -55
- package/lib/utils/path-pattern.js +114 -114
- package/lib/utils/prepare-reporters.js +30 -30
- package/lib/utils/prerender-callsite.js +18 -18
- package/lib/utils/process.js +119 -119
- package/lib/utils/promisified-functions.js +46 -46
- package/lib/utils/re-executable-promise.js +39 -39
- package/lib/utils/render-callsite-sync.js +29 -29
- package/lib/utils/render-template.js +10 -10
- package/lib/utils/reporter.js +30 -30
- package/lib/utils/resolve-path-relatively-cwd.js +7 -7
- package/lib/utils/string.js +105 -105
- package/lib/utils/temp-directory/cleanup-process/commands.js +7 -7
- package/lib/utils/temp-directory/cleanup-process/index.js +143 -143
- package/lib/utils/temp-directory/cleanup-process/worker.js +58 -58
- package/lib/utils/temp-directory/index.js +87 -87
- package/lib/utils/temp-directory/lockfile.js +56 -56
- package/lib/utils/thennable.js +7 -7
- package/lib/utils/timer.js +15 -15
- package/lib/utils/to-posix-path.js +8 -8
- package/lib/utils/types.js +2 -2
- package/lib/video-recorder/interfaces.js +2 -2
- package/lib/video-recorder/process.js +126 -126
- package/lib/video-recorder/recorder.js +136 -136
- package/lib/video-recorder/test-run-video-recorder.js +69 -69
- package/lib/video-recorder/videos.js +37 -37
- package/package.json +7 -7
- package/ts-defs/index.d.ts +109 -17
- package/ts-defs/selectors.d.ts +95 -7
- package/ts-defs/testcafe-scripts.d.ts +96 -8
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const path_1 = __importDefault(require("path"));
|
|
7
|
-
const debug_1 = __importDefault(require("debug"));
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const LOCKFILE_NAME = '.testcafe-lockfile';
|
|
10
|
-
const STALE_LOCKFILE_AGE = 2 * 24 * 60 * 60 * 1000;
|
|
11
|
-
const DEBUG_LOGGER = debug_1.default('testcafe:utils:temp-directory:lockfile');
|
|
12
|
-
class LockFile {
|
|
13
|
-
constructor(dirPath) {
|
|
14
|
-
this.path = path_1.default.join(dirPath, LOCKFILE_NAME);
|
|
15
|
-
}
|
|
16
|
-
_open({ force = false } = {}) {
|
|
17
|
-
try {
|
|
18
|
-
fs_1.default.writeFileSync(this.path, '', { flag: force ? 'w' : 'wx' });
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
catch (e) {
|
|
22
|
-
DEBUG_LOGGER('Failed to init lockfile ' + this.path);
|
|
23
|
-
DEBUG_LOGGER(e);
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
_isStale() {
|
|
28
|
-
const currentMs = Date.now();
|
|
29
|
-
try {
|
|
30
|
-
const { mtimeMs } = fs_1.default.statSync(this.path);
|
|
31
|
-
return currentMs - mtimeMs > STALE_LOCKFILE_AGE;
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
DEBUG_LOGGER('Failed to check status of lockfile ' + this.path);
|
|
35
|
-
DEBUG_LOGGER(e);
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
init() {
|
|
40
|
-
if (this._open())
|
|
41
|
-
return true;
|
|
42
|
-
if (this._isStale())
|
|
43
|
-
return this._open({ force: true });
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
dispose() {
|
|
47
|
-
try {
|
|
48
|
-
fs_1.default.unlinkSync(this.path);
|
|
49
|
-
}
|
|
50
|
-
catch (e) {
|
|
51
|
-
DEBUG_LOGGER('Failed to dispose lockfile ' + this.path);
|
|
52
|
-
DEBUG_LOGGER(e);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
exports.default = LockFile;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const debug_1 = __importDefault(require("debug"));
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const LOCKFILE_NAME = '.testcafe-lockfile';
|
|
10
|
+
const STALE_LOCKFILE_AGE = 2 * 24 * 60 * 60 * 1000;
|
|
11
|
+
const DEBUG_LOGGER = debug_1.default('testcafe:utils:temp-directory:lockfile');
|
|
12
|
+
class LockFile {
|
|
13
|
+
constructor(dirPath) {
|
|
14
|
+
this.path = path_1.default.join(dirPath, LOCKFILE_NAME);
|
|
15
|
+
}
|
|
16
|
+
_open({ force = false } = {}) {
|
|
17
|
+
try {
|
|
18
|
+
fs_1.default.writeFileSync(this.path, '', { flag: force ? 'w' : 'wx' });
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
DEBUG_LOGGER('Failed to init lockfile ' + this.path);
|
|
23
|
+
DEBUG_LOGGER(e);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
_isStale() {
|
|
28
|
+
const currentMs = Date.now();
|
|
29
|
+
try {
|
|
30
|
+
const { mtimeMs } = fs_1.default.statSync(this.path);
|
|
31
|
+
return currentMs - mtimeMs > STALE_LOCKFILE_AGE;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
DEBUG_LOGGER('Failed to check status of lockfile ' + this.path);
|
|
35
|
+
DEBUG_LOGGER(e);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
init() {
|
|
40
|
+
if (this._open())
|
|
41
|
+
return true;
|
|
42
|
+
if (this._isStale())
|
|
43
|
+
return this._open({ force: true });
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
dispose() {
|
|
47
|
+
try {
|
|
48
|
+
fs_1.default.unlinkSync(this.path);
|
|
49
|
+
}
|
|
50
|
+
catch (e) {
|
|
51
|
+
DEBUG_LOGGER('Failed to dispose lockfile ' + this.path);
|
|
52
|
+
DEBUG_LOGGER(e);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.default = LockFile;
|
|
57
57
|
module.exports = exports.default;
|
|
58
58
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9ja2ZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvdGVtcC1kaXJlY3RvcnkvbG9ja2ZpbGUuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsa0RBQTBCO0FBQzFCLDRDQUFvQjtBQUdwQixNQUFNLGFBQWEsR0FBUSxvQkFBb0IsQ0FBQztBQUNoRCxNQUFNLGtCQUFrQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDbkQsTUFBTSxZQUFZLEdBQVMsZUFBSyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7QUFFM0UsTUFBcUIsUUFBUTtJQUN6QixZQUFhLE9BQU87UUFDaEIsSUFBSSxDQUFDLElBQUksR0FBRyxjQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsS0FBSyxDQUFFLEVBQUUsS0FBSyxHQUFHLEtBQUssRUFBRSxHQUFHLEVBQUU7UUFDekIsSUFBSTtZQUNBLFlBQUUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7WUFFOUQsT0FBTyxJQUFJLENBQUM7U0FDZjtRQUNELE9BQU8sQ0FBQyxFQUFFO1lBQ04sWUFBWSxDQUFDLDBCQUEwQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyRCxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFaEIsT0FBTyxLQUFLLENBQUM7U0FDaEI7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNKLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUU3QixJQUFJO1lBQ0EsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLFlBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRTNDLE9BQU8sU0FBUyxHQUFHLE9BQU8sR0FBRyxrQkFBa0IsQ0FBQztTQUNuRDtRQUNELE9BQU8sQ0FBQyxFQUFFO1lBQ04sWUFBWSxDQUFDLHFDQUFxQyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoRSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFaEIsT0FBTyxLQUFLLENBQUM7U0FDaEI7SUFDTCxDQUFDO0lBRUQsSUFBSTtRQUNBLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRTtZQUNaLE9BQU8sSUFBSSxDQUFDO1FBRWhCLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNmLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRXZDLE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7SUFFRCxPQUFPO1FBQ0gsSUFBSTtZQUNBLFlBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQzVCO1FBQ0QsT0FBTyxDQUFDLEVBQUU7WUFDTixZQUFZLENBQUMsNkJBQTZCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3hELFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNuQjtJQUNMLENBQUM7Q0FDSjtBQXRERCwyQkFzREMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBkZWJ1ZyBmcm9tICdkZWJ1Zyc7XG5pbXBvcnQgZnMgZnJvbSAnZnMnO1xuXG5cbmNvbnN0IExPQ0tGSUxFX05BTUUgICAgICA9ICcudGVzdGNhZmUtbG9ja2ZpbGUnO1xuY29uc3QgU1RBTEVfTE9DS0ZJTEVfQUdFID0gMiAqIDI0ICogNjAgKiA2MCAqIDEwMDA7XG5jb25zdCBERUJVR19MT0dHRVIgICAgICAgPSBkZWJ1ZygndGVzdGNhZmU6dXRpbHM6dGVtcC1kaXJlY3Rvcnk6bG9ja2ZpbGUnKTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTG9ja0ZpbGUge1xuICAgIGNvbnN0cnVjdG9yIChkaXJQYXRoKSB7XG4gICAgICAgIHRoaXMucGF0aCA9IHBhdGguam9pbihkaXJQYXRoLCBMT0NLRklMRV9OQU1FKTtcbiAgICB9XG5cbiAgICBfb3BlbiAoeyBmb3JjZSA9IGZhbHNlIH0gPSB7fSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZnMud3JpdGVGaWxlU3luYyh0aGlzLnBhdGgsICcnLCB7IGZsYWc6IGZvcmNlID8gJ3cnIDogJ3d4JyB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIERFQlVHX0xPR0dFUignRmFpbGVkIHRvIGluaXQgbG9ja2ZpbGUgJyArIHRoaXMucGF0aCk7XG4gICAgICAgICAgICBERUJVR19MT0dHRVIoZSk7XG5cbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9pc1N0YWxlICgpIHtcbiAgICAgICAgY29uc3QgY3VycmVudE1zID0gRGF0ZS5ub3coKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3QgeyBtdGltZU1zIH0gPSBmcy5zdGF0U3luYyh0aGlzLnBhdGgpO1xuXG4gICAgICAgICAgICByZXR1cm4gY3VycmVudE1zIC0gbXRpbWVNcyA+IFNUQUxFX0xPQ0tGSUxFX0FHRTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgREVCVUdfTE9HR0VSKCdGYWlsZWQgdG8gY2hlY2sgc3RhdHVzIG9mIGxvY2tmaWxlICcgKyB0aGlzLnBhdGgpO1xuICAgICAgICAgICAgREVCVUdfTE9HR0VSKGUpO1xuXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbml0ICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX29wZW4oKSlcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgICAgIGlmICh0aGlzLl9pc1N0YWxlKCkpXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fb3Blbih7IGZvcmNlOiB0cnVlIH0pO1xuXG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBkaXNwb3NlICgpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZzLnVubGlua1N5bmModGhpcy5wYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgREVCVUdfTE9HR0VSKCdGYWlsZWQgdG8gZGlzcG9zZSBsb2NrZmlsZSAnICsgdGhpcy5wYXRoKTtcbiAgICAgICAgICAgIERFQlVHX0xPR0dFUihlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbiJdfQ==
|
package/lib/utils/thennable.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isThennable = void 0;
|
|
4
|
-
function isThennable(target) {
|
|
5
|
-
return target && typeof target === 'object' && 'then' in target && typeof target.then === 'function';
|
|
6
|
-
}
|
|
7
|
-
exports.isThennable = isThennable;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isThennable = void 0;
|
|
4
|
+
function isThennable(target) {
|
|
5
|
+
return target && typeof target === 'object' && 'then' in target && typeof target.then === 'function';
|
|
6
|
+
}
|
|
7
|
+
exports.isThennable = isThennable;
|
|
8
8
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhlbm5hYmxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL3RoZW5uYWJsZS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxTQUFnQixXQUFXLENBQUUsTUFBTTtJQUMvQixPQUFPLE1BQU0sSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksTUFBTSxJQUFJLE1BQU0sSUFBSSxPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFDO0FBQ3pHLENBQUM7QUFGRCxrQ0FFQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBmdW5jdGlvbiBpc1RoZW5uYWJsZSAodGFyZ2V0KSB7XG4gICAgcmV0dXJuIHRhcmdldCAmJiB0eXBlb2YgdGFyZ2V0ID09PSAnb2JqZWN0JyAmJiAndGhlbicgaW4gdGFyZ2V0ICYmIHR5cGVvZiB0YXJnZXQudGhlbiA9PT0gJ2Z1bmN0aW9uJztcbn1cbiJdfQ==
|
package/lib/utils/timer.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
class Timer {
|
|
4
|
-
constructor(timeout) {
|
|
5
|
-
this.expired = false;
|
|
6
|
-
this.promise = new Promise(resolve => {
|
|
7
|
-
setTimeout(resolve, timeout);
|
|
8
|
-
});
|
|
9
|
-
this.promise.then(() => this._expire());
|
|
10
|
-
}
|
|
11
|
-
_expire() {
|
|
12
|
-
this.expired = true;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.default = Timer;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class Timer {
|
|
4
|
+
constructor(timeout) {
|
|
5
|
+
this.expired = false;
|
|
6
|
+
this.promise = new Promise(resolve => {
|
|
7
|
+
setTimeout(resolve, timeout);
|
|
8
|
+
});
|
|
9
|
+
this.promise.then(() => this._expire());
|
|
10
|
+
}
|
|
11
|
+
_expire() {
|
|
12
|
+
this.expired = true;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.default = Timer;
|
|
16
16
|
module.exports = exports.default;
|
|
17
17
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdGltZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxNQUFxQixLQUFLO0lBSXRCLFlBQW9CLE9BQWU7UUFDL0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFFckIsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRTtZQUNqQyxVQUFVLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLENBQUMsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUVPLE9BQU87UUFDWCxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO0NBQ0o7QUFqQkQsd0JBaUJDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGRlZmF1bHQgY2xhc3MgVGltZXIge1xuICAgIHB1YmxpYyBleHBpcmVkOiBib29sZWFuO1xuICAgIHB1YmxpYyBwcm9taXNlOiBQcm9taXNlPHZvaWQ+O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yICh0aW1lb3V0OiBudW1iZXIpIHtcbiAgICAgICAgdGhpcy5leHBpcmVkID0gZmFsc2U7XG5cbiAgICAgICAgdGhpcy5wcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KHJlc29sdmUsIHRpbWVvdXQpO1xuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnByb21pc2UudGhlbigoKSA9PiB0aGlzLl9leHBpcmUoKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZXhwaXJlICgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5leHBpcmVkID0gdHJ1ZTtcbiAgICB9XG59XG4iXX0=
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const path_1 = require("path");
|
|
4
|
-
function default_1(val = '') {
|
|
5
|
-
return val.split(path_1.sep)
|
|
6
|
-
.join(path_1.posix.sep);
|
|
7
|
-
}
|
|
8
|
-
exports.default = default_1;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
function default_1(val = '') {
|
|
5
|
+
return val.split(path_1.sep)
|
|
6
|
+
.join(path_1.posix.sep);
|
|
7
|
+
}
|
|
8
|
+
exports.default = default_1;
|
|
9
9
|
module.exports = exports.default;
|
|
10
10
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG8tcG9zaXgtcGF0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy90by1wb3NpeC1wYXRoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQWtDO0FBRWxDLG1CQUF5QixNQUFjLEVBQUU7SUFDckMsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLFVBQUcsQ0FBQztTQUNoQixJQUFJLENBQUMsWUFBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFIRCw0QkFHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNlcCwgcG9zaXggfSBmcm9tICdwYXRoJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gKHZhbDogc3RyaW5nID0gJycpOiBzdHJpbmcge1xuICAgIHJldHVybiB2YWwuc3BsaXQoc2VwKVxuICAgICAgICAuam9pbihwb3NpeC5zZXApO1xufVxuIl19
|
package/lib/utils/types.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIEVudW1Gcm9tUHJvcGVydGllc09mPFQ+ID0ge1xuICAgIFtQIGluIGtleW9mIFRdOiBFeHRyYWN0PGtleW9mIFQsIFA+XG59XG4iXX0=
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92aWRlby1yZWNvcmRlci9pbnRlcmZhY2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgaW50ZXJmYWNlIFRlc3RSdW5WaWRlb0luZm8ge1xuICAgIHRlc3RSdW5JZDogc3RyaW5nO1xuICAgIHZpZGVvUGF0aDogc3RyaW5nO1xuICAgIHNpbmdsZUZpbGU6IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdFZpZGVvSW5mbyB7XG4gICAgcmVjb3JkaW5nczogVGVzdFJ1blZpZGVvSW5mb1tdO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RSdW5WaWRlb1NhdmVkRXZlbnRBcmdzIHtcbiAgICB0ZXN0UnVuOiB7IGlkOiBzdHJpbmc7IHRlc3Q6IHsgaWQ6IHN0cmluZyB9IH07XG4gICAgdmlkZW9QYXRoOiBzdHJpbmc7XG4gICAgc2luZ2xlRmlsZTogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBWaWRlb09wdGlvbnMge1xuICAgIHZpZGVvUGF0aDogc3RyaW5nO1xuICAgIHZpZGVvT3B0aW9uczogb2JqZWN0O1xuICAgIHZpZGVvRW5jb2RpbmdPcHRpb25zOiBvYmplY3Q7XG59XG4iXX0=
|
|
@@ -1,128 +1,128 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const debug_1 = __importDefault(require("debug"));
|
|
7
|
-
const child_process_1 = require("child_process");
|
|
8
|
-
const lodash_1 = require("lodash");
|
|
9
|
-
const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
|
|
10
|
-
const delay_1 = __importDefault(require("../utils/delay"));
|
|
11
|
-
const DEBUG_LOGGER_PREFIX = 'testcafe:video-recorder:process:';
|
|
12
|
-
const DEFAULT_OPTIONS = {
|
|
13
|
-
// NOTE: don't ask confirmation for rewriting the output file
|
|
14
|
-
'y': true,
|
|
15
|
-
// NOTE: use the time when a frame is read from the source as its timestamp
|
|
16
|
-
// IMPORTANT: must be specified before configuring the source
|
|
17
|
-
'use_wallclock_as_timestamps': 1,
|
|
18
|
-
// NOTE: use stdin as a source
|
|
19
|
-
'i': 'pipe:0',
|
|
20
|
-
// NOTE: use the H.264 video codec
|
|
21
|
-
'c:v': 'libx264',
|
|
22
|
-
// NOTE: use the 'ultrafast' compression preset
|
|
23
|
-
'preset': 'ultrafast',
|
|
24
|
-
// NOTE: use the yuv420p pixel format (the most widely supported)
|
|
25
|
-
'pix_fmt': 'yuv420p',
|
|
26
|
-
// NOTE: scale input frames to make the frame height divisible by 2 (yuv420p's requirement)
|
|
27
|
-
'vf': 'scale=trunc(iw/2)*2:trunc(ih/2)*2',
|
|
28
|
-
// NOTE: set the frame rate to 30 in the output video (the most widely supported)
|
|
29
|
-
'r': 30
|
|
30
|
-
};
|
|
31
|
-
const FFMPEG_START_DELAY = 500;
|
|
32
|
-
class VideoRecorder extends async_event_emitter_1.default {
|
|
33
|
-
constructor(basePath, ffmpegPath, connection, customOptions) {
|
|
34
|
-
super();
|
|
35
|
-
this.debugLogger = debug_1.default(DEBUG_LOGGER_PREFIX + connection.id);
|
|
36
|
-
this.customOptions = customOptions;
|
|
37
|
-
this.videoPath = basePath;
|
|
38
|
-
this.connection = connection;
|
|
39
|
-
this.ffmpegPath = ffmpegPath;
|
|
40
|
-
this.ffmpegProcess = null;
|
|
41
|
-
this.ffmpegStdoutBuf = '';
|
|
42
|
-
this.ffmpegStderrBuf = '';
|
|
43
|
-
this.ffmpegClosingPromise = null;
|
|
44
|
-
this.closed = false;
|
|
45
|
-
this.optionsList = this._getOptionsList();
|
|
46
|
-
this.capturingPromise = null;
|
|
47
|
-
}
|
|
48
|
-
static _filterOption([key, value]) {
|
|
49
|
-
if (value === true)
|
|
50
|
-
return ['-' + key];
|
|
51
|
-
return ['-' + key, value];
|
|
52
|
-
}
|
|
53
|
-
_setupFFMPEGBuffers() {
|
|
54
|
-
this.ffmpegProcess.stdout.on('data', data => {
|
|
55
|
-
this.ffmpegStdoutBuf += String(data);
|
|
56
|
-
});
|
|
57
|
-
this.ffmpegProcess.stderr.on('data', data => {
|
|
58
|
-
this.ffmpegStderrBuf += String(data);
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
_getChildProcessPromise() {
|
|
62
|
-
return new Promise((resolve, reject) => {
|
|
63
|
-
this.ffmpegProcess.on('exit', resolve);
|
|
64
|
-
this.ffmpegProcess.on('error', reject);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
_getOptionsList() {
|
|
68
|
-
const optionsObject = Object.assign({}, DEFAULT_OPTIONS, this.customOptions);
|
|
69
|
-
const optionsList = lodash_1.flatten(Object.entries(optionsObject).map(VideoRecorder._filterOption));
|
|
70
|
-
optionsList.push(this.videoPath);
|
|
71
|
-
return optionsList;
|
|
72
|
-
}
|
|
73
|
-
async _addFrame(frameData) {
|
|
74
|
-
const writingFinished = this.ffmpegProcess.stdin.write(frameData);
|
|
75
|
-
if (!writingFinished)
|
|
76
|
-
await new Promise(r => this.ffmpegProcess.stdin.once('drain', r));
|
|
77
|
-
}
|
|
78
|
-
async _capture() {
|
|
79
|
-
while (!this.closed) {
|
|
80
|
-
try {
|
|
81
|
-
const frame = await this.connection.provider.getVideoFrameData(this.connection.id);
|
|
82
|
-
if (frame) {
|
|
83
|
-
await this.emit('frame');
|
|
84
|
-
await this._addFrame(frame);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
catch (error) {
|
|
88
|
-
this.debugLogger(error);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
async init() {
|
|
93
|
-
this.ffmpegProcess = child_process_1.spawn(this.ffmpegPath, this.optionsList, { stdio: 'pipe' });
|
|
94
|
-
this._setupFFMPEGBuffers();
|
|
95
|
-
this.ffmpegClosingPromise = this
|
|
96
|
-
._getChildProcessPromise()
|
|
97
|
-
.then(code => {
|
|
98
|
-
this.closed = true;
|
|
99
|
-
if (code) {
|
|
100
|
-
this.debugLogger(code);
|
|
101
|
-
this.debugLogger(this.ffmpegStdoutBuf);
|
|
102
|
-
this.debugLogger(this.ffmpegStderrBuf);
|
|
103
|
-
}
|
|
104
|
-
})
|
|
105
|
-
.catch(error => {
|
|
106
|
-
this.closed = true;
|
|
107
|
-
this.debugLogger(error);
|
|
108
|
-
this.debugLogger(this.ffmpegStdoutBuf);
|
|
109
|
-
this.debugLogger(this.ffmpegStderrBuf);
|
|
110
|
-
});
|
|
111
|
-
await delay_1.default(FFMPEG_START_DELAY);
|
|
112
|
-
}
|
|
113
|
-
async startCapturing() {
|
|
114
|
-
this.capturingPromise = this._capture();
|
|
115
|
-
await this.once('frame');
|
|
116
|
-
}
|
|
117
|
-
async finishCapturing() {
|
|
118
|
-
if (this.closed)
|
|
119
|
-
return;
|
|
120
|
-
this.closed = true;
|
|
121
|
-
await this.capturingPromise;
|
|
122
|
-
this.ffmpegProcess.stdin.end();
|
|
123
|
-
await this.ffmpegClosingPromise;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
exports.default = VideoRecorder;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const debug_1 = __importDefault(require("debug"));
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const lodash_1 = require("lodash");
|
|
9
|
+
const async_event_emitter_1 = __importDefault(require("../utils/async-event-emitter"));
|
|
10
|
+
const delay_1 = __importDefault(require("../utils/delay"));
|
|
11
|
+
const DEBUG_LOGGER_PREFIX = 'testcafe:video-recorder:process:';
|
|
12
|
+
const DEFAULT_OPTIONS = {
|
|
13
|
+
// NOTE: don't ask confirmation for rewriting the output file
|
|
14
|
+
'y': true,
|
|
15
|
+
// NOTE: use the time when a frame is read from the source as its timestamp
|
|
16
|
+
// IMPORTANT: must be specified before configuring the source
|
|
17
|
+
'use_wallclock_as_timestamps': 1,
|
|
18
|
+
// NOTE: use stdin as a source
|
|
19
|
+
'i': 'pipe:0',
|
|
20
|
+
// NOTE: use the H.264 video codec
|
|
21
|
+
'c:v': 'libx264',
|
|
22
|
+
// NOTE: use the 'ultrafast' compression preset
|
|
23
|
+
'preset': 'ultrafast',
|
|
24
|
+
// NOTE: use the yuv420p pixel format (the most widely supported)
|
|
25
|
+
'pix_fmt': 'yuv420p',
|
|
26
|
+
// NOTE: scale input frames to make the frame height divisible by 2 (yuv420p's requirement)
|
|
27
|
+
'vf': 'scale=trunc(iw/2)*2:trunc(ih/2)*2',
|
|
28
|
+
// NOTE: set the frame rate to 30 in the output video (the most widely supported)
|
|
29
|
+
'r': 30
|
|
30
|
+
};
|
|
31
|
+
const FFMPEG_START_DELAY = 500;
|
|
32
|
+
class VideoRecorder extends async_event_emitter_1.default {
|
|
33
|
+
constructor(basePath, ffmpegPath, connection, customOptions) {
|
|
34
|
+
super();
|
|
35
|
+
this.debugLogger = debug_1.default(DEBUG_LOGGER_PREFIX + connection.id);
|
|
36
|
+
this.customOptions = customOptions;
|
|
37
|
+
this.videoPath = basePath;
|
|
38
|
+
this.connection = connection;
|
|
39
|
+
this.ffmpegPath = ffmpegPath;
|
|
40
|
+
this.ffmpegProcess = null;
|
|
41
|
+
this.ffmpegStdoutBuf = '';
|
|
42
|
+
this.ffmpegStderrBuf = '';
|
|
43
|
+
this.ffmpegClosingPromise = null;
|
|
44
|
+
this.closed = false;
|
|
45
|
+
this.optionsList = this._getOptionsList();
|
|
46
|
+
this.capturingPromise = null;
|
|
47
|
+
}
|
|
48
|
+
static _filterOption([key, value]) {
|
|
49
|
+
if (value === true)
|
|
50
|
+
return ['-' + key];
|
|
51
|
+
return ['-' + key, value];
|
|
52
|
+
}
|
|
53
|
+
_setupFFMPEGBuffers() {
|
|
54
|
+
this.ffmpegProcess.stdout.on('data', data => {
|
|
55
|
+
this.ffmpegStdoutBuf += String(data);
|
|
56
|
+
});
|
|
57
|
+
this.ffmpegProcess.stderr.on('data', data => {
|
|
58
|
+
this.ffmpegStderrBuf += String(data);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
_getChildProcessPromise() {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
this.ffmpegProcess.on('exit', resolve);
|
|
64
|
+
this.ffmpegProcess.on('error', reject);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
_getOptionsList() {
|
|
68
|
+
const optionsObject = Object.assign({}, DEFAULT_OPTIONS, this.customOptions);
|
|
69
|
+
const optionsList = lodash_1.flatten(Object.entries(optionsObject).map(VideoRecorder._filterOption));
|
|
70
|
+
optionsList.push(this.videoPath);
|
|
71
|
+
return optionsList;
|
|
72
|
+
}
|
|
73
|
+
async _addFrame(frameData) {
|
|
74
|
+
const writingFinished = this.ffmpegProcess.stdin.write(frameData);
|
|
75
|
+
if (!writingFinished)
|
|
76
|
+
await new Promise(r => this.ffmpegProcess.stdin.once('drain', r));
|
|
77
|
+
}
|
|
78
|
+
async _capture() {
|
|
79
|
+
while (!this.closed) {
|
|
80
|
+
try {
|
|
81
|
+
const frame = await this.connection.provider.getVideoFrameData(this.connection.id);
|
|
82
|
+
if (frame) {
|
|
83
|
+
await this.emit('frame');
|
|
84
|
+
await this._addFrame(frame);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.debugLogger(error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async init() {
|
|
93
|
+
this.ffmpegProcess = child_process_1.spawn(this.ffmpegPath, this.optionsList, { stdio: 'pipe' });
|
|
94
|
+
this._setupFFMPEGBuffers();
|
|
95
|
+
this.ffmpegClosingPromise = this
|
|
96
|
+
._getChildProcessPromise()
|
|
97
|
+
.then(code => {
|
|
98
|
+
this.closed = true;
|
|
99
|
+
if (code) {
|
|
100
|
+
this.debugLogger(code);
|
|
101
|
+
this.debugLogger(this.ffmpegStdoutBuf);
|
|
102
|
+
this.debugLogger(this.ffmpegStderrBuf);
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
.catch(error => {
|
|
106
|
+
this.closed = true;
|
|
107
|
+
this.debugLogger(error);
|
|
108
|
+
this.debugLogger(this.ffmpegStdoutBuf);
|
|
109
|
+
this.debugLogger(this.ffmpegStderrBuf);
|
|
110
|
+
});
|
|
111
|
+
await delay_1.default(FFMPEG_START_DELAY);
|
|
112
|
+
}
|
|
113
|
+
async startCapturing() {
|
|
114
|
+
this.capturingPromise = this._capture();
|
|
115
|
+
await this.once('frame');
|
|
116
|
+
}
|
|
117
|
+
async finishCapturing() {
|
|
118
|
+
if (this.closed)
|
|
119
|
+
return;
|
|
120
|
+
this.closed = true;
|
|
121
|
+
await this.capturingPromise;
|
|
122
|
+
this.ffmpegProcess.stdin.end();
|
|
123
|
+
await this.ffmpegClosingPromise;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
exports.default = VideoRecorder;
|
|
127
127
|
module.exports = exports.default;
|
|
128
128
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvY2Vzcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy92aWRlby1yZWNvcmRlci9wcm9jZXNzLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsa0RBQTBCO0FBQzFCLGlEQUFzQztBQUN0QyxtQ0FBaUM7QUFDakMsdUZBQXdEO0FBQ3hELDJEQUFtQztBQUduQyxNQUFNLG1CQUFtQixHQUFHLGtDQUFrQyxDQUFDO0FBRS9ELE1BQU0sZUFBZSxHQUFHO0lBQ3BCLDZEQUE2RDtJQUM3RCxHQUFHLEVBQUUsSUFBSTtJQUVULDJFQUEyRTtJQUMzRSw2REFBNkQ7SUFDN0QsNkJBQTZCLEVBQUUsQ0FBQztJQUVoQyw4QkFBOEI7SUFDOUIsR0FBRyxFQUFFLFFBQVE7SUFFYixrQ0FBa0M7SUFDbEMsS0FBSyxFQUFFLFNBQVM7SUFFaEIsK0NBQStDO0lBQy9DLFFBQVEsRUFBRSxXQUFXO0lBRXJCLGlFQUFpRTtJQUNqRSxTQUFTLEVBQUUsU0FBUztJQUVwQiwyRkFBMkY7SUFDM0YsSUFBSSxFQUFFLG1DQUFtQztJQUV6QyxpRkFBaUY7SUFDakYsR0FBRyxFQUFFLEVBQUU7Q0FDVixDQUFDO0FBRUYsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFFL0IsTUFBcUIsYUFBYyxTQUFRLDZCQUFZO0lBQ25ELFlBQWEsUUFBUSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsYUFBYTtRQUN4RCxLQUFLLEVBQUUsQ0FBQztRQUVSLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBSyxDQUFDLG1CQUFtQixHQUFHLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUU5RCxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsU0FBUyxHQUFPLFFBQVEsQ0FBQztRQUM5QixJQUFJLENBQUMsVUFBVSxHQUFNLFVBQVUsQ0FBQztRQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFNLFVBQVUsQ0FBQztRQUNoQyxJQUFJLENB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QUFFLENBQUM7UUFFeEMsTUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZTtRQUNqQixJQUFJLElBQUksQ0FBQyxNQUFNO1lBQ1gsT0FBTztRQUVYLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBRW5CLE1BQU0sSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBRTVCLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRS9CLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixDQUFDO0lBQ3BDLENBQUM7Q0FDSjtBQTlIRCxnQ0E4SEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZGVidWcgZnJvbSAnZGVidWcnO1xuaW1wb3J0IHsgc3Bhd24gfSBmcm9tICdjaGlsZF9wcm9jZXNzJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEFzeW5jRW1pdHRlciBmcm9tICcuLi91dGlscy9hc3luYy1ldmVudC1lbWl0dGVyJztcbmltcG9ydCBkZWxheSBmcm9tICcuLi91dGlscy9kZWxheSc7XG5cblxuY29uc3QgREVCVUdfTE9HR0VSX1BSRUZJWCA9ICd0ZXN0Y2FmZTp2aWRlby1yZWNvcmRlcjpwcm9jZXNzOic7XG5cbmNvbnN0IERFRkFVTFRfT1BUSU9OUyA9IHtcbiAgICAvLyBOT1RFOiBkb24ndCBhc2sgY29uZmlybWF0aW9uIGZvciByZXdyaXRpbmcgdGhlIG91dHB1dCBmaWxlXG4gICAgJ3knOiB0cnVlLFxuXG4gICAgLy8gTk9URTogdXNlIHRoZSB0aW1lIHdoZW4gYSBmcmFtZSBpcyByZWFkIGZyb20gdGhlIHNvdXJjZSBhcyBpdHMgdGltZXN0YW1wXG4gICAgLy8gSU1QT1JUQU5UOiBtdXN0IGJlIHNwZWNpZmllZCBiZWZvcmUgY29uZmlndXJpbmcgdGhlIHNvdXJjZVxuICAgICd1c2Vfd2FsbGNsb2NrX2FzX3RpbWVzdGFtcHMnOiAxLFxuXG4gICAgLy8gTk9URTogdXNlIHN0ZGluIGFzIGEgc291cmNlXG4gICAgJ2knOiAncGlwZTowJyxcblxuICAgIC8vIE5PVEU6IHVzZSB0aGUgSC4yNjQgdmlkZW8gY29kZWNcbiAgICAnYzp2JzogJ2xpYngyNjQnLFxuXG4gICAgLy8gTk9URTogdXNlIHRoZSAndWx0cmFmYXN0JyBjb21wcmVzc2lvbiBwcmVzZXRcbiAgICAncHJlc2V0JzogJ3VsdHJhZmFzdCcsXG5cbiAgICAvLyBOT1RFOiB1c2UgdGhlIHl1djQyMHAgcGl4ZWwgZm9ybWF0ICh0aGUgbW9zdCB3aWRlbHkgc3VwcG9ydGVkKVxuICAgICdwaXhfZm10JzogJ3l1djQyMHAnLFxuXG4gICAgLy8gTk9URTogc2NhbGUgaW5wdXQgZnJhbWVzIHRvIG1ha2UgdGhlIGZyYW1lIGhlaWdodCBkaXZpc2libGUgYnkgMiAoeXV2NDIwcCdzIHJlcXVpcmVtZW50KVxuICAgICd2Zic6ICdzY2FsZT10cnVuYyhpdy8yKSoyOnRydW5jKGloLzIpKjInLFxuXG4gICAgLy8gTk9URTogc2V0IHRoZSBmcmFtZSByYXRlIHRvIDMwIGluIHRoZSBvdXRwdXQgdmlkZW8gKHRoZSBtb3N0IHdpZGVseSBzdXBwb3J0ZWQpXG4gICAgJ3InOiAzMFxufTtcblxuY29uc3QgRkZNUEVHX1NUQVJUX0RFTEFZID0gNTAwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWRlb1JlY29yZGVyIGV4dGVuZHMgQXN5bmNFbWl0dGVyIHtcbiAgICBjb25zdHJ1Y3RvciAoYmFzZVBhdGgsIGZmbXBlZ1BhdGgsIGNvbm5lY3Rpb24sIGN1c3RvbU9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICB0aGlzLmRlYnVnTG9nZ2VyID0gZGVidWcoREVCVUdfTE9HR0VSX1BSRUZJWCArIGNvbm5lY3Rpb24uaWQpO1xuXG4gICAgICAgIHRoaXMuY3VzdG9tT3B0aW9ucyA9IGN1c3RvbU9wdGlvbnM7XG4gICAgICAgIHRoaXMudmlkZW9QYXRoICAgICA9IGJhc2VQYXRoO1xuICAgICAgICB0aGlzLmNvbm5lY3Rpb24gICAgPSBjb25uZWN0aW9uO1xuICAgICAgICB0aGlzLmZmbXBlZ1BhdGggICAgPSBmZm1wZWdQYXRoO1xuICAgICAgICB0aGlzLmZmbXBlZ1Byb2Nlc3MgPSBudWxsO1xuXG4gICAgICAgIHRoaXMuZmZtcGVnU3Rkb3V0QnVmID0gJyc7XG4gICAgICAgIHRoaXMuZmZtcGVnU3RkZXJyQnVmID0gJyc7XG5cbiAgICAgICAgdGhpcy5mZm1wZWdDbG9zaW5nUHJvbWlzZSA9IG51bGw7XG5cbiAgICAgICAgdGhpcy5jbG9zZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLm9wdGlvbnNMaXN0ID0gdGhpcy5fZ2V0T3B0aW9uc0xpc3QoKTtcblxuICAgICAgICB0aGlzLmNhcHR1cmluZ1Byb21pc2UgPSBudWxsO1xuICAgIH1cblxuICAgIHN0YXRpYyBfZmlsdGVyT3B0aW9uIChba2V5LCB2YWx1ZV0pIHtcbiAgICAgICAgaWYgKHZhbHVlID09PSB0cnVlKVxuICAgICAgICAgICAgcmV0dXJuIFsnLScgKyBrZXldO1xuXG4gICAgICAgIHJldHVybiBbJy0nICsga2V5LCB2YWx1ZV07XG4gICAgfVxuXG4gICAgX3NldHVwRkZNUEVHQnVmZmVycyAoKSB7XG4gICAgICAgIHRoaXMuZmZtcGVnUHJvY2Vzcy5zdGRvdXQub24oJ2RhdGEnLCBkYXRhID0+IHtcbiAgICAgICAgICAgIHRoaXMuZmZtcGVnU3Rkb3V0QnVmICs9IFN0cmluZyhkYXRhKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5mZm1wZWdQcm9jZXNzLnN0ZGVyci5vbignZGF0YScsIGRhdGEgPT4ge1xuICAgICAgICAgICAgdGhpcy5mZm1wZWdTdGRlcnJCdWYgKz0gU3RyaW5nKGRhdGEpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfZ2V0Q2hpbGRQcm9jZXNzUHJvbWlzZSAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICB0aGlzLmZmbXBlZ1Byb2Nlc3Mub24oJ2V4aXQnLCByZXNvbHZlKTtcbiAgICAgICAgICAgIHRoaXMuZmZtcGVnUHJvY2Vzcy5vbignZXJyb3InLCByZWplY3QpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBfZ2V0T3B0aW9uc0xpc3QgKCkge1xuICAgICAgICBjb25zdCBvcHRpb25zT2JqZWN0ID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCB0aGlzLmN1c3RvbU9wdGlvbnMpO1xuXG4gICAgICAgIGNvbnN0IG9wdGlvbnNMaXN0ID0gZmxhdHRlbihPYmplY3QuZW50cmllcyhvcHRpb25zT2JqZWN0KS5tYXAoVmlkZW9SZWNvcmRlci5fZmlsdGVyT3B0aW9uKSk7XG5cbiAgICAgICAgb3B0aW9uc0xpc3QucHVzaCh0aGlzLnZpZGVvUGF0aCk7XG5cbiAgICAgICAgcmV0dXJuIG9wdGlvbnNMaXN0O1xuICAgIH1cblxuICAgIGFzeW5jIF9hZGRGcmFtZSAoZnJhbWVEYXRhKSB7XG4gICAgICAgIGNvbnN0IHdyaXRpbmdGaW5pc2hlZCA9IHRoaXMuZmZtcGVnUHJvY2Vzcy5zdGRpbi53cml0ZShmcmFtZURhdGEpO1xuXG4gICAgICAgIGlmICghd3JpdGluZ0ZpbmlzaGVkKVxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2UociA9PiB0aGlzLmZmbXBlZ1Byb2Nlc3Muc3RkaW4ub25jZSgnZHJhaW4nLCByKSk7XG4gICAgfVxuXG4gICAgYXN5bmMgX2NhcHR1cmUgKCkge1xuICAgICAgICB3aGlsZSAoIXRoaXMuY2xvc2VkKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGNvbnN0IGZyYW1lID0gYXdhaXQgdGhpcy5jb25uZWN0aW9uLnByb3ZpZGVyLmdldFZpZGVvRnJhbWVEYXRhKHRoaXMuY29ubmVjdGlvbi5pZCk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZnJhbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5lbWl0KCdmcmFtZScpO1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLl9hZGRGcmFtZShmcmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlcihlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBhc3luYyBpbml0ICgpIHtcbiAgICAgICAgdGhpcy5mZm1wZWdQcm9jZXNzID0gc3Bhd24odGhpcy5mZm1wZWdQYXRoLCB0aGlzLm9wdGlvbnNMaXN0LCB7IHN0ZGlvOiAncGlwZScgfSk7XG5cbiAgICAgICAgdGhpcy5fc2V0dXBGRk1QRUdCdWZmZXJzKCk7XG5cbiAgICAgICAgdGhpcy5mZm1wZWdDbG9zaW5nUHJvbWlzZSA9IHRoaXNcbiAgICAgICAgICAgIC5fZ2V0Q2hpbGRQcm9jZXNzUHJvbWlzZSgpXG4gICAgICAgICAgICAudGhlbihjb2RlID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlZCA9IHRydWU7XG5cbiAgICAgICAgICAgICAgICBpZiAoY29kZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlYnVnTG9nZ2VyKGNvZGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRlYnVnTG9nZ2VyKHRoaXMuZmZtcGVnU3Rkb3V0QnVmKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlcih0aGlzLmZmbXBlZ1N0ZGVyckJ1Zik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5jYXRjaChlcnJvciA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlcihlcnJvcik7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlcih0aGlzLmZmbXBlZ1N0ZG91dEJ1Zik7XG4gICAgICAgICAgICAgICAgdGhpcy5kZWJ1Z0xvZ2dlcih0aGlzLmZmbXBlZ1N0ZGVyckJ1Zik7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICBhd2FpdCBkZWxheShGRk1QRUdfU1RBUlRfREVMQVkpO1xuICAgIH1cblxuICAgIGFzeW5jIHN0YXJ0Q2FwdHVyaW5nICgpIHtcbiAgICAgICAgdGhpcy5jYXB0dXJpbmdQcm9taXNlID0gdGhpcy5fY2FwdHVyZSgpO1xuXG4gICAgICAgIGF3YWl0IHRoaXMub25jZSgnZnJhbWUnKTtcbiAgICB9XG5cbiAgICBhc3luYyBmaW5pc2hDYXB0dXJpbmcgKCkge1xuICAgICAgICBpZiAodGhpcy5jbG9zZWQpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlO1xuXG4gICAgICAgIGF3YWl0IHRoaXMuY2FwdHVyaW5nUHJvbWlzZTtcblxuICAgICAgICB0aGlzLmZmbXBlZ1Byb2Nlc3Muc3RkaW4uZW5kKCk7XG5cbiAgICAgICAgYXdhaXQgdGhpcy5mZm1wZWdDbG9zaW5nUHJvbWlzZTtcbiAgICB9XG59XG4iXX0=
|