UNPKG

@lewiswright/vitest-plugin-vis

Version:
98 lines (97 loc) 3.18 kB
/** * Most of the code in this file is copied from Vitest. * * @see https://github.com/vitest-dev/vitest/blob/main/packages/browser/src/client/utils.ts */ export function convertElementToCssSelector(element) { if (!element || !(element instanceof Element)) { throw new Error(`Expected DOM element to be an instance of Element, received ${typeof element}`); } return getUniqueCssSelector(element); } function escapeIdForCSSSelector(id) { return id .split('') .map((char) => { const code = char.charCodeAt(0); if (char === ' ' || char === '#' || char === '.' || char === ':' || char === '[' || char === ']' || char === '>' || char === '+' || char === '~' || char === '\\') { // Escape common special characters with backslashes return `\\${char}`; } if (code >= 0x10000) { // Unicode escape for characters outside the BMP return `\\${code.toString(16).toUpperCase().padStart(6, '0')} `; } if (code < 0x20 || code === 0x7f) { // Non-printable ASCII characters (0x00-0x1F and 0x7F) are escaped return `\\${code.toString(16).toUpperCase().padStart(2, '0')} `; } if (code >= 0x80) { // Non-ASCII characters (0x80 and above) are escaped return `\\${code.toString(16).toUpperCase().padStart(2, '0')} `; } // Allowable characters are used directly return char; }) .join(''); } function getUniqueCssSelector(el) { const path = []; let parent; let hasShadowRoot = false; // eslint-disable-next-line no-cond-assign while ((parent = getParent(el))) { if (parent.shadowRoot) { hasShadowRoot = true; } const tag = el.tagName; if (el.id) { path.push(`#${escapeIdForCSSSelector(el.id)}`); } else if (!el.nextElementSibling && !el.previousElementSibling) { path.push(tag.toLowerCase()); } else { let index = 0; let sameTagSiblings = 0; let elementIndex = 0; for (const sibling of parent.children) { index++; if (sibling.tagName === tag) { sameTagSiblings++; } if (sibling === el) { elementIndex = index; } } if (sameTagSiblings > 1) { path.push(`${tag.toLowerCase()}:nth-child(${elementIndex})`); } else { path.push(tag.toLowerCase()); } } el = parent; } return `${getBrowserState().provider === 'webdriverio' && hasShadowRoot ? '>>>' : ''}${path.reverse().join(' > ')}`; } function getParent(el) { const parent = el.parentNode; if (parent instanceof ShadowRoot) { return parent.host; } return parent; } function getBrowserState() { // @ts-expect-error not typed global return window.__vitest_browser_runner__; }