Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/testing/html-serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ function serializeElementWithShadow(
}

const elem = element as HTMLElement;
const tagName = elem.tagName.toLowerCase();
// Use localName to preserve case for SVG elements (e.g., foreignObject, feGaussianBlur)
// For HTML elements, localName is already lowercase
const tagName = (elem as any).localName || elem.tagName.toLowerCase();

// Build opening tag with attributes
let html = `<${tagName}`;
Expand Down
43 changes: 33 additions & 10 deletions src/testing/matchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,12 +324,15 @@ function toEqualHtml(
}

let receivedHtml: string;
let isStringComparison = false;

// Serialize the received value
if (typeof received === 'string') {
isStringComparison = true;
const fragment = parseHtmlFragment(received);
// For string inputs, use innerHTML to avoid template wrapper
receivedHtml = (fragment as any).innerHTML || fragment.textContent || '';
// Use serializeHtml to preserve all elements including the outer ones
// Don't prettify for comparison - we'll normalize instead
receivedHtml = serializeHtml(fragment, { serializeShadowRoot: true, pretty: false });
} else if ((received as any).nodeType === 11) {
// Document fragment
receivedHtml = serializeHtml(received as any, { serializeShadowRoot: true });
Expand All @@ -341,9 +344,17 @@ function toEqualHtml(
}

// Parse and serialize expected HTML for consistent formatting
// For expected HTML, just normalize whitespace without parsing through DOM
// to preserve custom elements like <mock:shadow-root>
let expectedHtml = normalizeHtml(expected.trim());
let expectedHtml: string;
if (isStringComparison) {
// When comparing strings, parse and serialize both the same way
const expectedFragment = parseHtmlFragment(expected.trim());
expectedHtml = serializeHtml(expectedFragment, { serializeShadowRoot: true, pretty: false });
} else {
// For element comparisons, just normalize to preserve <mock:shadow-root> tags
expectedHtml = expected.trim();
}

expectedHtml = normalizeHtml(expectedHtml);
receivedHtml = normalizeHtml(receivedHtml);

const pass = receivedHtml === expectedHtml;
Expand Down Expand Up @@ -372,12 +383,15 @@ function toEqualLightHtml(
}

let receivedHtml: string;
let isStringComparison = false;

// Serialize the received value (without shadow DOM)
if (typeof received === 'string') {
isStringComparison = true;
const fragment = parseHtmlFragment(received);
// For string inputs, use innerHTML to avoid template wrapper
receivedHtml = (fragment as any).innerHTML || fragment.textContent || '';
// Use serializeHtml to preserve all elements including the outer ones
// Don't prettify for comparison - we'll normalize instead
receivedHtml = serializeHtml(fragment, { serializeShadowRoot: false, pretty: false });
} else if ((received as any).nodeType === 11) {
// Document fragment
receivedHtml = serializeHtml(received as any, { serializeShadowRoot: false });
Expand All @@ -388,9 +402,18 @@ function toEqualLightHtml(
throw new TypeError(`expect.toEqualLightHtml() value should be an element, shadow root, or string`);
}

// For expected HTML, just normalize whitespace without parsing through DOM
// to preserve custom elements like <mock:shadow-root>
let expectedHtml = normalizeHtml(expected.trim());
// Parse and serialize expected HTML for consistent formatting
let expectedHtml: string;
if (isStringComparison) {
// When comparing strings, parse and serialize both the same way
const expectedFragment = parseHtmlFragment(expected.trim());
expectedHtml = serializeHtml(expectedFragment, { serializeShadowRoot: false, pretty: false });
} else {
// For element comparisons, just normalize to preserve <mock:shadow-root> tags
expectedHtml = expected.trim();
}

expectedHtml = normalizeHtml(expectedHtml);
receivedHtml = normalizeHtml(receivedHtml);

const pass = receivedHtml === expectedHtml;
Expand Down