@mablhq/mabl-cli 1.61.8 → 2.0.3

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 (86) hide show
  1. package/Globals.js +11 -7
  2. package/api/basicApiClient.js +10 -10
  3. package/api/mablApiClient.js +39 -1
  4. package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +6 -6
  5. package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +8 -0
  6. package/cli.js +1 -0
  7. package/commands/app-files/app-files.js +5 -0
  8. package/commands/app-files/app-files_cmds/create.js +98 -0
  9. package/commands/app-files/app-files_cmds/delete.js +31 -0
  10. package/commands/app-files/app-files_cmds/download.js +50 -0
  11. package/commands/app-files/app-files_cmds/list.js +72 -0
  12. package/commands/config/config_cmds/install.js +92 -0
  13. package/commands/constants.js +10 -3
  14. package/commands/tests/testsUtil.js +45 -15
  15. package/commands/tests/tests_cmds/run-mobile.js +218 -0
  16. package/commands/tests/tests_cmds/run.js +11 -9
  17. package/core/util.js +36 -2
  18. package/env/defaultEnv.js +2 -1
  19. package/env/dev.js +2 -1
  20. package/env/env.js +3 -1
  21. package/env/local.js +2 -1
  22. package/env/prod.js +2 -1
  23. package/execution/index.js +13 -1
  24. package/execution/runAppiumServer.js +133 -0
  25. package/http/MablHttpAgent.js +4 -1
  26. package/http/RequestFilteringHttpAgent.js +3 -3
  27. package/http/axiosProxyConfig.js +27 -22
  28. package/http/httpUtil.js +6 -10
  29. package/mablApi/index.js +1 -1
  30. package/mablscript/MablAction.js +1 -1
  31. package/mablscript/MablStep.js +28 -2
  32. package/mablscript/MablStepV2.js +51 -0
  33. package/mablscript/MablSymbol.js +6 -2
  34. package/mablscript/actions/ExtractAction.js +11 -6
  35. package/mablscript/actions/FindAction.js +5 -5
  36. package/mablscript/actions/JavaScriptAction.js +19 -12
  37. package/mablscript/importer.js +97 -14
  38. package/mablscript/mobile/steps/CreateVariableMobileStep.js +53 -0
  39. package/mablscript/mobile/steps/EnterTextStep.js +41 -0
  40. package/mablscript/mobile/steps/NavigateBackStep.js +20 -0
  41. package/mablscript/mobile/steps/NavigateHomeStep.js +21 -0
  42. package/mablscript/mobile/steps/ScrollStep.js +37 -0
  43. package/mablscript/mobile/steps/SetOrientationStep.js +20 -0
  44. package/mablscript/mobile/steps/TapStep.js +37 -0
  45. package/mablscript/mobile/steps/actions/MobileFindAction.js +23 -0
  46. package/mablscript/mobile/steps/stepUtil.js +71 -0
  47. package/mablscript/mobile/tests/StepTestsUtil.js +20 -0
  48. package/mablscript/mobile/tests/TestMobileFindDescriptors.js +215 -0
  49. package/mablscript/mobile/tests/steps/CreateVariableMobileStep.mobiletest.js +287 -0
  50. package/mablscript/mobile/tests/steps/EnterTextStep.mobiletest.js +74 -0
  51. package/mablscript/mobile/tests/steps/GeneralHumanization.mobiletest.js +167 -0
  52. package/mablscript/mobile/tests/steps/NavigateBackStep.mobiletest.js +22 -0
  53. package/mablscript/mobile/tests/steps/NavigateHomeStep.mobiletest.js +22 -0
  54. package/mablscript/mobile/tests/steps/ScrollStep.mobiletest.js +112 -0
  55. package/mablscript/mobile/tests/steps/SetOrientationStep.mobiletest.js +27 -0
  56. package/mablscript/mobile/tests/steps/TapStep.mobiletest.js +53 -0
  57. package/mablscript/steps/AssertStep.js +48 -38
  58. package/mablscript/steps/AssertStepOld.js +30 -2
  59. package/mablscript/steps/CreateVariableStep.js +9 -2
  60. package/mablscript/steps/EchoStep.js +4 -3
  61. package/mablscript/steps/ElseIfConditionStep.js +8 -2
  62. package/mablscript/steps/ElseStep.js +2 -1
  63. package/mablscript/steps/EndStep.js +2 -1
  64. package/mablscript/steps/EvaluateJavaScriptStep.js +6 -1
  65. package/mablscript/steps/IfConditionStep.js +17 -10
  66. package/mablscript/steps/SendHttpRequestStep.js +4 -3
  67. package/mablscript/steps/WaitStep.js +4 -3
  68. package/mablscript/types/GetVariableDescriptor.js +8 -3
  69. package/mablscript/types/mobile/CreateVariableMobileStepDescriptor.js +9 -0
  70. package/mablscript/types/mobile/EnterTextStepDescriptor.js +2 -0
  71. package/mablscript/types/mobile/NavigateBackStepDescriptor.js +2 -0
  72. package/mablscript/types/mobile/NavigateHomeStepDescriptor.js +2 -0
  73. package/mablscript/types/mobile/ScrollStepDescriptor.js +2 -0
  74. package/mablscript/types/mobile/SetOrientationStepDescriptor.js +8 -0
  75. package/mablscript/types/mobile/StepWithMobileFindDescriptor.js +2 -0
  76. package/mablscript/types/mobile/TapStepDescriptor.js +8 -0
  77. package/mablscriptFind/index.js +1 -1
  78. package/package.json +13 -6
  79. package/resources/pdf-viewer/embeddedPdfDetection.js +1 -14
  80. package/resources/webdriver.js +21 -0
  81. package/upload/index.js +5 -0
  82. package/util/FileCache.js +180 -0
  83. package/util/Lazy.js +90 -0
  84. package/util/MobileAppFileCache.js +102 -0
  85. package/util/RichPromise.js +3 -1
  86. package/webdriver/index.js +41 -0
@@ -0,0 +1,133 @@
1
+ const appium = require('appium');
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ const APPIUM_SERVER_READY = 'APPIUM_SERVER_READY';
10
+ const APPIUM_SERVER_SHUTDOWN = 'APPIUM_SERVER_SHUTDOWN';
11
+ const APPIUM_SERVER_LOG = 'APPIUM_SERVER_LOG';
12
+ const APPIUM_SERVER_PARENT_ALIVE = 'APPIUM_SERVER_PARENT_ALIVE';
13
+ const APPIUM_SERVER_CHECK_IN = 'APPIUM_SERVER_CHECK_IN';
14
+
15
+
16
+ const CHECK_IN_FAIL_LIMIT_MILLIS = 15_000;
17
+
18
+ const CHECK_IN_INTERVAL_MILLIS = 5_000;
19
+
20
+
21
+ const appiumConfig = JSON.parse(process.argv[2]);
22
+
23
+ if (appiumConfig.androidHome) {
24
+ process.env.ANDROID_HOME = appiumConfig.androidHome;
25
+ delete appiumConfig.androidHome;
26
+ }
27
+
28
+
29
+
30
+ appiumConfig.allowInsecure = ['chromedriver_autodownload'];
31
+
32
+ let server;
33
+ let shutdownCalled = false;
34
+ let lastKnownCheckInTime = Date.now();
35
+ let intervalCheckIn;
36
+
37
+ appium
38
+ .main({...appiumConfig, logHandler: logHandlerFunc})
39
+ .then((serverInstance) => {
40
+ server = serverInstance;
41
+ process.send({type: APPIUM_SERVER_READY});
42
+ lastKnownCheckInTime = Date.now();
43
+ intervalCheckIn = global.setInterval(
44
+ checkInOnParent,
45
+ CHECK_IN_INTERVAL_MILLIS,
46
+ );
47
+ })
48
+ .catch((error) => {
49
+
50
+ throw error;
51
+ });
52
+ process.on('message', (message) => {
53
+ switch (message) {
54
+ case APPIUM_SERVER_PARENT_ALIVE:
55
+ lastKnownCheckInTime = Date.now();
56
+ break;
57
+ case APPIUM_SERVER_SHUTDOWN:
58
+ shutdownCalled = true;
59
+ server.close().catch((error) => {
60
+
61
+ throw error;
62
+ });
63
+ break;
64
+ default:
65
+ console.log('unsupported message', message);
66
+ }
67
+ });
68
+
69
+
70
+ function logHandlerFunc(logLevel, log) {
71
+ process.send({
72
+ type: APPIUM_SERVER_LOG,
73
+ payload: {
74
+ logLevel,
75
+ log,
76
+ },
77
+ });
78
+ }
79
+
80
+
81
+ const originalExit = process.exit;
82
+
83
+
84
+
85
+ process.exit = (code) => {
86
+ if (shutdownCalled) {
87
+ global.clearInterval(intervalCheckIn);
88
+
89
+
90
+ originalExit();
91
+ process.kill();
92
+ }
93
+ if (code && code > 0) {
94
+ const stack = new Error().stack;
95
+ process.send({
96
+ type: APPIUM_SERVER_LOG,
97
+ payload: {
98
+ logLevel: 'error',
99
+ log: `process.exit() call prevented - ${stack}`,
100
+ },
101
+ });
102
+ return;
103
+ }
104
+ };
105
+
106
+ process.on('disconnect', () => {
107
+ console.log(
108
+ '[runAppiumServer.js] lost connection to parent process, terminating',
109
+ );
110
+ originalExit();
111
+ process.kill();
112
+ });
113
+
114
+
115
+ function checkInOnParent() {
116
+ try {
117
+ process.send({type: APPIUM_SERVER_CHECK_IN});
118
+ const currentTime = Date.now();
119
+ const timeSinceLastCheckIn = currentTime - lastKnownCheckInTime;
120
+ if (timeSinceLastCheckIn > CHECK_IN_FAIL_LIMIT_MILLIS) {
121
+ console.log(
122
+ '[runAppiumServer.js] parent process has gone dark, terminating',
123
+ );
124
+ global.clearInterval(intervalCheckIn);
125
+ originalExit();
126
+ process.kill();
127
+ }
128
+ lastKnownCheckInTime = currentTime;
129
+ } catch (error) {
130
+ console.error('Could not run checkin function', error);
131
+ }
132
+ return;
133
+ }
@@ -55,11 +55,14 @@ class MablHttpAgent extends agent_base_1.Agent {
55
55
  httpsAgent: (_b = httpsAgent !== null && httpsAgent !== void 0 ? httpsAgent : proxyConfig.httpsAgent) !== null && _b !== void 0 ? _b : https.globalAgent,
56
56
  };
57
57
  }
58
- callback(req, opts) {
58
+ createSocket(req, options, cb) {
59
59
  var _a;
60
60
  if ((_a = this.maybeGetFirstStringHeader(req, httpUtil_1.USER_AGENT_HEADER)) === null || _a === void 0 ? void 0 : _a.startsWith('PostmanRuntime/')) {
61
61
  req.setHeader(httpUtil_1.USER_AGENT_HEADER, httpUtil_1.USER_AGENT);
62
62
  }
63
+ super.createSocket(req, options, cb);
64
+ }
65
+ connect(_req, opts) {
63
66
  return Promise.resolve(opts.secureEndpoint ? this.httpsAgent : this.httpAgent);
64
67
  }
65
68
  maybeGetFirstStringHeader(req, name) {
@@ -45,17 +45,17 @@ class RequestFilteringHttpAgent extends MablHttpAgent_1.MablHttpAgent {
45
45
  const constructorParameters = await MablHttpAgent_1.MablHttpAgent.getConstructorParameters();
46
46
  return new RequestFilteringHttpAgent(constructorParameters.httpAgent, constructorParameters.httpsAgent);
47
47
  }
48
- callback(req, opts) {
48
+ connect(req, opts) {
49
49
  if (isForbiddenHost(opts.host)) {
50
50
  return Promise.reject(new RequestSecurityError_1.RequestSecurityError('Request contains forbidden host'));
51
51
  }
52
- else if (containsForbiddenHeader(opts.headers)) {
52
+ else if (containsForbiddenHeader(req.getHeaders())) {
53
53
  return Promise.reject(new RequestSecurityError_1.RequestSecurityError('Request contains forbidden header'));
54
54
  }
55
55
  else if (isPrivateAddress(opts.host)) {
56
56
  return Promise.reject(new RequestSecurityError_1.RequestSecurityError('Request contains private address'));
57
57
  }
58
- return super.callback(req, opts);
58
+ return super.connect(req, opts);
59
59
  }
60
60
  }
61
61
  exports.RequestFilteringHttpAgent = RequestFilteringHttpAgent;
@@ -23,12 +23,17 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.maybeGetModifiedAxiosConfigForHttpProxy = exports.proxyUrlToPortConfig = exports.axiosProxyConfig = exports.currentProxyConfig = void 0;
26
+ exports.proxyUrlToPortConfig = exports.axiosProxyConfig = exports.currentProxyConfig = exports.setTestExecutionProxyUrl = void 0;
27
27
  const cliConfigProvider_1 = require("../providers/cliConfigProvider");
28
28
  const https = __importStar(require("https"));
29
29
  const https_proxy_agent_1 = require("https-proxy-agent");
30
30
  const hpagent_1 = require("hpagent");
31
31
  const httpUtil_1 = require("./httpUtil");
32
+ let testExecutionProxyUrl;
33
+ function setTestExecutionProxyUrl(url) {
34
+ testExecutionProxyUrl = url;
35
+ }
36
+ exports.setTestExecutionProxyUrl = setTestExecutionProxyUrl;
32
37
  async function currentProxyConfig(mode = 'mabl') {
33
38
  const httpConfig = (await cliConfigProvider_1.CliConfigProvider.getCliConfig()).http;
34
39
  return axiosProxyConfig(mode === 'test' ? httpConfig === null || httpConfig === void 0 ? void 0 : httpConfig.test : httpConfig === null || httpConfig === void 0 ? void 0 : httpConfig.mabl);
@@ -41,15 +46,21 @@ function axiosProxyConfig(httpConfig) {
41
46
  [httpUtil_1.USER_AGENT_HEADER]: httpUtil_1.USER_AGENT,
42
47
  },
43
48
  };
44
- if (!httpConfig.sslVerify) {
49
+ let { proxyType, sslVerify } = httpConfig;
50
+ if (testExecutionProxyUrl) {
51
+ sslVerify = false;
52
+ proxyType = 'current';
53
+ }
54
+ if (!sslVerify) {
45
55
  config.httpsAgent = new https.Agent({
46
56
  rejectUnauthorized: false,
47
57
  });
48
58
  }
49
- if ((_a = httpConfig.proxyHost) === null || _a === void 0 ? void 0 : _a.href) {
50
- config.proxy = proxyUrlToPortConfig(httpConfig.proxyHost);
59
+ if (testExecutionProxyUrl || ((_a = httpConfig.proxyHost) === null || _a === void 0 ? void 0 : _a.href)) {
60
+ config.proxy = proxyUrlToPortConfig((testExecutionProxyUrl !== null && testExecutionProxyUrl !== void 0 ? testExecutionProxyUrl : httpConfig.proxyHost));
51
61
  }
52
- return maybeGetModifiedAxiosConfigForHttpProxy(config, httpConfig.sslVerify, httpConfig.proxyType);
62
+ const result = maybeGetModifiedAxiosConfigForHttpProxy(config, sslVerify, proxyType);
63
+ return result;
53
64
  }
54
65
  exports.axiosProxyConfig = axiosProxyConfig;
55
66
  function escapeRegexDots(input) {
@@ -87,12 +98,16 @@ function maybeGetModifiedAxiosConfigForHttpProxy(config, sslVerify, proxyType) {
87
98
  };
88
99
  newConfig.proxy = false;
89
100
  const authConfig = config.proxy.auth;
101
+ let proxyString = 'http://';
102
+ if (authConfig) {
103
+ proxyString += `${authConfig.username}:${authConfig.password}@`;
104
+ }
105
+ proxyString += `${config.proxy.host}:${config.proxy.port}`;
106
+ const proxyUrl = new URL(proxyString);
107
+ const configOptions = {
108
+ rejectUnauthorized: sslVerify !== false,
109
+ };
90
110
  if (proxyType === 'current') {
91
- let proxyString = 'http://';
92
- if (authConfig !== undefined) {
93
- proxyString += `${authConfig.username}:${authConfig.password}@`;
94
- }
95
- proxyString += `${config.proxy.host}:${config.proxy.port}`;
96
111
  const agentConfig = {
97
112
  keepAlive: true,
98
113
  keepAliveMsecs: 1000,
@@ -102,22 +117,12 @@ function maybeGetModifiedAxiosConfigForHttpProxy(config, sslVerify, proxyType) {
102
117
  rejectUnauthorized: sslVerify !== false,
103
118
  };
104
119
  newConfig.httpsAgent = new hpagent_1.HttpsProxyAgent(agentConfig);
105
- newConfig.httpAgent = new hpagent_1.HttpsProxyAgent(agentConfig);
106
120
  }
107
121
  else {
108
- const configOptions = {
109
- host: config.proxy.host,
110
- port: config.proxy.port,
111
- auth: authConfig
112
- ? `${authConfig.username}:${authConfig.password}`
113
- : undefined,
114
- rejectUnauthorized: sslVerify !== false,
115
- };
116
- newConfig.httpsAgent = new https_proxy_agent_1.HttpsProxyAgent(configOptions);
117
- newConfig.httpAgent = new https_proxy_agent_1.HttpsProxyAgent(configOptions);
122
+ newConfig.httpsAgent = new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, configOptions);
118
123
  }
124
+ newConfig.httpAgent = new https_proxy_agent_1.HttpsProxyAgent(proxyUrl, configOptions);
119
125
  return newConfig;
120
126
  }
121
127
  return config;
122
128
  }
123
- exports.maybeGetModifiedAxiosConfigForHttpProxy = maybeGetModifiedAxiosConfigForHttpProxy;
package/http/httpUtil.js CHANGED
@@ -27,16 +27,12 @@ function maybeGetSocksAgent(linkServer) {
27
27
  if (!linkServer) {
28
28
  return;
29
29
  }
30
- const agentOptions = {
31
- host: linkServer.forwarding_host,
32
- port: linkServer.forwarding_port,
33
- userId: linkServer.workspace_id,
34
- password: linkServer.label,
35
- tls: {
36
- rejectUnauthorized: false,
37
- },
38
- };
39
- return new socks_proxy_agent_1.SocksProxyAgent(agentOptions);
30
+ const user = linkServer.workspace_id;
31
+ const password = linkServer.label;
32
+ const host = linkServer.forwarding_host;
33
+ const port = linkServer.forwarding_port;
34
+ const url = new URL(`socks5h://${user}:${password}@${host}:${port}`);
35
+ return new socks_proxy_agent_1.SocksProxyAgent(url);
40
36
  }
41
37
  function postProcessHeaders(response) {
42
38
  var _a, _b, _c;