@testim/testim-cli 3.288.0 → 3.290.0-beta

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 (217) hide show
  1. package/cli.js +22390 -122
  2. package/cli.js.map +1 -0
  3. package/npm-shrinkwrap.json +8 -29129
  4. package/package.json +16 -10
  5. package/OverrideTestDataBuilder.js +0 -117
  6. package/agent/routers/cliJsCode/index.js +0 -13
  7. package/agent/routers/cliJsCode/router.js +0 -63
  8. package/agent/routers/cliJsCode/service.js +0 -705
  9. package/agent/routers/codim/router.js +0 -69
  10. package/agent/routers/codim/router.test.js +0 -60
  11. package/agent/routers/codim/service.js +0 -193
  12. package/agent/routers/general/index.js +0 -36
  13. package/agent/routers/hybrid/registerRoutes.js +0 -81
  14. package/agent/routers/index.js +0 -56
  15. package/agent/routers/playground/router.js +0 -77
  16. package/agent/routers/playground/service.js +0 -96
  17. package/agent/routers/standalone-browser/registerRoutes.js +0 -47
  18. package/agent/server.js +0 -150
  19. package/cdpTestRunner.js +0 -86
  20. package/chromiumInstaller.js +0 -91
  21. package/cli/isCiRun.js +0 -10
  22. package/cli/onExit.js +0 -65
  23. package/cli/writeStackTrace.js +0 -27
  24. package/cliAgentMode.js +0 -384
  25. package/codim/codim-cli.js +0 -91
  26. package/codim/codim-npm-package/index.ts +0 -427
  27. package/codim/codim-npm-package/package-lock.json +0 -14
  28. package/codim/codim-npm-package/package.json +0 -14
  29. package/codim/hybrid-utils.js +0 -28
  30. package/codim/measure-perf.js +0 -41
  31. package/codim/template.js/.idea/workspace.xml +0 -57
  32. package/codim/template.js/.vscode/launch.json +0 -53
  33. package/codim/template.ts/.idea/workspace.xml +0 -57
  34. package/codim/template.ts/.vscode/launch.json +0 -55
  35. package/commons/AbortError.js +0 -12
  36. package/commons/SeleniumPerfStats.js +0 -58
  37. package/commons/chrome-launcher.js +0 -15
  38. package/commons/chromedriverWrapper.js +0 -70
  39. package/commons/config.js +0 -39
  40. package/commons/constants.js +0 -67
  41. package/commons/detectDebugger.js +0 -19
  42. package/commons/featureAvailabilityService.js +0 -26
  43. package/commons/featureFlags.js +0 -132
  44. package/commons/getSessionPlayerRequire.js +0 -28
  45. package/commons/httpRequest.js +0 -261
  46. package/commons/httpRequestCounters.js +0 -98
  47. package/commons/httpRequestCounters.test.js +0 -38
  48. package/commons/initializeUserWithAuth.js +0 -55
  49. package/commons/lazyRequire.js +0 -105
  50. package/commons/logUtils.js +0 -15
  51. package/commons/logUtils.test.js +0 -21
  52. package/commons/logger.js +0 -178
  53. package/commons/mockNetworkRuleFileSchema.json +0 -140
  54. package/commons/npmWrapper.js +0 -174
  55. package/commons/npmWrapper.test.js +0 -374
  56. package/commons/performance-logger.js +0 -71
  57. package/commons/preloadTests.js +0 -29
  58. package/commons/prepareRunner.js +0 -85
  59. package/commons/prepareRunner.test.js +0 -144
  60. package/commons/prepareRunnerAndTestimStartUtils.js +0 -198
  61. package/commons/prepareRunnerAndTestimStartUtils.test.js +0 -73
  62. package/commons/requireWithFallback.js +0 -25
  63. package/commons/runnerFileCache.js +0 -204
  64. package/commons/socket/baseSocketServiceSocketIO.js +0 -197
  65. package/commons/socket/realDataService.js +0 -59
  66. package/commons/socket/realDataServiceSocketIO.js +0 -33
  67. package/commons/socket/remoteStepService.js +0 -55
  68. package/commons/socket/remoteStepServiceSocketIO.js +0 -61
  69. package/commons/socket/socketService.js +0 -175
  70. package/commons/socket/testResultService.js +0 -62
  71. package/commons/socket/testResultServiceSocketIO.js +0 -64
  72. package/commons/testimAnalytics.js +0 -40
  73. package/commons/testimCloudflare.js +0 -83
  74. package/commons/testimCloudflare.test.js +0 -185
  75. package/commons/testimCustomToken.js +0 -124
  76. package/commons/testimDesiredCapabilitiesBuilder.js +0 -647
  77. package/commons/testimNgrok.js +0 -90
  78. package/commons/testimNgrok.test.js +0 -140
  79. package/commons/testimServicesApi.js +0 -631
  80. package/commons/testimTunnel.js +0 -73
  81. package/commons/testimTunnel.test.js +0 -172
  82. package/commons/xhr2.js +0 -897
  83. package/coverage/SummaryToObjectReport.js +0 -19
  84. package/coverage/jsCoverage.js +0 -252
  85. package/credentialsManager.js +0 -142
  86. package/errors.js +0 -161
  87. package/executionQueue.js +0 -37
  88. package/fixLocalBuild.js +0 -24
  89. package/inputFileUtils.js +0 -103
  90. package/lib/coralogix-winston.transport.js +0 -99
  91. package/player/SeleniumProtocolError.js +0 -100
  92. package/player/WebDriverHttpRequest.js +0 -177
  93. package/player/WebdriverioWebDriverApi.js +0 -671
  94. package/player/appiumTestPlayer.js +0 -90
  95. package/player/chromeLauncherTestPlayer.js +0 -67
  96. package/player/constants.js +0 -332
  97. package/player/extensionTestPlayer.js +0 -32
  98. package/player/findElementStrategy.js +0 -154
  99. package/player/scripts/isElementDisplayed.js +0 -252
  100. package/player/seleniumTestPlayer.js +0 -140
  101. package/player/services/frameLocator.js +0 -170
  102. package/player/services/mobileFrameLocatorMock.js +0 -32
  103. package/player/services/playbackTimeoutCalculator.js +0 -175
  104. package/player/services/portSelector.js +0 -19
  105. package/player/services/tabService.js +0 -551
  106. package/player/services/tabServiceMock.js +0 -167
  107. package/player/services/windowCreationListener.js +0 -8
  108. package/player/stepActions/RefreshStepAction.js +0 -16
  109. package/player/stepActions/apiStepAction.js +0 -89
  110. package/player/stepActions/baseCliJsStepAction.js +0 -51
  111. package/player/stepActions/baseJsStepAction.js +0 -277
  112. package/player/stepActions/cliConditionStepAction.js +0 -11
  113. package/player/stepActions/cliJsStepAction.js +0 -11
  114. package/player/stepActions/dropFileStepAction.js +0 -34
  115. package/player/stepActions/evaluateExpressionStepAction.js +0 -52
  116. package/player/stepActions/extensionOnlyStepAction.js +0 -12
  117. package/player/stepActions/extractTextStepAction.js +0 -19
  118. package/player/stepActions/hoverStepAction.js +0 -55
  119. package/player/stepActions/inputFileStepAction.js +0 -199
  120. package/player/stepActions/jsCodeStepAction.js +0 -11
  121. package/player/stepActions/jsConditionStepAction.js +0 -11
  122. package/player/stepActions/locateStepAction.js +0 -159
  123. package/player/stepActions/mouseStepAction.js +0 -370
  124. package/player/stepActions/navigationStepAction.js +0 -29
  125. package/player/stepActions/nodePackageStepAction.js +0 -47
  126. package/player/stepActions/pixelValidationStepAction.js +0 -39
  127. package/player/stepActions/scripts/dispatchEvents.js +0 -282
  128. package/player/stepActions/scripts/doClick.js +0 -221
  129. package/player/stepActions/scripts/doDragPath.js +0 -225
  130. package/player/stepActions/scripts/doubleClick.js +0 -119
  131. package/player/stepActions/scripts/dropEvent.js +0 -63
  132. package/player/stepActions/scripts/focusElement.js +0 -46
  133. package/player/stepActions/scripts/html5dragAction.js +0 -56
  134. package/player/stepActions/scripts/html5dragActionV2.js +0 -312
  135. package/player/stepActions/scripts/runCode.js +0 -147
  136. package/player/stepActions/scripts/scroll.js +0 -90
  137. package/player/stepActions/scripts/selectOption.js +0 -51
  138. package/player/stepActions/scripts/setText.js +0 -415
  139. package/player/stepActions/scripts/wheel.js +0 -61
  140. package/player/stepActions/scrollStepAction.js +0 -96
  141. package/player/stepActions/selectOptionStepAction.js +0 -49
  142. package/player/stepActions/sfdcRecordedStepAction.js +0 -24
  143. package/player/stepActions/sfdcStepAction.js +0 -28
  144. package/player/stepActions/sleepStepAction.js +0 -12
  145. package/player/stepActions/specialKeyStepAction.js +0 -52
  146. package/player/stepActions/stepAction.js +0 -73
  147. package/player/stepActions/stepActionRegistrar.js +0 -111
  148. package/player/stepActions/submitStepAction.js +0 -12
  149. package/player/stepActions/tdkHybridStepAction.js +0 -18
  150. package/player/stepActions/textStepAction.js +0 -110
  151. package/player/stepActions/textValidationStepAction.js +0 -64
  152. package/player/stepActions/wheelStepAction.js +0 -41
  153. package/player/utils/cookieUtils.js +0 -39
  154. package/player/utils/eyeSdkService.js +0 -250
  155. package/player/utils/imageCaptureUtils.js +0 -267
  156. package/player/utils/screenshotUtils.js +0 -68
  157. package/player/utils/stepActionUtils.js +0 -90
  158. package/player/utils/windowUtils.js +0 -195
  159. package/player/webDriverUtils.js +0 -40
  160. package/player/webDriverUtils.test.js +0 -116
  161. package/player/webdriver.js +0 -976
  162. package/polyfills/Array.prototype.at.js +0 -13
  163. package/polyfills/index.js +0 -9
  164. package/processHandler.js +0 -79
  165. package/processHandler.test.js +0 -55
  166. package/reports/chromeReporter.js +0 -17
  167. package/reports/consoleReporter.js +0 -190
  168. package/reports/debugReporter.js +0 -82
  169. package/reports/jsonReporter.js +0 -55
  170. package/reports/junitReporter.js +0 -183
  171. package/reports/reporter.js +0 -166
  172. package/reports/reporterUtils.js +0 -54
  173. package/reports/teamCityReporter.js +0 -73
  174. package/runOptions.d.ts +0 -305
  175. package/runOptions.js +0 -1288
  176. package/runOptionsAgentFlow.js +0 -87
  177. package/runOptionsUtils.js +0 -60
  178. package/runner.js +0 -355
  179. package/runners/ParallelWorkerManager.js +0 -284
  180. package/runners/TestPlanRunner.js +0 -419
  181. package/runners/buildCodeTests.js +0 -159
  182. package/runners/runnerUtils.js +0 -81
  183. package/services/analyticsService.js +0 -96
  184. package/services/branchService.js +0 -29
  185. package/services/gridService.js +0 -357
  186. package/services/gridService.test.js +0 -357
  187. package/services/labFeaturesService.js +0 -64
  188. package/services/lambdatestService.js +0 -227
  189. package/services/lambdatestService.test.js +0 -353
  190. package/services/localRCASaver.js +0 -124
  191. package/stepPlayers/cliJsStepPlayback.js +0 -40
  192. package/stepPlayers/hybridStepPlayback.js +0 -140
  193. package/stepPlayers/nodePackageStepPlayback.js +0 -28
  194. package/stepPlayers/playwrightHybridStepPlayback.js +0 -61
  195. package/stepPlayers/puppeteerHybridStepPlayback.js +0 -76
  196. package/stepPlayers/remoteStepPlayback.js +0 -80
  197. package/stepPlayers/seleniumHybridStepPlayback.js +0 -84
  198. package/stepPlayers/tdkHybridStepPlayback.js +0 -112
  199. package/testRunHandler.js +0 -603
  200. package/testRunStatus.js +0 -567
  201. package/testimNpmDriver.js +0 -52
  202. package/utils/argsUtils.js +0 -91
  203. package/utils/argsUtils.test.js +0 -32
  204. package/utils/fsUtils.js +0 -174
  205. package/utils/index.js +0 -197
  206. package/utils/promiseUtils.js +0 -85
  207. package/utils/stringUtils.js +0 -98
  208. package/utils/stringUtils.test.js +0 -22
  209. package/utils/timeUtils.js +0 -25
  210. package/utils/utils.test.js +0 -27
  211. package/workers/BaseWorker.js +0 -498
  212. package/workers/BaseWorker.test.js +0 -186
  213. package/workers/WorkerAppium.js +0 -180
  214. package/workers/WorkerExtension.js +0 -192
  215. package/workers/WorkerExtensionSingleBrowser.js +0 -77
  216. package/workers/WorkerSelenium.js +0 -253
  217. package/workers/workerUtils.js +0 -20
package/cliAgentMode.js DELETED
@@ -1,384 +0,0 @@
1
- /* eslint-disable camelcase */
2
- // @ts-check
3
-
4
- 'use strict';
5
-
6
- const path = require('path');
7
- const fs = require('fs-extra');
8
- const ms = require('ms');
9
- const WebSocket = require('ws');
10
- const ChromeLauncher = require('chrome-launcher');
11
- const config = require('./commons/config');
12
- const { ArgError } = require('./errors');
13
- const lazyRequire = require('./commons/lazyRequire');
14
- const prepareUtils = require('./commons/prepareRunnerAndTestimStartUtils');
15
- const { downloadAndSave, unzipFile, getCdpAddressForHost, TESTIM_BROWSER_DIR, promiseFromCallback } = require('./utils');
16
- const ora = require('ora');
17
- const { downloadAndInstallChromium, CHROMIUM_VERSION } = require('./chromiumInstaller');
18
-
19
-
20
- const LOG_LEVEL = config.WEBDRIVER_DEBUG ? 'verbose' : 'silent';
21
- const EXTENSION_CACHE_TIME = ms('1h');
22
- const USER_DATA_DIR = path.join(TESTIM_BROWSER_DIR, 'profile');
23
-
24
- // https://github.com/bayandin/chromedriver/blob/5013f2124888c50fff15dc2ff8287288f780b046/chrome_launcher.cc#L105
25
- const CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILENAME = 'DevToolsActivePort';
26
- const CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH = path.join(USER_DATA_DIR, CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILENAME);
27
-
28
- module.exports = {
29
- shouldStartAgentMode,
30
- runAgentMode,
31
- getStartedWithStart,
32
- };
33
-
34
- /**
35
- * @type {(options: import('./runOptions').Options) => options is import('./runOptions').AgentModeOptions}
36
- */
37
- function shouldStartAgentMode(options) {
38
- // @ts-ignore should be `as any`
39
- return options.agentMode;
40
- }
41
-
42
- /** @param {import('./runOptions').AgentModeOptions} options */
43
- async function runAgentMode(options) {
44
- let testimStandaloneBrowser;
45
-
46
- await prepareUtils.preparePlayer(options.playerLocation, options.canary);
47
-
48
- if (options.startTestimBrowser) {
49
- await getRidOfPossiblyRunningChromeWithOurDataDir();
50
- try {
51
- // Consider moving that into the agent server and add endpoint to start browser?
52
- testimStandaloneBrowser = await startTestimStandaloneBrowser(options);
53
- } catch (e) {
54
- if (e?.message?.includes('user data directory is already in use')) {
55
- throw new ArgError('Please close all chrome browsers that were opened with "testim start" and try again');
56
- }
57
- throw e;
58
- }
59
- }
60
-
61
- const agentServer = require('./agent/server');
62
-
63
- if (testimStandaloneBrowser?.webdriverApi) {
64
- // if we're starting the agent here, pre-load the sessionPlayer so it loads faster
65
- // on first play
66
- const LOAD_PLAYER_DELAY = 6000;
67
- setTimeout(async () => {
68
- setTimeout(() => require('./player/seleniumTestPlayer'));
69
-
70
- const packages = [
71
- 'webpack',
72
- // We may build/static analyze functions file to do it here
73
- // silent full-blown build will require additional work,
74
- // But actually can be valuable as general speedup if we cache the webpack instance
75
- // "puppeteer",
76
- // "selenium-webdriver"
77
- // "playwright"
78
- ];
79
-
80
- for (const packageToInstall of packages) {
81
- await lazyRequire(packageToInstall, { silent: true }).catch(() => { });
82
- }
83
- }, LOAD_PLAYER_DELAY);
84
- }
85
-
86
- return agentServer.init(
87
- options,
88
- // @ts-ignore
89
- testimStandaloneBrowser
90
- );
91
- }
92
-
93
- let startedWithStart = false;
94
-
95
- function getStartedWithStart() {
96
- return startedWithStart;
97
- }
98
-
99
- function isPidRunning(pid) {
100
- try {
101
- return process.kill(pid, 0);
102
- } catch {
103
- return false;
104
- }
105
- }
106
-
107
- async function startFixedVersionChromium(options, extensionBase64, downloadedExtensionPathUnzipped) {
108
- const CHROMIUM_PROCESS_INFO_FILE = path.join(TESTIM_BROWSER_DIR, `chrome-${CHROMIUM_VERSION}-process`);
109
- const CHECK_CHROMIUM_RUNNING_INTERVAL = 3000;
110
-
111
- const onBrowserClosed = () => {
112
- fs.removeSync(CHROMIUM_PROCESS_INFO_FILE);
113
- // eslint-disable-next-line no-console
114
- console.log('\n\nBrowser session ended');
115
- process.exit(0);
116
- };
117
-
118
-
119
- if (fs.existsSync(CHROMIUM_PROCESS_INFO_FILE)) {
120
- const processInfo = fs.readJSONSync(CHROMIUM_PROCESS_INFO_FILE);
121
- if (isPidRunning(processInfo.pid)) { // if a previous instance of our browser is still running, use it and exit if it does
122
- const monitorPidForExit = () => (isPidRunning(processInfo.pid) ? setTimeout(monitorPidForExit, CHECK_CHROMIUM_RUNNING_INTERVAL) : onBrowserClosed());
123
- monitorPidForExit();
124
- return {
125
- webdriverApi: processInfo,
126
- };
127
- }
128
- }
129
- const chromeBinary = await downloadAndInstallChromium();
130
-
131
- if (!(await fs.pathExists(USER_DATA_DIR))) {
132
- await fs.mkdirp(USER_DATA_DIR);
133
- }
134
- const capabilities = buildSeleniumOptions(USER_DATA_DIR, extensionBase64, downloadedExtensionPathUnzipped, chromeBinary);
135
- const chromeFlags = [
136
- ...capabilities.desiredCapabilities.chromeOptions.args,
137
- ...ChromeLauncher.Launcher.defaultFlags().filter(flag => ![
138
- '--disable-extensions',
139
- '--disable-component-extensions-with-background-pages', // causes google connect to disallow some accounts (eg gmail accounts get a "This browser or app may not be secure" error)
140
- ].includes(flag)),
141
- ];
142
- // Chromium needs API keys to communicate with google APIs (https://www.chromium.org/developers/how-tos/api-keys/)
143
- // These are keys are keys that were included in some chrome builds
144
- const envVars = {
145
- GOOGLE_API_KEY: 'AIzaSyCkfPOPZXDKNn8hhgu3JrA62wIgC93d44k',
146
- GOOGLE_DEFAULT_CLIENT_ID: '811574891467.apps.googleusercontent.com',
147
- GOOGLE_DEFAULT_CLIENT_SECRET: 'kdloedMFGdGla2P1zacGjAQh',
148
- };
149
- const appUrl = `${options.extensionPath ? 'http://localhost:3000/app/' : 'https://app.testim.io'}?startMode=true`;
150
- const chrome = await ChromeLauncher.launch({ chromeFlags, startingUrl: appUrl, ignoreDefaultFlags: true, userDataDir: USER_DATA_DIR, chromePath: chromeBinary, envVars });
151
- const processInfo = { port: chrome.port, pid: chrome.pid, cdpUrl: await getCdpAddressForHost(`localhost:${chrome.port}`) };
152
- fs.writeJSONSync(CHROMIUM_PROCESS_INFO_FILE, processInfo);
153
- chrome.process.once('exit', onBrowserClosed);
154
- chrome.process.once('close', onBrowserClosed);
155
- return {
156
- webdriverApi: processInfo,
157
- };
158
- }
159
-
160
- /** @param {import('./runOptions').AgentModeOptions} options */
161
- async function startTestimStandaloneBrowser(options) {
162
- // After next clickim release we will have also testim-full.zip
163
- // const fullExtensionUrl = "https://testimstatic.blob.core.windows.net/extension/testim-full-master.zip";
164
- // CDN url
165
- const fullExtensionUrl = `${config.EDGE_URL}/extension/testim-full-master.zip`;
166
- const extensionFilename = path.basename(fullExtensionUrl);
167
-
168
- const downloadedExtensionPath = path.join(TESTIM_BROWSER_DIR, extensionFilename);
169
- const downloadedExtensionPathUnzipped = path.join(TESTIM_BROWSER_DIR, `${extensionFilename}__unzipped__`);
170
-
171
- let shouldDownloadExtension = !(options.ext || options.extensionPath);
172
-
173
- if (shouldDownloadExtension && await fs.pathExists(downloadedExtensionPath)) {
174
- const stat = await fs.stat(downloadedExtensionPath);
175
- shouldDownloadExtension = (Date.now() - EXTENSION_CACHE_TIME > stat.mtimeMs);
176
- }
177
- await fs.mkdirp(TESTIM_BROWSER_DIR);
178
-
179
- if (shouldDownloadExtension) {
180
- const spinner = ora('Downloading Testim Editor').start();
181
- await downloadAndSave(fullExtensionUrl, downloadedExtensionPath);
182
-
183
- try {
184
- // Ensure the zip is ok
185
- await unzipFile(downloadedExtensionPath, downloadedExtensionPathUnzipped);
186
- } catch (e) {
187
- // The downloaded zip is corrupted, try re download once
188
- await fs.remove(downloadedExtensionPath);
189
- await downloadAndSave(fullExtensionUrl, downloadedExtensionPath);
190
- try {
191
- await unzipFile(downloadedExtensionPath, downloadedExtensionPathUnzipped);
192
- } catch (err) {
193
- // zip is bad again.
194
- await fs.remove(downloadedExtensionPath);
195
- spinner.fail('Failed to download Testim Editor');
196
- throw new Error('Failed to download Testim Editor');
197
- }
198
- } finally {
199
- if (!options.downloadBrowser) {
200
- await fs.remove(downloadedExtensionPathUnzipped);
201
- }
202
- }
203
-
204
- spinner.succeed();
205
- }
206
-
207
- const extensionBase64 = options.extensionPath ? null : (await fs.readFile(options.ext || downloadedExtensionPath)).toString('base64');
208
- if (options.downloadBrowser) {
209
- return await startFixedVersionChromium(options, extensionBase64, downloadedExtensionPathUnzipped);
210
- }
211
- await prepareUtils.prepareChromeDriver(
212
- { projectId: options.project },
213
- // @ts-expect-error not clear where chromeBinaryLocations comes from
214
- { chromeBinaryLocation: options.chromeBinaryLocations },
215
- );
216
-
217
- // @ts-expect-error not clear where chromeBinaryLocations comes from
218
- const seleniumOptions = buildSeleniumOptions(USER_DATA_DIR, extensionBase64, options.extensionPath, options.chromeBinaryLocations);
219
-
220
- const WebDriver = require('./player/webdriver');
221
- const { SeleniumPerfStats } = require('./commons/SeleniumPerfStats');
222
-
223
- const webdriverApi = new WebDriver();
224
- webdriverApi.seleniumPerfStats = new SeleniumPerfStats();
225
-
226
- // starts chrome via selenium, note this is intentionally initClient and not init to bypass desired capabilities parsing
227
- const webdriverInitResponse = await webdriverApi.initClient(seleniumOptions);
228
-
229
- // example values from webdriverIntRespons
230
- // webdriverInitResponse.sessionId
231
- // webdriverInitResponse.value["goog:chromeOptions"].debuggerAddress
232
- // webdriverInitResponse.chrome.userDataDir;
233
-
234
- // require user token, so we can't use it for now
235
- // const { getEditorUrl } = require('./commons/testimServicesApi');
236
-
237
- startedWithStart = true;
238
- const appUrl = `${options.extensionPath ? 'http://localhost:3000/app/' : 'https://app.testim.io'}?startMode=true`;
239
-
240
- await webdriverApi.url(appUrl);
241
- // save the initial URL we navigated to so we don't consider it the AuT
242
- webdriverApi.initialUrl = appUrl;
243
- try {
244
- //TODO(Benji) do we want this to be exactly getCdpAddressForHost or should this fail less gracefully indicating the agent did not start correctly?
245
- webdriverApi.cdpUrl = await getCdpAddressForHost(webdriverInitResponse.value['goog:chromeOptions'].debuggerAddress);
246
- } catch (e) {
247
- // ignore error
248
- }
249
-
250
- return {
251
- webdriverApi,
252
- };
253
- }
254
-
255
- /**
256
- * @param {string} userDataDir
257
- * @param {string | null} fullExtensionPath
258
- */
259
- function buildSeleniumOptions(userDataDir, fullExtensionPath, unpackedExtensionPath, chromeBinaryPath) {
260
- const extensions = fullExtensionPath ? [fullExtensionPath] : [];
261
- const args = [
262
- `--user-data-dir=${userDataDir}`, // crashes chromium, re-enable if using chrome
263
- '--log-level=OFF',
264
- '--silent-debugger-extension-api',
265
- '--no-first-run',
266
- ];
267
- if (unpackedExtensionPath) {
268
- args.push(`--load-extension=${unpackedExtensionPath}`);
269
- }
270
-
271
- return {
272
- logLevel: LOG_LEVEL,
273
- desiredCapabilities: {
274
- chromeOptions: {
275
- args,
276
- extensions,
277
- binary: chromeBinaryPath,
278
- },
279
- browserName: 'chrome',
280
- },
281
- host: 'localhost',
282
- port: 9515, // chromedriver port
283
- };
284
- }
285
-
286
- /**
287
- * Overview of what we do here:
288
- * we check if CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH is exists
289
- * If we can read the port & CDP url info from that file.
290
- * If we can read, but we can't send http request to the devtools server we assume it's closed and just delete the file
291
- * If we can read and send HTTP request, send CDP command of Browser.close to CDP, and delete the file.
292
- * If any of these fails we assume we couldn't kill the browser, and the user will get the "close the running chromes errors down the line"
293
- */
294
- async function getRidOfPossiblyRunningChromeWithOurDataDir() {
295
- if (!await fs.pathExists(CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH)) {
296
- return;
297
- }
298
-
299
- try {
300
- const { webSocketDebuggerUrl } = await readAndValidateChromedriverDevToolsActivePortFile();
301
- await tryToCloseBrowserWithCDPUrl(webSocketDebuggerUrl);
302
- await fs.unlink(CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH);
303
- } catch (e) {
304
- // chrome is probably not really running, we are cool
305
- if (e && e.message === 'unable to connect to devtools http server') {
306
- await fs.unlink(CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH);
307
- }
308
- }
309
- }
310
-
311
- async function readAndValidateChromedriverDevToolsActivePortFile() {
312
- /**
313
- * file content example:
314
-
315
- 58938
316
- /devtools/browser/d4290379-ec08-4d03-a41a-ab9d9d4c36ac
317
-
318
- */
319
-
320
- const fileContent = await fs.readFile(CHOMEDRIVER_DEVTOOLS_ACTIVE_PORT_FILE_PATH, { encoding: 'utf8' });
321
-
322
- const [portLine, browserCDPURLLine] = fileContent.split('\n').map(line => line.trim());
323
-
324
- const port = Number.parseInt(portLine, 10);
325
-
326
- if (!Number.isInteger(port) || port < 1 || port > 65535) {
327
- throw new Error('invalid port number');
328
- }
329
-
330
- if (!browserCDPURLLine.startsWith('/devtools/browser/')) {
331
- throw new Error('invalid devtools browser url');
332
- }
333
-
334
- const webSocketDebuggerUrl = await getCdpAddressForHost(`localhost:${port}`, 500);
335
- // invariant check
336
- if (!webSocketDebuggerUrl.endsWith(browserCDPURLLine)) {
337
- throw new Error('invariant webSocketDebuggerUrl miss match');
338
- }
339
-
340
- return {
341
- port,
342
- webSocketDebuggerUrl,
343
- };
344
- }
345
-
346
-
347
- /**
348
- * @param {string | import("url").URL} webSocketDebuggerUrl
349
- * @param {number=} timeout
350
- */
351
- async function tryToCloseBrowserWithCDPUrl(webSocketDebuggerUrl, timeout = 100) {
352
- const websocketConnection = await wsConnectAndOpen(webSocketDebuggerUrl, timeout);
353
-
354
- return promiseFromCallback(cb => {
355
- websocketConnection.send(JSON.stringify({
356
- id: 0,
357
- method: 'Browser.close',
358
- }), cb);
359
- });
360
- }
361
-
362
- /**
363
- * @param {string | import("url").URL} webSocketDebuggerUrl
364
- * @param {number=} timeout
365
- */
366
- async function wsConnectAndOpen(webSocketDebuggerUrl, timeout = 100) {
367
- const websocket = new WebSocket(webSocketDebuggerUrl, { timeout });
368
-
369
- const openPromise = promiseFromCallback((cb) => {
370
- websocket.once('open', cb);
371
- }).then(() => {
372
- websocket.removeAllListeners();
373
- });
374
-
375
- const errorPromise = promiseFromCallback((cb) => {
376
- websocket.once('error', cb);
377
- }).catch(() => {
378
- websocket.close();
379
- websocket.removeAllListeners();
380
- });
381
-
382
- return Promise.race([openPromise, errorPromise]).then(() => websocket);
383
- }
384
-
@@ -1,91 +0,0 @@
1
- // @ts-check
2
-
3
- /* eslint-disable no-console */
4
-
5
- 'use strict';
6
-
7
- const fs = require('fs');
8
- const childProcess = require('child_process');
9
- const path = require('path');
10
- const chalk = require('chalk');
11
- const validateNpmPackageName = require('validate-npm-package-name');
12
- const { promisify } = require('util');
13
- const { ArgError } = require('../errors.js');
14
- const { copyDir } = require('../utils/fsUtils');
15
-
16
- const exec = promisify(childProcess.exec);
17
-
18
- /** @param {string} name */
19
- module.exports.init = async function init(name) {
20
- const ora = require('ora');
21
- const prompts = require('prompts');
22
-
23
- if (typeof name !== 'string' || !name.trim()) {
24
- const response = await prompts({
25
- type: 'text',
26
- name: 'project',
27
- message: 'Please enter Project name',
28
- validate: value => String(value).length > 3,
29
- });
30
- name = response.project;
31
- }
32
-
33
- const fullPath = path.resolve(name);
34
-
35
- if (fs.existsSync(fullPath) && fs.readdirSync(fullPath).length !== 0) {
36
- console.log(`${fullPath} is not empty. Quitting...`);
37
- process.exit(1);
38
- }
39
-
40
- const packageName = fullPath.substr(Math.max(fullPath.lastIndexOf('/'), fullPath.lastIndexOf('\\')) + 1);
41
-
42
- const nameValidity = validateNpmPackageName(packageName);
43
-
44
- if (!nameValidity.validForNewPackages) {
45
- const message = `The name '${packageName}' is not a valid package name:`;
46
- console.log(chalk.red(message));
47
- if (nameValidity.errors) nameValidity.errors.forEach((e) => console.log(chalk.red(e)));
48
- if (nameValidity.warnings) nameValidity.warnings.forEach((e) => console.log(chalk.yellowBright(`warning: ${e}`)));
49
-
50
- throw new ArgError(`${message}\nvalidation errors:\n${nameValidity.errors?.join('\n') || ''}\nwarnings:\n${nameValidity.warnings?.join('\n') || ''}`);
51
- }
52
-
53
- const response = await prompts({
54
- type: 'toggle',
55
- name: 'isJs',
56
- message: 'Add support for TypeScript?',
57
- initial: true,
58
- active: 'no',
59
- inactive: 'yes',
60
- });
61
-
62
- const sourceFolder = response.isJs ? 'template.js' : 'template.ts'; // these are directories and not file names
63
-
64
- const source = path.join(__dirname, sourceFolder);
65
- const destDir = path.join(process.cwd(), name);
66
-
67
- let spinner = ora(`Creating new test project in ${destDir}`).start();
68
-
69
- await copyDir(source, destDir);
70
-
71
- const sourcePackageJson = path.join(__dirname, sourceFolder, 'package.json');
72
- const destPackageJson = path.join(process.cwd(), name, 'package.json');
73
-
74
- const packageContents = await fs.promises.readFile(sourcePackageJson);
75
-
76
- const newPackageJson = packageContents.toString().replace('~testim-codeful-test-project~', packageName);
77
-
78
- await fs.promises.writeFile(destPackageJson, newPackageJson);
79
-
80
- const gitIgnore = 'node_modules';
81
- const gitIgnoreFilePath = path.join(process.cwd(), name, '.gitignore');
82
- await fs.promises.writeFile(gitIgnoreFilePath, gitIgnore);
83
-
84
- spinner.succeed();
85
- spinner = ora('Installing dependencies').start();
86
- await exec('npm install', { cwd: destDir });
87
-
88
- spinner.succeed();
89
-
90
- console.log(`Testim Dev Kit project folder successfully created in ${destDir}.`);
91
- };