@saucelabs/cypress-visual-plugin
Version:
Cypress plugin for Sauce Visual Testing
175 lines (173 loc) • 5.19 kB
JavaScript
import {
__spreadProps,
__spreadValues
} from "./chunk-CIGAQ47A.js";
// src/commands.ts
var visualLog = (msg, level = "error") => cy.task("visual-log", { level, msg });
function isRegion(elem) {
if ("x" in elem && "y" in elem && "width" in elem && "height" in elem) {
return true;
}
return false;
}
function isChainable(elem) {
return "chainerId" in elem;
}
function intoElement(region) {
return "element" in region ? region.element : region;
}
function getElementDimensions(elem) {
const rect = elem.getBoundingClientRect();
return {
x: Math.floor(rect.left),
y: Math.floor(rect.top),
width: Math.floor(rect.width),
height: Math.floor(rect.height)
};
}
function toChainableRegion(item) {
if (isChainable(item)) {
return item.then(($el) => {
const result = [];
for (let i = 0; i < $el.length; i++)
result.push(getElementDimensions($el[i]));
return result;
});
} else if (isRegion(item)) {
return cy.wrap([item]);
} else {
return cy.wrap([]);
}
}
function chainableWaitForAll(list) {
const result = [];
list.forEach((item) => {
item.then((el) => {
result.push(el);
});
});
return cy.wrap(result);
}
var sauceVisualCheckCommand = (screenshotName, options) => {
var _a, _b;
const { clipSelector } = options != null ? options : {};
const randomId = () => Cypress._.random(0, 1e9);
cy.task("visual-log-capture", { screenshotName });
const viewport = {
width: 0,
height: 0
};
cy.window({ log: false }).then((win) => {
viewport.width = win.innerWidth;
viewport.height = win.innerHeight;
});
if (clipSelector) {
cy.get(clipSelector).then((elem) => {
const firstMatch = elem.get().find((item) => item);
if (firstMatch) {
cy.wrap(getElementDimensions(firstMatch)).as("clipToBounds");
}
});
} else {
cy.wrap(void 0).as("clipToBounds");
}
const visualRegions = [
...((_a = options == null ? void 0 : options.ignoredRegions) != null ? _a : []).map((r) => ({
enableOnly: [],
element: r
})),
...(_b = options == null ? void 0 : options.regions) != null ? _b : []
];
const resolved = chainableWaitForAll(
visualRegions.map(intoElement).map(toChainableRegion)
);
const regionsPromise = resolved.then((regions) => {
let hasError = false;
const result = [];
for (const idx in regions) {
if (regions[idx].length === 0) {
visualLog(
`sauce-visual: ignoreRegion[${idx}] does not exists or is empty`
);
hasError = true;
}
for (const plainRegion of regions[idx]) {
result.push(__spreadProps(__spreadValues({}, visualRegions[idx]), {
element: plainRegion
}));
}
}
if (hasError)
throw new Error(
"Some region are invalid. Please check the log for details."
);
return result;
});
const screenshotId = `sauce-visual-${randomId()}`;
cy.window({ log: false }).then((win) => {
cy.task("get-script", { log: false }).then((script) => {
const realViewport = viewport.height && viewport.width ? viewport : void 0;
const getDom = () => {
if (!(options == null ? void 0 : options.captureDom))
return null;
try {
if (!script)
throw new Error(`Cannot get dom capturing script.`);
const dom = win.eval(
`(function({ clipSelector }){${script}})({ clipSelector: '${clipSelector}' })`
);
if (typeof dom !== "string")
throw new Error(`Dom type should be a string not a ${typeof dom}.`);
return dom;
} catch (err) {
visualLog(`sauce-visual: Failed to capture dom:
${err}`);
return null;
}
};
return regionsPromise.then((regions) => {
var _a2;
cy.task("visual-register-screenshot", {
id: screenshotId,
name: screenshotName,
suiteName: Cypress.currentTest.titlePath.slice(0, -1).join(" "),
testName: Cypress.currentTest.title,
regions,
diffingMethod: options == null ? void 0 : options.diffingMethod,
diffingOptions: options == null ? void 0 : options.diffingOptions,
devicePixelRatio: win.devicePixelRatio,
viewport: realViewport,
dom: (_a2 = getDom()) != null ? _a2 : void 0
});
});
});
});
cy.get("@clipToBounds").then(
(clipToBounds) => {
cy.screenshot(screenshotId, __spreadValues({
clip: clipToBounds
}, options == null ? void 0 : options.cypress));
}
);
};
Cypress.Commands.add(
"visualCheck",
(screenshotName, options) => {
visualLog(
`sauce-visual: Command "visualCheck" is deprecated and will be removed in a future version. Please use "sauceVisualCheck".`,
"warn"
);
return sauceVisualCheckCommand(screenshotName, options);
}
);
Cypress.Commands.add("sauceVisualCheck", sauceVisualCheckCommand);
Cypress.Commands.add("sauceVisualResults", () => {
return cy.task("visual-test-results");
});
export {
getElementDimensions,
intoElement,
isChainable,
isRegion,
toChainableRegion
};