@applitools/utils
Advanced tools
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.disableCanvasPreserveDrawingBuffer = void 0; | ||
| function disableCanvasPreserveDrawingBuffer() { | ||
| function disablePreserveDrawingBuffer() { | ||
| if (HTMLCanvasElement.prototype.__isPatchedForDisablePreserveDrawingBuffer) { | ||
| // eslint-disable-next-line no-console | ||
| console.log('Canvas preserveDrawingBuffer patch has already been applied.'); | ||
| return; | ||
| } | ||
| // eslint-disable-next-line no-console | ||
| console.log('Applying canvas preserveDrawingBuffer patch...'); | ||
| const originalGetContext = HTMLCanvasElement.prototype.getContext; | ||
| function getContextPatched(contextId, contextAttributes) { | ||
| if (contextId === 'webgl' || contextId === 'webgl2') { | ||
| if (typeof contextAttributes !== 'object' || contextAttributes === null) { | ||
| contextAttributes = {}; | ||
| } | ||
| contextAttributes.preserveDrawingBuffer = false; | ||
| } | ||
| return originalGetContext.apply(this, [contextId, contextAttributes]); | ||
| } | ||
| HTMLCanvasElement.prototype.getContext = getContextPatched; | ||
| Object.defineProperty(HTMLCanvasElement.prototype, '__isPatchedForDisablePreserveDrawingBuffer', { | ||
| value: true, | ||
| writable: false, | ||
| configurable: true, | ||
| }); | ||
| } | ||
| // eslint-disable-next-line no-console | ||
| console.log('✅ Patch applied. New WebGL contexts will now not preserve their drawing buffer.'); | ||
| if (typeof window !== 'undefined') { | ||
| Object.assign(window, { disablePreserveDrawingBuffer }); | ||
| } | ||
| disablePreserveDrawingBuffer(); | ||
| } | ||
| exports.disableCanvasPreserveDrawingBuffer = disableCanvasPreserveDrawingBuffer; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.enableCanvasPreserveDrawingBuffer = void 0; | ||
| function enableCanvasPreserveDrawingBuffer() { | ||
| function enablePreserveDrawingBuffer() { | ||
| if (HTMLCanvasElement.prototype.__isPatchedForPreserveDrawingBuffer) { | ||
| // eslint-disable-next-line no-console | ||
| console.log('Canvas preserveDrawingBuffer patch has already been applied.'); | ||
| return; | ||
| } | ||
| // eslint-disable-next-line no-console | ||
| console.log('Applying canvas preserveDrawingBuffer patch...'); | ||
| const originalGetContext = HTMLCanvasElement.prototype.getContext; | ||
| function getContextPatched(contextId, contextAttributes) { | ||
| if (contextId === 'webgl' || contextId === 'webgl2') { | ||
| if (typeof contextAttributes !== 'object' || contextAttributes === null) { | ||
| contextAttributes = {}; | ||
| } | ||
| contextAttributes.preserveDrawingBuffer = true; | ||
| } | ||
| return originalGetContext.apply(this, [contextId, contextAttributes]); | ||
| } | ||
| HTMLCanvasElement.prototype.getContext = getContextPatched; | ||
| Object.defineProperty(HTMLCanvasElement.prototype, '__isPatchedForPreserveDrawingBuffer', { | ||
| value: true, | ||
| writable: false, | ||
| configurable: true, | ||
| }); | ||
| // eslint-disable-next-line no-console | ||
| console.log('✅ Patch applied. New WebGL contexts will now preserve their drawing buffer.'); | ||
| } | ||
| if (typeof window !== 'undefined') { | ||
| Object.assign(window, { enablePreserveDrawingBuffer }); | ||
| } | ||
| enablePreserveDrawingBuffer(); | ||
| } | ||
| exports.enableCanvasPreserveDrawingBuffer = enableCanvasPreserveDrawingBuffer; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.captureImagesFunc = void 0; | ||
| function captureImagesFunc() { | ||
| async function isNonBlackImage(dataUrl) { | ||
| const img = new Image(); | ||
| img.src = dataUrl; | ||
| await new Promise((resolve, reject) => { | ||
| img.onload = () => resolve(); | ||
| img.onerror = () => reject(); | ||
| }); | ||
| const canvas = document.createElement('canvas'); | ||
| canvas.width = img.width; | ||
| canvas.height = img.height; | ||
| const ctx = canvas.getContext('2d'); | ||
| if (!ctx) | ||
| return false; | ||
| ctx.drawImage(img, 0, 0); | ||
| const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height).data; | ||
| for (let i = 0; i < imageData.length; i += 4) { | ||
| if (imageData[i] !== 0 || imageData[i + 1] !== 0 || imageData[i + 2] !== 0) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| function processWebGLCanvases(win) { | ||
| Array.from(win.document.getElementsByTagName('canvas')).forEach((canvas) => { | ||
| const gl = canvas.getContext('webgl') || canvas.getContext('webgl2'); | ||
| if (!gl) | ||
| return; | ||
| const attrs = gl.getContextAttributes(); | ||
| if (!attrs) | ||
| return; | ||
| const { preserveDrawingBuffer } = attrs; | ||
| if (!preserveDrawingBuffer && canvas.width > 0 && canvas.height > 0) { | ||
| const dataUrl = canvas.toDataURL('image/png'); | ||
| if ((canvas.dataset.dataUrl || '') === dataUrl) | ||
| return; | ||
| isNonBlackImage(dataUrl).then(result => { | ||
| if (result) { | ||
| canvas.dataset.dataUrl = dataUrl; | ||
| } | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| function patchRequestAnimationFrame(win) { | ||
| var _a; | ||
| if (win.__rafPatched) { | ||
| return; | ||
| } | ||
| const HTMLCanvasElementCtor = win.HTMLCanvasElement || | ||
| (win.constructor && win.constructor.HTMLCanvasElement) || | ||
| (win.document && ((_a = win.document.defaultView) === null || _a === void 0 ? void 0 : _a.HTMLCanvasElement)); | ||
| const origGetContext = (HTMLCanvasElementCtor && HTMLCanvasElementCtor.prototype.getContext); | ||
| if (!origGetContext) { | ||
| return; | ||
| } | ||
| const originalRAF = win.requestAnimationFrame; | ||
| win.requestAnimationFrame = function (callback) { | ||
| const rafId = originalRAF.call(this, (time) => { | ||
| callback.call(win, time); | ||
| processWebGLCanvases(win); | ||
| }); | ||
| return rafId; | ||
| }; | ||
| win.__rafPatched = true; | ||
| } | ||
| function takeCanvasScreenshots(win = window) { | ||
| if (win.__rafPatched) { | ||
| return; | ||
| } | ||
| try { | ||
| patchRequestAnimationFrame(win); | ||
| } | ||
| catch (e) { } | ||
| } | ||
| Object.assign(window, { takeCanvasScreenshots }); | ||
| takeCanvasScreenshots(); | ||
| } | ||
| exports.captureImagesFunc = captureImagesFunc; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./capture-canvas-disable-preserve-drawing-buffer"), exports); | ||
| __exportStar(require("./capture-canvas-enable-preserve-drawing-buffer"), exports); | ||
| __exportStar(require("./capture-canvas-image-always"), exports); |
| export declare function disableCanvasPreserveDrawingBuffer(): void; |
| export declare function enableCanvasPreserveDrawingBuffer(): void; |
| export declare function captureImagesFunc(): void; |
| export * from './capture-canvas-disable-preserve-drawing-buffer'; | ||
| export * from './capture-canvas-enable-preserve-drawing-buffer'; | ||
| export * from './capture-canvas-image-always'; |
+7
-0
| # Changelog | ||
| ## [1.12.0](https://github.com/Applitools-Dev/sdk/compare/js/utils@1.11.1...js/utils@1.12.0) (2025-09-09) | ||
| ### Features | ||
| * enable canvas with webgl for autonomous | FLD 3515 ([#3197](https://github.com/Applitools-Dev/sdk/issues/3197)) ([23f22e5](https://github.com/Applitools-Dev/sdk/commit/23f22e517d52dc70f24093dfb21e072b9aa9fb60)) | ||
| ## [1.11.1](https://github.com/Applitools-Dev/sdk/compare/js/utils@1.11.0...js/utils@1.11.1) (2025-08-12) | ||
@@ -4,0 +11,0 @@ |
+2
-1
@@ -29,3 +29,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.config = exports.process = exports.streams = exports.math = exports.queues = exports.promises = exports.geometry = exports.general = exports.guard = exports.types = void 0; | ||
| exports.snippets = exports.config = exports.process = exports.streams = exports.math = exports.queues = exports.promises = exports.geometry = exports.general = exports.guard = exports.types = void 0; | ||
| __exportStar(require("./utility-types"), exports); | ||
@@ -42,1 +42,2 @@ exports.types = __importStar(require("./types")); | ||
| exports.config = __importStar(require("./config")); | ||
| exports.snippets = __importStar(require("./snippets")); |
+1
-1
| { | ||
| "name": "@applitools/utils", | ||
| "version": "1.11.1", | ||
| "version": "1.12.0", | ||
| "keywords": [ | ||
@@ -5,0 +5,0 @@ "applitools", |
+1
-0
@@ -12,1 +12,2 @@ export * from './utility-types'; | ||
| export * as config from './config'; | ||
| export * as snippets from './snippets'; |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
105565
8.67%41
24.24%1939
10.42%