@mablhq/mabl-cli 1.12.6 → 1.12.24
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/browserLauncher/browserLauncher.js +3 -1
- package/browserLauncher/elementHandle.js +8 -1
- package/browserLauncher/frame.js +15 -0
- package/browserLauncher/frameBase.js +4 -0
- package/browserLauncher/playwrightBrowserLauncher/playwrightDom.js +97 -23
- package/browserLauncher/playwrightBrowserLauncher/playwrightFrame.js +10 -6
- package/browserLauncher/playwrightBrowserLauncher/playwrightPage.js +28 -60
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerElementHandle.js +54 -0
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerFrame.js +2 -1
- package/browserLauncher/puppeteerBrowserLauncher/puppeteerPage.js +0 -45
- package/cli.js +0 -5
- package/core/messaging/messaging.js +14 -1
- package/execution/index.js +1 -1
- package/mablApi/index.js +1 -1
- package/mablscriptFind/index.js +1 -1
- package/package.json +2 -1
- package/popupDismissal/index.js +6 -5
- package/resources/mablFind.js +1 -1
- package/resources/popupDismissal.js +1 -1
- package/util/actionabilityUtil.js +35 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
window.popupDismissal=function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e),n.d(e,"elementsByHigherZIndex",(function(){return i})),n.d(e,"detectAndDismissPopupCandidates",(function(){return h})),n.d(e,"elementsInFrontCount",(function(){return g}));const o=["close","dismiss","exit","not at this time","no thanks","no, thanks","i, agree","i agree"],r=[{attributeName:"className",matchFunction:a},{attributeName:"name",matchFunction:a},{attributeName:"id",matchFunction:a},{attributeName:"href",matchFunction:a},{attributeName:"innerText",matchFunction:function(t,e){const n=new RegExp(`\\b${e}\\b`);return!!t.toLowerCase().match(n)}}];function i(t){return Array.from(document.querySelectorAll("body *")).reduce((e,n)=>{const o=parseFloat(window.getComputedStyle(n).zIndex);return!Number.isNaN(o)&&o>=t&&(e.has(o)?e.get(o).push(n):e.set(o,[n])),e},new Map)}function u(t){let e=[t];return Array.from(t.children).forEach(t=>{e=e.concat(u(t))}),e}function a(t,e){return t.toLowerCase().includes(e)}function c(t){const e=[];return t.forEach(t=>{const n=[],i=[];t.elements.forEach(t=>{var e,u;(null===(e=t)||void 0===e?void 0:e.offsetParent)&&(["BUTTON","A","DIV"].includes(null===(u=t.tagName)||void 0===u?void 0:u.toUpperCase())&&function(t){let e=0;return r.forEach(n=>{o.forEach(o=>{t.getAttribute(n.attributeName)&&n.matchFunction(t.getAttribute(n.attributeName),o)&&(e+=1)})}),e}(t)&&!i.includes(t)?i.push(t):function(t){if(t.getBoundingClientRect){const e=t.getBoundingClientRect(),n=e.width/window.innerWidth,o=e.height/window.innerHeight;return n>.95&&o>.95}return!1}(t)&&n.push(t))}),e.push({zIndex:t.zIndex,actionableElements:i,domCovering:n,dismissedStatus:!1,elementsInFront:0})}),e}function s(t,e){const n=t.getBoundingClientRect(),o=n.height/2,r=e?1:n.width/2,i=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,detail:0,screenX:n.left+r,screenY:n.top+o,clientX:t.clientLeft+r,clientY:t.clientTop+o,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:void 0});t.dispatchEvent(i)}function l(t,e,n){const o=void 0!==e?e:f(t).x,r=void 0!==n?n:f(t).y,i=document.elementsFromPoint(o,r),u=i.findIndex(e=>e===t);return u?i.slice(0,u):[]}function d(t){return new Promise(e=>setTimeout(e,t))}function f(t){const e=t.getBoundingClientRect();return{x:Math.floor(e.x),y:Math.floor(e.y),top:Math.floor(e.top),bottom:Math.ceil(e.bottom),left:Math.floor(e.left),right:Math.ceil(e.right),height:Math.floor(e.bottom)-Math.ceil(e.top),width:Math.floor(e.right)-Math.ceil(e.left)}}function m(t){const e=i(function(t
|
|
1
|
+
window.popupDismissal=function(t){var e={};function n(o){if(e[o])return e[o].exports;var r=e[o]={i:o,l:!1,exports:{}};return t[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}return n.m=t,n.c=e,n.d=function(t,e,o){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:o})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)n.d(o,r,function(e){return t[e]}.bind(null,r));return o},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e),n.d(e,"elementsByHigherZIndex",(function(){return i})),n.d(e,"getAllElementsAbove",(function(){return m})),n.d(e,"detectAndDismissPopupCandidates",(function(){return h})),n.d(e,"elementsInFrontCount",(function(){return g}));const o=["close","dismiss","exit","not at this time","no thanks","no, thanks","i, agree","i agree"],r=[{attributeName:"className",matchFunction:a},{attributeName:"name",matchFunction:a},{attributeName:"id",matchFunction:a},{attributeName:"href",matchFunction:a},{attributeName:"innerText",matchFunction:function(t,e){const n=new RegExp(`\\b${e}\\b`);return!!t.toLowerCase().match(n)}}];function i(t){return Array.from(document.querySelectorAll("body *")).reduce((e,n)=>{const o=parseFloat(window.getComputedStyle(n).zIndex);return!Number.isNaN(o)&&o>=t&&(e.has(o)?e.get(o).push(n):e.set(o,[n])),e},new Map)}function u(t){let e=[t];return Array.from(t.children).forEach(t=>{e=e.concat(u(t))}),e}function a(t,e){return t.toLowerCase().includes(e)}function c(t){const e=[];return t.forEach(t=>{const n=[],i=[];t.elements.forEach(t=>{var e,u;(null===(e=t)||void 0===e?void 0:e.offsetParent)&&(["BUTTON","A","DIV"].includes(null===(u=t.tagName)||void 0===u?void 0:u.toUpperCase())&&function(t){let e=0;return r.forEach(n=>{o.forEach(o=>{t.getAttribute(n.attributeName)&&n.matchFunction(t.getAttribute(n.attributeName),o)&&(e+=1)})}),e}(t)&&!i.includes(t)?i.push(t):function(t){if(t.getBoundingClientRect){const e=t.getBoundingClientRect(),n=e.width/window.innerWidth,o=e.height/window.innerHeight;return n>.95&&o>.95}return!1}(t)&&n.push(t))}),e.push({zIndex:t.zIndex,actionableElements:i,domCovering:n,dismissedStatus:!1,elementsInFront:0})}),e}function s(t,e){const n=t.getBoundingClientRect(),o=n.height/2,r=e?1:n.width/2,i=new MouseEvent("click",{bubbles:!0,cancelable:!0,view:window,detail:0,screenX:n.left+r,screenY:n.top+o,clientX:t.clientLeft+r,clientY:t.clientTop+o,ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1,button:0,relatedTarget:void 0});t.dispatchEvent(i)}function l(t,e,n){const o=void 0!==e?e:f(t).x,r=void 0!==n?n:f(t).y,i=document.elementsFromPoint(o,r),u=i.findIndex(e=>e===t);return u?i.slice(0,u):[]}function d(t){return new Promise(e=>setTimeout(e,t))}function f(t){const e=t.getBoundingClientRect();return{x:Math.floor(e.x),y:Math.floor(e.y),top:Math.floor(e.top),bottom:Math.ceil(e.bottom),left:Math.floor(e.left),right:Math.ceil(e.right),height:Math.floor(e.bottom)-Math.ceil(e.top),width:Math.floor(e.right)-Math.ceil(e.left)}}function m(t){const e=i(function(t){const e=t=>void 0===t||"html"===t.tagName.toLowerCase();let n=t;for(;!e(n);){const e=window.getComputedStyle(t).zIndex;if(e&&"auto"!==e)return e;n=(null==n?void 0:n.parentElement)?n.parentElement:void 0}return 0}(t[t.length-1])),n=Array.from(e).map(([t,e])=>({zIndex:t,elements:e.flatMap(u).reverse()}));return n.sort((t,e)=>e.zIndex-t.zIndex),n}async function h(t){const e=f(t);try{let n=l(t,e.x,e.y);const o=n.length;if(0===o)return{zIndex:0,elementsInFront:0,dismissedStatus:!1,domCovering:[],actionableElements:[]};const r=async function(n,r){for(const i of n)if(s(i,r),await d(750),l(t,e.x,e.y).length<o)return!0;return!1};let i=m(n);const u=c(i);for(const t of u){let e=await r(t.domCovering,!0);if(e||(e=await r(t.actionableElements,!1)),e)return t.dismissedStatus=!0,t}n=l(t,e.x,e.y),i=m(n);const a=c(i),f=a.length?a[0]:{zIndex:0,elementsInFront:0,dismissedStatus:!1,domCovering:[],actionableElements:[]};return f.elementsInFront=n.length,f.dismissedStatus=!1,f}catch(t){return{zIndex:0,elementsInFront:0,dismissedStatus:!1,domCovering:[],actionableElements:[],errorInDetection:t.toString()}}}function g(t){return l(t).length}}]);
|
|
@@ -19,15 +19,38 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
19
19
|
return result;
|
|
20
20
|
};
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.maybeAddPopupLogic = exports.checkActionabilityAt = void 0;
|
|
22
|
+
exports.maybeAddPopupLogic = exports.checkActionabilityAt = exports.checkActionabilityAtWithRetries = void 0;
|
|
23
23
|
const fs = __importStar(require("fs"));
|
|
24
24
|
const resourceUtil_1 = require("./resourceUtil");
|
|
25
25
|
const messaging_1 = require("../core/messaging/messaging");
|
|
26
|
+
const ExecutorUtils_1 = require("../execution/actions/ExecutorUtils");
|
|
27
|
+
const logUtils_1 = require("./logUtils");
|
|
28
|
+
const loggingProvider_1 = require("../providers/logging/loggingProvider");
|
|
26
29
|
const ACTIONABILITY_CHECK_SCRIPT_LOCATION = resourceUtil_1.findResource('actionabilityCheck.js');
|
|
27
30
|
const EMBEDDED_POPUP_SCRIPT_LOCATION = resourceUtil_1.findResource('popupDismissal.js');
|
|
31
|
+
const NO_CLICKABLE_POINT_ERROR = 'Unable to find a clickable point for the element';
|
|
28
32
|
let embeddedPopupScript;
|
|
29
33
|
let embeddedActionabilityLogic;
|
|
30
|
-
async function
|
|
34
|
+
async function checkActionabilityAtWithRetries(elementHandle, executionContext, failIfClickablePointWasNotFound = true) {
|
|
35
|
+
var _a, _b, _c, _d;
|
|
36
|
+
let actionabilityResult;
|
|
37
|
+
try {
|
|
38
|
+
actionabilityResult = await ExecutorUtils_1.runWithRetries(() => checkActionabilityAt(elementHandle, executionContext), 10, ['Element not at point', 'Element not clickable at point'], executionContext);
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (failIfClickablePointWasNotFound && error === NO_CLICKABLE_POINT_ERROR) {
|
|
42
|
+
throw new Error('Unable to find a clickable point for the element');
|
|
43
|
+
}
|
|
44
|
+
logUtils_1.logWebUIAndCliOutput(`Found element may not be actionable`, loggingProvider_1.LogLevel.Warn, executionContext, { executionPhase: messaging_1.ExecutionPhase.DURING_ACTION });
|
|
45
|
+
logUtils_1.logInternal(`Found element might not be actionable at the expected point (x: ${(_b = (_a = actionabilityResult === null || actionabilityResult === void 0 ? void 0 : actionabilityResult.clickablePoint) === null || _a === void 0 ? void 0 : _a.x) !== null && _b !== void 0 ? _b : 'Not found'}, y: ${(_d = (_c = actionabilityResult === null || actionabilityResult === void 0 ? void 0 : actionabilityResult.clickablePoint) === null || _c === void 0 ? void 0 : _c.y) !== null && _d !== void 0 ? _d : 'Not found'}), performing action anyway`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.checkActionabilityAtWithRetries = checkActionabilityAtWithRetries;
|
|
49
|
+
async function checkActionabilityAt(elementHandle, executionContext, recheckOnFail = true) {
|
|
50
|
+
let point = await elementHandle.clickablePoint();
|
|
51
|
+
if (point === undefined) {
|
|
52
|
+
throw new Error(NO_CLICKABLE_POINT_ERROR);
|
|
53
|
+
}
|
|
31
54
|
const frame = await elementHandle.frame();
|
|
32
55
|
if (frame === null || frame === void 0 ? void 0 : frame.parentFrame()) {
|
|
33
56
|
const element = await frame.getFrameOwnerElement();
|
|
@@ -40,22 +63,22 @@ async function checkActionabilityAt(elementHandle, point, executionContext, with
|
|
|
40
63
|
}
|
|
41
64
|
}
|
|
42
65
|
await maybeAddActionabilityLogic(elementHandle);
|
|
43
|
-
const result = await elementHandle.evaluate((node, point) => mablCheckActionability(node, point), point);
|
|
66
|
+
const result = await elementHandle.evaluate((node, point) => mablCheckActionability(node, point), { ...point });
|
|
44
67
|
if (result !== 'done') {
|
|
45
68
|
if (typeof result === 'object' && 'actionabilityDescription' in result) {
|
|
46
|
-
|
|
47
|
-
await attemptPopupDismissal(elementHandle
|
|
48
|
-
if (
|
|
49
|
-
return checkActionabilityAt(elementHandle,
|
|
69
|
+
logUtils_1.logInternal(`${result.actionabilityDescription} intercepts pointer events. Trying to auto-dismiss popups.`);
|
|
70
|
+
await attemptPopupDismissal(elementHandle);
|
|
71
|
+
if (recheckOnFail) {
|
|
72
|
+
return checkActionabilityAt(elementHandle, executionContext, false);
|
|
50
73
|
}
|
|
51
74
|
throw new Error(`Element not clickable at point.`);
|
|
52
75
|
}
|
|
53
76
|
throw new Error(`Element not at point. ${result}`);
|
|
54
77
|
}
|
|
55
|
-
return result;
|
|
78
|
+
return { result, clickablePoint: point };
|
|
56
79
|
}
|
|
57
80
|
exports.checkActionabilityAt = checkActionabilityAt;
|
|
58
|
-
async function attemptPopupDismissal(element
|
|
81
|
+
async function attemptPopupDismissal(element) {
|
|
59
82
|
const frame = await element.frame();
|
|
60
83
|
if (frame === undefined) {
|
|
61
84
|
return false;
|
|
@@ -64,19 +87,19 @@ async function attemptPopupDismissal(element, logger) {
|
|
|
64
87
|
const { dismissedStatus, elementsInFront } = await element.evaluate(element => window.popupDismissal.detectAndDismissPopupCandidates(element));
|
|
65
88
|
if (!dismissedStatus) {
|
|
66
89
|
if (elementsInFront) {
|
|
67
|
-
|
|
90
|
+
logUtils_1.logInternal('Failed to auto dismiss and there are still elements in front. Sending escape key to body.');
|
|
68
91
|
const bodyElement = await frame.$('BODY');
|
|
69
92
|
if (bodyElement) {
|
|
70
93
|
await bodyElement.press('Escape');
|
|
71
94
|
}
|
|
72
95
|
const elementsInFront = await element.evaluate(element => window.popupDismissal.elementsInFrontCount(element));
|
|
73
96
|
if (elementsInFront) {
|
|
74
|
-
|
|
97
|
+
logUtils_1.logInternal('The popup did not dismiss using the escape key.');
|
|
75
98
|
return false;
|
|
76
99
|
}
|
|
77
100
|
}
|
|
78
101
|
else {
|
|
79
|
-
|
|
102
|
+
logUtils_1.logInternal('Failed to auto dismiss. No elements found in front of target element.');
|
|
80
103
|
return false;
|
|
81
104
|
}
|
|
82
105
|
}
|