cypress-ct-stencil
Version:
Framework Definition for StencilJS with Cypress Component Testing
87 lines (86 loc) • 2.95 kB
JavaScript
import { getContainerEl, setupHooks } from '@cypress/mount-utils';
export function mount(template, options = { waitUntilVisible: Cypress.env('CtStencilWaitUntilVisible'), log: Cypress.env('CtStencilLog') }) {
const container = getContainerEl();
if (Array.isArray(template)) {
template.forEach((v) => {
const element = createDOMNode(v, options.log);
element && container.appendChild(element);
});
}
else if (typeof template === 'string') {
container.innerHTML = template;
}
else {
const element = createDOMNode(template, options.log);
element && container.appendChild(element);
}
if (options.waitUntilVisible)
Array.from(container.children).forEach((v) => waitUntilVisible(v));
}
function waitUntilVisible(element) {
if (!element)
return;
if ('children' in element)
Array.from(element.children).forEach((v) => waitUntilVisible(v));
cy.get(element.nodeName.toLowerCase()).should('be.visible');
}
/**
* Function that recusively creates DOM nodes.
* @param vnode Stencil's VNode
*/
function createDOMNode(vnode, log) {
var _a;
const { $attrs$: attrs, $tag$: tag } = vnode;
if (!tag)
return;
const el = document.createElement(tag);
for (const key in attrs) {
if (key === 'style' && typeof attrs[key] === 'object') {
const styleObj = attrs[key];
// @ts-ignore
Object.entries(styleObj).forEach((styleProp) => (el.style[styleProp[0]] = styleProp[1]));
}
else if (key.startsWith('data')) {
el.setAttribute(key, attrs[key]);
}
else if (key.startsWith('attr-')) {
el.setAttribute((_a = key.split('attr-').pop()) !== null && _a !== void 0 ? _a : '', attrs[key]);
}
else if (key === 'class') {
el.className = attrs[key];
}
else if (typeof attrs[key] === 'function' && key !== 'ref') {
el.addEventListener(camelize(key.substring(2)), attrs[key]);
}
else if (key === 'ref') {
attrs[key](el);
}
else {
// @ts-ignore
el[key] = attrs[key];
}
}
const children = vnode.$children$ || [];
for (const child of children) {
const text = child.$text$;
const childNode = createDOMNode(child, log);
if (childNode)
el.appendChild(childNode);
if (text)
el.innerText = text;
}
if (log)
Cypress.log({ name: 'Mount', message: 'Mounting node ' + el.tagName.toLowerCase() });
return el;
}
function camelize(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, function (match, index) {
if (+match === 0)
return '';
return index === 0 ? match.toLowerCase() : match.toUpperCase();
});
}
function cleanup() {
getContainerEl().textContent = '';
}
setupHooks(cleanup);