UNPKG

@progress/kendo-e2e

Version:

Kendo UI end-to-end test utilities.

159 lines 6.39 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.compareHtml = compareHtml; exports.getPartialHtml = getPartialHtml; exports.sanitizeNGSelectors = sanitizeNGSelectors; /* eslint-disable prefer-const */ const sanitize_html_1 = __importDefault(require("sanitize-html")); const jsdom_1 = __importDefault(require("jsdom")); /** * Check if two html documents have same class hierarchy. * * @example * await compareHtml("<div class="set">SET</div>", "<div class="qa">QA</div>"); * * @param actualHtml An html object. * @param expectedHtml An html object. */ function compareHtml(actualHtml, expectedHtml, options) { const passed = []; const missing = []; const extra = []; let actualSelectors = []; let expectedSelectors = []; const result = { passed, missing, extra, actualSelectors, expectedSelectors }; const config = { allowedTags: false, allowVulnerableTags: true, allowedAttributes: { "*": ["class"] }, }; const actualDom = new jsdom_1.default.JSDOM((0, sanitize_html_1.default)(actualHtml, config)).window.document.documentElement; const expectedDom = new jsdom_1.default.JSDOM((0, sanitize_html_1.default)(expectedHtml, config)).window.document.documentElement; let parent = ""; parseDom(actualDom, actualSelectors, parent); parent = ""; parseDom(expectedDom, expectedSelectors); if (options === null || options === void 0 ? void 0 : options.sanitizeNGSelectors) { const sanitizedActualSelectors = []; for (const actualSelector of actualSelectors) { sanitizedActualSelectors.push(sanitizeNGSelectors(actualSelector)); } actualSelectors = sanitizedActualSelectors; } result.actualSelectors = actualSelectors; result.expectedSelectors = expectedSelectors; // Delete all allowed missing from expected selectors let expectedSelectorsWithoutMissing = []; if ((options === null || options === void 0 ? void 0 : options.allowMissing) !== undefined) { for (const selector of expectedSelectors) { let replacedSelector = selector; for (const missingItem of options === null || options === void 0 ? void 0 : options.allowMissing) { replacedSelector = removeDuplicatedSpaces(replacedSelector.replace(new RegExp(`${missingItem}(?![a-z])(?!-)`, 'g'), '')); } if (replacedSelector !== '') { expectedSelectorsWithoutMissing.push(replacedSelector); } } expectedSelectorsWithoutMissing = [...new Set(expectedSelectorsWithoutMissing)]; } else { expectedSelectorsWithoutMissing = expectedSelectors; } // Delete all allowed extra from actual selectors let actualWithoutExtra = []; if ((options === null || options === void 0 ? void 0 : options.allowExtra) !== undefined) { for (const selector of actualSelectors) { let replacedSelector = selector; for (const extraItem of options === null || options === void 0 ? void 0 : options.allowExtra) { replacedSelector = removeDuplicatedSpaces(replacedSelector.replace(new RegExp(`${extraItem}(?![a-z])(?!-)`, 'g'), '')); } if (replacedSelector !== '') { actualWithoutExtra.push(replacedSelector); } } actualWithoutExtra = [...new Set(actualWithoutExtra)]; } else { actualWithoutExtra = actualSelectors; } result.missing = expectedSelectorsWithoutMissing.filter((element) => !actualWithoutExtra.includes(element)); // Detect extra elements result.extra = []; result.passed = []; if (actualWithoutExtra.length > 0) { for (const selector of actualWithoutExtra) { const dom = new jsdom_1.default.JSDOM((0, sanitize_html_1.default)(expectedHtml, config)); const element = dom.window.document.querySelector(selector); if (element === null) { result.extra.push(selector); } else { result.passed.push(selector); } } result.extra = [...new Set(result.extra)]; result.passed = [...new Set(result.passed)]; } return result; } /** * Get partial html of bigger html block. * * @example * await getPartialHtml("<div><ul class="k-list"><ul></div>", ".k-list"); * * @param originalHtml An html object. * @param selector Css selector. */ function getPartialHtml(originalHtml, selector) { const config = { allowedTags: false, allowVulnerableTags: true, allowedAttributes: { "*": ["class"] }, }; const dom = new jsdom_1.default.JSDOM((0, sanitize_html_1.default)(originalHtml, config)); const element = dom.window.document.querySelector(selector); if (element !== null) { return element.outerHTML; } else { return ''; } } /** * Remove angular specific selectors. * * @example * await sanitize(".k-scrollview.ng-tns-c43-0 .k-scrollview-wrap.ng-tns-c43-0.ng-trigger.ng-trigger-animateTo"); * * @param selector Css selector as string. */ function sanitizeNGSelectors(selector) { const selectorsArray = selector.split(" "); const filteredArray = []; for (const selectorPart of selectorsArray) { const filteredPart = selectorPart.split(".").filter((s) => !s.startsWith('ng-')).join("."); filteredArray.push(filteredPart); } return removeDuplicatedSpaces(filteredArray.join(" ")); } function parseDom(node, attributes, parent = "") { if (node === null) { return; } let newParent = parent; if (node.attributes[0] !== undefined) { const value = removeDuplicatedSpaces(node.attributes[0].value).replace(new RegExp('!', 'g'), '\\!'); attributes.push(`${parent}.${value.split(" ").sort().join(".")}`); newParent = `${parent}.${value.split(" ").sort().join(".")} `; } parseDom(node.firstElementChild, attributes, newParent); parseDom(node.nextElementSibling, attributes, parent); } function removeDuplicatedSpaces(text) { return text.replace(new RegExp(/ +/g, 'g'), ' ').trim(); } //# sourceMappingURL=html-comparer.js.map