renderSuite = {
const renderHeader = (task, guid, result = {}, results) => {
const {name, promise, tasks, isNested} = task
const {duration} = result
const totalTests = tasks.reduce(flattenTasks, [])
const passingTests = results?.filter(x => x.pass)
const success = results?.every(x => x.pass)
const aggregatedColor = success === undefined ? 'gray' : success ? 'green' : 'red'
return htl.html.fragment`<span class="describe-header-${guid}" style=${{gridArea: '1 / 2 / 2 / 3', paddingTop: '0.1em'}}>
${renderLabel('describe', name)}
${renderPassingStatistics({passingTests, totalTests})}
${duration && renderDuration(duration)}
</span>`
}
const renderSuiteInternal = (task, guid, {noFragment} = {}) => {
const {tasks, isNested} = task
return (noFragment ? htl.html : htl.html.fragment)`
<div style=${{display: 'grid', gridTemplateColumns: 'auto 1fr auto', gap: '0.25em', alignItems: 'center'}}>
${isNested ? undefined : htl.html.fragment`<style>
.icon-spinning-${hash} {
animation: spinning-${hash} 1.5s infinite linear;
}
@keyframes spinning-${hash} {
0% {transform: rotate(0deg)}
100% {transform: rotate(360deg)}
}
</style>`}
<span style=${{gridArea: '1 / 1 / 2 / 2', padding: '0.3em', display: 'flex', alignItems: 'center', color: isNested ? '#00a1df' : '#006edf'}}>
${true ? undefined : isNested ? '🔹' : '🔷'}${systemIcon(20)}
</span>
${renderHeader(task, guid)}
<div style=${{
alignSelf: 'stretch',
gridArea: '1 / 1 / 2 / span 3',
border: '1px solid #ddd',
borderRadius: '0.15em',
padding: '0.2em',
paddingBottom: '0.05em'
}}></div>
<div style=${{gridColumn: '2 / span 2', display: 'flex', flexDirection: 'column', gap: '0.25em'}}>
${tasks.map(task => renderTestOrSuite(task))}
</div>
</div>
`
}
const renderSuiteTask = (task, {noFragment} = {}) => {
const guid = crypto.randomUUID()
const parent = document.createElement('div')
parent.appendChild(renderSuiteInternal(task, guid, {noFragment}))
const resultsPromise = Promise.all(task.tasks.reduce(flattenTasks, []).map(task => task.promise))
Promise.all([task.promise, resultsPromise]).then(async ([result, results]) => {
const currentHeader = parent.querySelector(`.describe-header-${guid}`)
currentHeader.replaceWith(renderHeader(task, guid, result, results))
})
return parent
}
const renderTestOrSuite = task => task.tasks ? renderSuiteTask(task) : renderTest(task)
return renderSuiteTask
}