import assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { htmlToJsx, normalizeVariantOutput } from './live-e2e/agent.mjs';
describe('live-e2e agent output translation', () => {
it('converts HTML class and inline style attributes to JSX syntax', () => {
const jsx = htmlToJsx(
'
Title
',
);
assert.equal(
jsx,
'Title
',
);
});
it('camel-cases vendor-prefixed style properties', () => {
const jsx = htmlToJsx(
'Title
',
);
assert.equal(
jsx,
'Title
',
);
});
it('keeps semicolons inside quoted and parenthesized style values', () => {
const jsx = htmlToJsx(
`Title
`,
);
assert.equal(
jsx,
`Title
`,
);
});
it('does not rewrite class inside data-class attributes', () => {
const jsx = htmlToJsx('Title
');
assert.equal(jsx, 'Title
');
});
it('hoists model inline styles into variant-scoped CSS', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'Title
',
},
{
innerHtml: `Title
`,
},
],
},
{ styleMode: 'scoped' },
);
assert.equal(
output.variants[0].innerHtml,
'Title
',
);
assert.equal(
output.variants[1].innerHtml,
'Title
',
);
assert.match(output.scopedCss, /@scope \(\[data-impeccable-variant="1"\]\)/);
assert.match(output.scopedCss, /:scope \[data-impeccable-hoist-id="1"\]\s*\{/);
assert.match(output.scopedCss, /color: red;/);
assert.match(output.scopedCss, /font-weight: 700;/);
assert.match(output.scopedCss, /content: "a;b";/);
assert.match(output.scopedCss, /background-image: url\("foo;bar"\);/);
});
it('hoists styles split across multiple lines', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'Title
',
},
],
},
{ styleMode: 'scoped' },
);
assert.equal(
output.variants[0].innerHtml,
'Title
',
);
assert.match(output.scopedCss, /color: red;/);
assert.match(output.scopedCss, /font-size: 2rem;/);
});
it('binds hoisted rules to the element the style was on, not the variant root', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'Title
',
},
],
},
{ styleMode: 'scoped' },
);
assert.equal(
output.variants[0].innerHtml,
'Title
',
);
assert.match(output.scopedCss, /:scope \[data-impeccable-hoist-id="1"\]\s*\{/);
assert.match(output.scopedCss, /color: red;/);
assert.match(output.scopedCss, /transform: scale\(1\.1\);/);
});
it('emits a separate rule per styled element inside one variant', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'Title
',
},
],
},
{ styleMode: 'scoped' },
);
assert.match(output.scopedCss, /:scope \[data-impeccable-hoist-id="1"\]\s*\{[^}]*color: red;/);
assert.match(output.scopedCss, /:scope \[data-impeccable-hoist-id="2"\]\s*\{[^}]*font-weight: 700;/);
});
it('targets only the styled element when same-tag siblings are present', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'plainstyled
',
},
],
},
{ styleMode: 'scoped' },
);
const hoistMatches = output.variants[0].innerHtml.match(/data-impeccable-hoist-id=/g) || [];
assert.equal(hoistMatches.length, 1, 'only the styled span should carry the hoist attribute');
assert.match(
output.variants[0].innerHtml,
/styled<\/span>/,
);
assert.match(output.variants[0].innerHtml, /plain<\/span>/);
assert.match(output.scopedCss, /:scope \[data-impeccable-hoist-id="1"\]\s*\{[^}]*color: red;/);
});
it('handles > inside a quoted attribute value without losing the style', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{
innerHtml: 'Title
',
},
],
},
{ styleMode: 'scoped' },
);
assert.match(output.variants[0].innerHtml, /aria-label="x > y"/);
assert.match(output.variants[0].innerHtml, /data-impeccable-hoist-id="1"/);
assert.doesNotMatch(output.variants[0].innerHtml, /style=/);
assert.match(output.scopedCss, /color: red;/);
});
it('emits the astro-global-prefixed selector shape when styleMode requests it', () => {
const output = normalizeVariantOutput(
{
scopedCss: '',
variants: [
{ innerHtml: 'Title
' },
],
},
{ styleMode: 'astro-global-prefixed' },
);
assert.match(
output.scopedCss,
/\[data-impeccable-variant="1"\] \[data-impeccable-hoist-id="1"\] \{/,
);
assert.doesNotMatch(output.scopedCss, /@scope/);
});
it('fills missing base variant rules when a model emits only param-conditioned CSS', () => {
const output = normalizeVariantOutput(
{
scopedCss: [
'@scope ([data-impeccable-variant="1"]) { :scope > h1 { color: blue; } }',
'@scope ([data-impeccable-variant="2"][data-p-uppercase]) { :scope > h1 { text-transform: uppercase; } }',
].join('\n'),
variants: [
{ innerHtml: 'One
' },
{ innerHtml: 'Two
' },
],
},
{ styleMode: 'scoped' },
);
assert.match(output.scopedCss, /@scope \(\[data-impeccable-variant="2"\]\)/);
assert.match(output.scopedCss, /--impeccable-variant-ready: 1;/);
assert.match(output.scopedCss, /@scope \(\[data-impeccable-variant="2"\]\[data-p-uppercase\]\)/);
});
it('returns the original output untouched when no inline styles are present', () => {
const original = {
scopedCss: '@scope ([data-impeccable-variant="1"]) { :scope > h1 { color: blue; } }',
variants: [{ innerHtml: 'Title
' }],
};
const result = normalizeVariantOutput(original, { styleMode: 'scoped' });
assert.equal(result, original);
});
});