@mablhq/mabl-cli 1.12.24 → 1.13.17

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 (107) hide show
  1. package/api/basicApiClient.js +63 -26
  2. package/api/mablApiClient.js +9 -9
  3. package/api/mablApiClientFactory.js +1 -0
  4. package/auth/AuthClient.js +1 -4
  5. package/browserLauncher/browserLauncherFactory.js +7 -3
  6. package/browserLauncher/playwrightBrowserLauncher/playwrightBrowser.js +6 -2
  7. package/browserLauncher/playwrightBrowserLauncher/playwrightBrowserLauncher.js +1 -0
  8. package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +60 -20
  9. package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +24 -17
  10. package/browserLauncher/playwrightBrowserLauncher/playwrightHttpResponse.js +3 -0
  11. package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +72 -68
  12. package/browserLauncher/playwrightBrowserLauncher/wrappers.js +1 -1
  13. package/browserLauncher/puppeteerBrowserLauncher/puppeteerBrowser.js +7 -3
  14. package/browserLauncher/puppeteerBrowserLauncher/puppeteerElementHandle.js +13 -7
  15. package/browserLauncher/puppeteerBrowserLauncher/puppeteerFrame.js +7 -7
  16. package/browserLauncher/puppeteerBrowserLauncher/puppeteerHttpRequest.js +1 -1
  17. package/browserLauncher/puppeteerBrowserLauncher/puppeteerHttpResponse.js +4 -1
  18. package/browserLauncher/puppeteerBrowserLauncher/puppeteerJsHandle.js +3 -3
  19. package/browserLauncher/puppeteerBrowserLauncher/puppeteerPage.js +23 -16
  20. package/browserLauncher/puppeteerBrowserLauncher/wrappers.js +1 -1
  21. package/browserLauncher/types.js +6 -1
  22. package/cli.js +6 -4
  23. package/commands/applications/applications_cmds/list.js +1 -1
  24. package/commands/branches/branches_cmds/create.js +1 -1
  25. package/commands/branches/branches_cmds/list.js +1 -1
  26. package/commands/branches/branches_cmds/merge.js +1 -1
  27. package/commands/commandUtil/awaitCompletion.js +2 -2
  28. package/commands/commandUtil/codeInsights.js +6 -6
  29. package/commands/commandUtil/fileUtil.js +1 -1
  30. package/commands/commandUtil/util.js +12 -12
  31. package/commands/config/config_cmds/list.js +1 -1
  32. package/commands/constants.js +1 -1
  33. package/commands/credentials/credentials_cmds/list.js +1 -1
  34. package/commands/deploy/deploy_cmds/create.js +2 -2
  35. package/commands/deploy/deploy_cmds/executionResultPresenter.js +7 -7
  36. package/commands/deploy/deploy_cmds/list.js +1 -1
  37. package/commands/environments/environments_cmds/create.js +3 -3
  38. package/commands/environments/environments_cmds/list.js +1 -1
  39. package/commands/environments/environments_cmds/urls_cmds/add.js +1 -1
  40. package/commands/flows/flows_cmds/list.js +1 -1
  41. package/commands/plans/plans_cmds/list.js +1 -1
  42. package/commands/test-runs/test-runs_cmds/export.js +1 -1
  43. package/commands/tests/executionUtil.js +1 -1
  44. package/commands/tests/testsUtil.js +16 -20
  45. package/commands/tests/tests_cmds/edit.js +1 -1
  46. package/commands/tests/tests_cmds/export.js +1 -1
  47. package/commands/tests/tests_cmds/import.js +13 -13
  48. package/commands/tests/tests_cmds/list.js +2 -2
  49. package/commands/tests/tests_cmds/run-alpha.js +1 -1
  50. package/commands/tests/tests_cmds/run-cloud.js +7 -7
  51. package/commands/tests/tests_cmds/run-legacy.js +2 -2
  52. package/commands/tests/tests_cmds/run.js +25 -7
  53. package/commands/workspaces/workspace_cmds/copy.js +1 -1
  54. package/commands/workspaces/workspace_cmds/list.js +1 -1
  55. package/configGenerators/flowConfigGenerator.js +3 -3
  56. package/configGenerators/selIdeGenerator.js +1 -1
  57. package/configGenerators/testConfigGenerator.js +7 -8
  58. package/core/execution/ApiTestUtils.js +2 -2
  59. package/core/trainer/openUtils.js +47 -0
  60. package/core/trainer/trainingSessions.js +36 -61
  61. package/env/defaultEnv.js +2 -1
  62. package/env/dev.js +2 -1
  63. package/env/env.js +3 -1
  64. package/env/local.js +2 -1
  65. package/env/prod.js +2 -1
  66. package/execution/index.js +1 -1
  67. package/execution/index.js.LICENSE.txt +12 -0
  68. package/index.d.ts +7 -0
  69. package/mablscript/MablStep.js +11 -7
  70. package/mablscript/actions/ConditionAction.js +2 -4
  71. package/mablscript/actions/FindAction.js +4 -4
  72. package/mablscript/importer.js +16 -14
  73. package/mablscript/steps/AccessibilityCheck.js +88 -0
  74. package/mablscript/steps/AssertStep.js +6 -5
  75. package/mablscript/steps/CreateVariableStep.js +2 -3
  76. package/mablscript/steps/DownloadStep.js +1 -2
  77. package/mablscript/steps/EnterTextStep.js +2 -1
  78. package/mablscript/steps/IfConditionStep.js +3 -3
  79. package/mablscript/steps/SendHttpRequestStep.js +11 -3
  80. package/mablscript/steps/SendKeyStep.js +2 -2
  81. package/mablscript/steps/SetFilesStep.js +1 -1
  82. package/mablscript/steps/SwitchContextStep.js +2 -1
  83. package/mablscript/types/AccessibilityCheckStepDescriptor.js +2 -0
  84. package/mablscript/types/AccessibilityCheckTypes.js +9 -0
  85. package/mablscript/types/VariableDataType.js +1 -8
  86. package/mablscript/types/VariableNamespace.js +1 -1
  87. package/mablscriptFind/index.js +1 -1
  88. package/package.json +8 -6
  89. package/popupDismissal/index.js +36 -30
  90. package/providers/authenticationProvider.js +2 -3
  91. package/providers/cliConfigProvider.js +1 -1
  92. package/providers/exportRequestProvider.js +1 -1
  93. package/providers/logging/loggingProvider.js +2 -2
  94. package/providers/scmContextProvider.js +1 -1
  95. package/reporters/mochAwesome/mochAwesomeReporter.js +10 -6
  96. package/reporters/reporter.js +1 -1
  97. package/resources/mablFind.js +1 -1
  98. package/resources/popupDismissal.js +1 -1
  99. package/util/RichPromise.js +2 -2
  100. package/util/actionabilityUtil.js +59 -9
  101. package/util/asyncUtil.js +45 -0
  102. package/util/downloadUtil.js +1 -1
  103. package/util/logUtils.js +22 -3
  104. package/util/markdownUtil.js +3 -3
  105. package/util/pureUtil.js +6 -6
  106. package/util/resourceUtil.js +18 -1
  107. package/core/trainer/trainerBrowserUtil.js +0 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mablhq/mabl-cli",
3
- "version": "1.12.24",
3
+ "version": "1.13.17",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "The official mabl command line interface tool",
6
6
  "main": "index.js",
@@ -25,7 +25,8 @@
25
25
  "postinstall": "node ./util/postInstallMessage.js"
26
26
  },
27
27
  "dependencies": {
28
- "@playwright/test": "1.15.2",
28
+ "@playwright/test": "1.17.1",
29
+ "playwright-core": "1.17.1",
29
30
  "@types/fs-extra": "^8.1.0",
30
31
  "@types/serve-handler": "^6.1.0",
31
32
  "@types/tmp": "^0.2.0",
@@ -34,9 +35,10 @@
34
35
  "anyproxy": "^4.1.3",
35
36
  "async-mutex": "^0.3.1",
36
37
  "async-retry": "1.3.3",
38
+ "axe-core": "4.3.3",
37
39
  "axios": "^0.21.1",
38
- "axios-cookiejar-support": "^1.0.1",
39
- "chalk": "^2.4.2",
40
+ "axios-cookiejar-support": "1.0.1",
41
+ "chalk": "2.4.2",
40
42
  "change-case": "^4.1.1",
41
43
  "chrome-launcher": "^0.13.1",
42
44
  "cli-table3": "^0.5.1",
@@ -46,6 +48,7 @@
46
48
  "env-paths": "^2.2.0",
47
49
  "esprima": "^4.0.1",
48
50
  "estraverse": "^4.3.0",
51
+ "fastest-levenshtein": "^1.0.10",
49
52
  "fs-extra": "^8.1.0",
50
53
  "git-repo-info": "^2.1.1",
51
54
  "glob": "^7.1.4",
@@ -55,12 +58,11 @@
55
58
  "js-yaml": "^3.13.1",
56
59
  "jsesc": "^3.0.2",
57
60
  "jwt-decode": "^2.2.0",
58
- "fastest-levenshtein": "^1.0.10",
59
61
  "lodash.get": "^4.4.2",
60
62
  "markdown-table": "^2.0.0",
61
63
  "mime-types": "^2.1.26",
62
64
  "mochawesome-report-generator": "^5.2.0",
63
- "moment": "^2.24.0",
65
+ "moment": "2.26.0",
64
66
  "moment-duration-format": "^2.3.2",
65
67
  "newman": "5.2.3",
66
68
  "open": "^6.4.0",
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.elementsInFrontCount = exports.detectAndDismissPopupCandidates = exports.getAllElementsAbove = exports.elementsByHigherZIndex = void 0;
3
+ exports.elementsInFrontCount = exports.detectAndDismissPopupCandidates = exports.getAllElementsAbove = exports.elementsAtCoordinate = exports.elementsByHigherZIndex = void 0;
4
4
  const DISMISSAL_WAIT_TIME_MS = 750;
5
5
  const ZINDEX_AUTO = 'auto';
6
6
  const MINIMUM_POPUP_DISPLAY_COVERAGE_PX = 0.95;
@@ -40,9 +40,9 @@ function getEffectiveZIndex(element) {
40
40
  const isRootElement = (element) => element === undefined || element.tagName.toLowerCase() === 'html';
41
41
  let current = element;
42
42
  while (!isRootElement(current)) {
43
- const zIndex = window.getComputedStyle(element).zIndex;
43
+ const zIndex = window.getComputedStyle(current).zIndex;
44
44
  if (zIndex && zIndex !== ZINDEX_AUTO) {
45
- return zIndex;
45
+ return parseInt(zIndex, 10);
46
46
  }
47
47
  current = (current === null || current === void 0 ? void 0 : current.parentElement) ? current.parentElement : undefined;
48
48
  }
@@ -51,7 +51,7 @@ function getEffectiveZIndex(element) {
51
51
  function getDescendantElements(childElement) {
52
52
  let children = [childElement];
53
53
  const childNodes = Array.from(childElement.children);
54
- childNodes.forEach(el => {
54
+ childNodes.forEach((el) => {
55
55
  children = children.concat(getDescendantElements(el));
56
56
  });
57
57
  return children;
@@ -65,8 +65,8 @@ function matchWithWordBoundary(attribute, matchVal) {
65
65
  }
66
66
  function checkElementAttributes(element) {
67
67
  let matches = 0;
68
- ATTRIBUTES_TO_CHECK.forEach(attr => {
69
- CLOSE_VALUES.forEach(closeVal => {
68
+ ATTRIBUTES_TO_CHECK.forEach((attr) => {
69
+ CLOSE_VALUES.forEach((closeVal) => {
70
70
  if (element.getAttribute(attr.attributeName) &&
71
71
  attr.matchFunction(element.getAttribute(attr.attributeName), closeVal)) {
72
72
  matches += 1;
@@ -87,10 +87,10 @@ function checkElementDomCoverage(element) {
87
87
  }
88
88
  function developCloseCandidates(candidates) {
89
89
  const candidatesByZIndex = [];
90
- candidates.forEach(candidate => {
90
+ candidates.forEach((candidate) => {
91
91
  const domCovering = [];
92
92
  const actionableElements = [];
93
- candidate.elements.forEach(element => {
93
+ candidate.elements.forEach((element) => {
94
94
  var _a, _b;
95
95
  if ((_a = element) === null || _a === void 0 ? void 0 : _a.offsetParent) {
96
96
  if (['BUTTON', 'A', 'DIV'].includes((_b = element.tagName) === null || _b === void 0 ? void 0 : _b.toUpperCase()) &&
@@ -135,15 +135,16 @@ function fireClickEvent(targetElement, leftEdgeClick) {
135
135
  });
136
136
  targetElement.dispatchEvent(mouseEvent);
137
137
  }
138
- function elementsInFront(element, pointX, pointY) {
138
+ function elementsAtCoordinate(element, pointX, pointY) {
139
139
  const x = pointX !== undefined ? pointX : getBoundingClientRectWithXY(element).x;
140
140
  const y = pointY !== undefined ? pointY : getBoundingClientRectWithXY(element).y;
141
141
  const elementsAtPoint = document.elementsFromPoint(x, y);
142
- const targetIndex = elementsAtPoint.findIndex(iterElement => iterElement === element);
142
+ const targetIndex = elementsAtPoint.findIndex((iterElement) => iterElement === element);
143
143
  return targetIndex ? elementsAtPoint.slice(0, targetIndex) : [];
144
144
  }
145
+ exports.elementsAtCoordinate = elementsAtCoordinate;
145
146
  function sleep(time) {
146
- return new Promise(resolve => setTimeout(resolve, time));
147
+ return new Promise((resolve) => setTimeout(resolve, time));
147
148
  }
148
149
  function getBoundingClientRectWithXY(element) {
149
150
  const rect = element.getBoundingClientRect();
@@ -158,8 +159,15 @@ function getBoundingClientRectWithXY(element) {
158
159
  width: Math.floor(rect.right) - Math.ceil(rect.left),
159
160
  };
160
161
  }
161
- function getAllElementsAbove(elements) {
162
- const zIndexAboveTarget = getEffectiveZIndex(elements[elements.length - 1]);
162
+ function getAllElementsAbove(targetElement, elements) {
163
+ if (elements.length === 0) {
164
+ return [];
165
+ }
166
+ const targetZindex = getEffectiveZIndex(targetElement);
167
+ const zIndexAboveTarget = Math.min(...elements === null || elements === void 0 ? void 0 : elements.map((el) => getEffectiveZIndex(el)));
168
+ if (zIndexAboveTarget <= targetZindex) {
169
+ return [];
170
+ }
163
171
  const higherElementsByZIndex = elementsByHigherZIndex(zIndexAboveTarget);
164
172
  const allElementsByZIndex = Array.from(higherElementsByZIndex).map(([item, higherElements]) => {
165
173
  const allElements = higherElements
@@ -174,29 +182,25 @@ exports.getAllElementsAbove = getAllElementsAbove;
174
182
  async function detectAndDismissPopupCandidates(element) {
175
183
  const elementBoundingBox = getBoundingClientRectWithXY(element);
176
184
  try {
177
- let higherElements = elementsInFront(element, elementBoundingBox.x, elementBoundingBox.y);
185
+ let higherElements = elementsAtCoordinate(element, elementBoundingBox.x, elementBoundingBox.y);
178
186
  const elementsInFrontCount = higherElements.length;
179
187
  if (elementsInFrontCount === 0) {
180
188
  return {
181
- zIndex: 0,
182
189
  elementsInFront: 0,
183
190
  dismissedStatus: false,
184
- domCovering: [],
185
- actionableElements: [],
186
191
  };
187
192
  }
188
193
  const clickCandidates = async function (candidates, leftEdgeClick) {
189
194
  for (const candidate of candidates) {
190
195
  fireClickEvent(candidate, leftEdgeClick);
191
196
  await sleep(DISMISSAL_WAIT_TIME_MS);
192
- if (elementsInFront(element, elementBoundingBox.x, elementBoundingBox.y)
193
- .length < elementsInFrontCount) {
197
+ if (elementsAtCoordinate(element, elementBoundingBox.x, elementBoundingBox.y).length < elementsInFrontCount) {
194
198
  return true;
195
199
  }
196
200
  }
197
201
  return false;
198
202
  };
199
- let allElements = getAllElementsAbove(higherElements);
203
+ let allElements = getAllElementsAbove(element, higherElements);
200
204
  const candidatesByZIndex = developCloseCandidates(allElements);
201
205
  for (const candidate of candidatesByZIndex) {
202
206
  let matched = await clickCandidates(candidate.domCovering, true);
@@ -204,12 +208,14 @@ async function detectAndDismissPopupCandidates(element) {
204
208
  matched = await clickCandidates(candidate.actionableElements, false);
205
209
  }
206
210
  if (matched) {
207
- candidate.dismissedStatus = true;
208
- return candidate;
211
+ return {
212
+ dismissedStatus: true,
213
+ elementsInFront: 0,
214
+ };
209
215
  }
210
216
  }
211
- higherElements = elementsInFront(element, elementBoundingBox.x, elementBoundingBox.y);
212
- allElements = getAllElementsAbove(higherElements);
217
+ higherElements = elementsAtCoordinate(element, elementBoundingBox.x, elementBoundingBox.y);
218
+ allElements = getAllElementsAbove(element, higherElements);
213
219
  const candidates = developCloseCandidates(allElements);
214
220
  const result = candidates.length
215
221
  ? candidates[0]
@@ -222,21 +228,21 @@ async function detectAndDismissPopupCandidates(element) {
222
228
  };
223
229
  result.elementsInFront = higherElements.length;
224
230
  result.dismissedStatus = false;
225
- return result;
231
+ return {
232
+ dismissedStatus: result.dismissedStatus,
233
+ elementsInFront: result.elementsInFront,
234
+ };
226
235
  }
227
236
  catch (error) {
228
237
  return {
229
- zIndex: 0,
230
238
  elementsInFront: 0,
231
239
  dismissedStatus: false,
232
- domCovering: [],
233
- actionableElements: [],
234
- errorInDetection: error.toString(),
240
+ error: error.toString(),
235
241
  };
236
242
  }
237
243
  }
238
244
  exports.detectAndDismissPopupCandidates = detectAndDismissPopupCandidates;
239
245
  function elementsInFrontCount(element) {
240
- return elementsInFront(element).length;
246
+ return elementsAtCoordinate(element).length;
241
247
  }
242
248
  exports.elementsInFrontCount = elementsInFrontCount;
@@ -30,8 +30,7 @@ class AuthenticationProvider {
30
30
  this.oktaClient = new OktaClient_1.OktaClient(client);
31
31
  }
32
32
  async getAuthConfigWithAutoRenew() {
33
- let authConfig = cliConfigProvider_1.CliConfigProvider.getCliConfig()
34
- .authentication;
33
+ let authConfig = cliConfigProvider_1.CliConfigProvider.getCliConfig().authentication;
35
34
  if (authConfig.accessToken) {
36
35
  if (this.verbose) {
37
36
  loggingProvider_1.logger.info('Found existing access token');
@@ -134,7 +133,7 @@ class AuthenticationProvider {
134
133
  async authenticate() {
135
134
  var _a;
136
135
  try {
137
- const { codeChallenge, codeVerifier, } = this.oktaClient.generateCodeChallenge();
136
+ const { codeChallenge, codeVerifier } = this.oktaClient.generateCodeChallenge();
138
137
  const redirectUri = `${env_1.BASE_APP_URL}/app-code`;
139
138
  const authUrl = this.oktaClient.buildAuthorizationUrl(codeChallenge, redirectUri);
140
139
  loggingProvider_1.logger.info(`Your browser has been opened to the following URL for obtaining an authorization code:
@@ -103,7 +103,7 @@ class CliConfigProvider {
103
103
  };
104
104
  }
105
105
  static clearAuthConfig() {
106
- AUTH_KEY_NAMES.forEach(keyName => clearValue(keyName));
106
+ AUTH_KEY_NAMES.forEach((keyName) => clearValue(keyName));
107
107
  return this.getCliConfig();
108
108
  }
109
109
  static setCliConfig(config) {
@@ -69,7 +69,7 @@ class ExportRequestProvider {
69
69
  return new Promise((resolve, reject) => {
70
70
  setTimeout(() => this.awaitCompletion()
71
71
  .then(() => resolve())
72
- .catch(error => reject(error)), this.pollingIntervalMilliseconds);
72
+ .catch((error) => reject(error)), this.pollingIntervalMilliseconds);
73
73
  });
74
74
  }
75
75
  }
@@ -60,11 +60,11 @@ class CliTransport extends winston_transport_1.default {
60
60
  }
61
61
  exports.logger = winston.createLogger({
62
62
  level: defaultEnv_1.CONSOLE_LOGGING_LEVEL,
63
- format: winston.format.printf(info => `${stripAnsi(info.message)}`),
63
+ format: winston.format.printf((info) => `${stripAnsi(info.message)}`),
64
64
  defaultMeta: { service: 'mabl-cli' },
65
65
  transports: [
66
66
  new CliTransport({
67
- format: winston.format.printf(info => { var _a; return `${(_a = info.message) !== null && _a !== void 0 ? _a : info[MESSAGE]}`; }),
67
+ format: winston.format.printf((info) => { var _a; return `${(_a = info.message) !== null && _a !== void 0 ? _a : info[MESSAGE]}`; }),
68
68
  }),
69
69
  ],
70
70
  });
@@ -48,7 +48,7 @@ class ScmContextProvider {
48
48
  () => this.getForTravis(),
49
49
  ];
50
50
  let buildResultHolder;
51
- processors.some(processor => {
51
+ processors.some((processor) => {
52
52
  buildResultHolder = processor();
53
53
  return buildResultHolder;
54
54
  });
@@ -85,12 +85,16 @@ function generateMochAwesomeReportFromTestResults(testResults, reportOptions) {
85
85
  exports.generateMochAwesomeReportFromTestResults = generateMochAwesomeReportFromTestResults;
86
86
  function generatePlainSuiteFromTestResults(testResults) {
87
87
  const parentId = uuid_1.v4();
88
- const plainTests = testResults.testResults.map(testResult => generatePlainTestForTestRun(parentId, testResult));
89
- const passes = plainTests.filter(test => test.pass).map(test => test.uuid);
90
- const failures = plainTests.filter(test => test.fail).map(test => test.uuid);
88
+ const plainTests = testResults.testResults.map((testResult) => generatePlainTestForTestRun(parentId, testResult));
89
+ const passes = plainTests
90
+ .filter((test) => test.pass)
91
+ .map((test) => test.uuid);
92
+ const failures = plainTests
93
+ .filter((test) => test.fail)
94
+ .map((test) => test.uuid);
91
95
  const skipped = plainTests
92
- .filter(test => test.skipped)
93
- .map(test => test.uuid);
96
+ .filter((test) => test.skipped)
97
+ .map((test) => test.uuid);
94
98
  const command = constructTestRunCommand();
95
99
  return {
96
100
  uuid: parentId,
@@ -160,7 +164,7 @@ function getTestState(testResultStatus) {
160
164
  function constructTestRunCommand() {
161
165
  try {
162
166
  const processArgs = process.argv;
163
- const testArgIndex = processArgs.findIndex(arg => arg === 'tests');
167
+ const testArgIndex = processArgs.findIndex((arg) => arg === 'tests');
164
168
  if (testArgIndex) {
165
169
  processArgs.splice(0, testArgIndex + 1);
166
170
  }
@@ -29,7 +29,7 @@ exports.handleReportingForTestsRun = handleReportingForTestsRun;
29
29
  function parseOutReportOptions(suppliedOptions) {
30
30
  const reporterOptions = {};
31
31
  const pairs = suppliedOptions.split(',');
32
- pairs.forEach(pair => {
32
+ pairs.forEach((pair) => {
33
33
  const [key, value] = pair.split('=', 3);
34
34
  if (value.toLowerCase() === 'false' || value.toLowerCase() === 'true') {
35
35
  reporterOptions[key] = value.toLowerCase() === 'true';