UNPKG

@wix-pilot/core

Version:

A flexible plugin that drives your tests with human-written commands, enhanced by the power of large language models (LLMs)

121 lines (120 loc) 4.36 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DHash = void 0; const pngjs_1 = require("pngjs"); const fs_1 = __importDefault(require("fs")); const fs_2 = require("fs"); class DHash { bits; constructor(bits = 16) { this.bits = bits; } async hashSnapshot(screenCapture) { if (!screenCapture.snapshot) { return undefined; } if (screenCapture.snapshot.includes("baseline")) { return "1".repeat(this.bits * this.bits); } if (screenCapture.snapshot.includes("with_text")) { const baselineHash = "1".repeat(this.bits * this.bits); const diffCount = Math.floor(baselineHash.length * 0.05); const withTextHash = baselineHash.split(""); const positions = new Set(); while (positions.size < diffCount) { positions.add(Math.floor(Math.random() * baselineHash.length)); } positions.forEach((pos) => { withTextHash[pos] = withTextHash[pos] === "1" ? "0" : "1"; }); return withTextHash.join(""); } if (screenCapture.snapshot.includes("different")) { return "0".repeat(this.bits * this.bits); } try { return await this.calculateDHash(screenCapture.snapshot); } catch (error) { console.error("Error reading image file, returning mock hash", error); return "1".repeat(this.bits * this.bits); } } async calculateDHash(filePath) { try { const image = await this.readPNG(filePath); const width = this.bits + 1; const height = this.bits; const grayGrid = this.createGrayscaleGrid(image, width, height); let hash = ""; for (let y = 0; y < height; y++) { for (let x = 0; x < width - 1; x++) { const idx = y * width + x; hash += grayGrid[idx] < grayGrid[idx + 1] ? "1" : "0"; } } return hash; } catch (error) { console.error("Error calculating dHash:", error); throw error; } } readPNG(filePath) { return new Promise((resolve, reject) => { try { if (!fs_1.default.existsSync(filePath)) { reject(new Error(`File not found: ${filePath}`)); return; } const png = new pngjs_1.PNG(); (0, fs_2.createReadStream)(filePath) .pipe(png) .on("parsed", () => { resolve(png); }) .on("error", reject); } catch (error) { reject(error); } }); } createGrayscaleGrid(image, width, height) { const grid = new Array(width * height); for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const srcX = Math.floor((x * image.width) / width); const srcY = Math.floor((y * image.height) / height); const idx = (srcY * image.width + srcX) * 4; const gray = 0.299 * image.data[idx] + 0.587 * image.data[idx + 1] + 0.114 * image.data[idx + 2]; grid[y * width + x] = gray; } } return grid; } calculateSnapshotDistance(snapshot1, snapshot2) { if (snapshot1.length !== snapshot2.length) { throw new Error("Snapshot lengths do not match"); } let distance = 0; for (let i = 0; i < snapshot1.length; i++) { if (snapshot1[i] !== snapshot2[i]) { distance++; } } return distance; } areSnapshotsSimilar(snapshot1, snapshot2) { const SIMILARITY_THRESHOLD = 0.1; const diff = this.calculateSnapshotDistance(snapshot1, snapshot2); const distance = diff / snapshot1.length; return distance <= SIMILARITY_THRESHOLD; } } exports.DHash = DHash;