Skip to content

Commit 47645d8

Browse files
authored
test(wtr): clean global state and mock LWC (#5467)
* test(wtr): clear <head> and clear global stylesheets when needed * test(wtr): mock LWC to validate sanitizeAttribute We can't mock individual methods of ESM modules in the browser, so we use WTR's import map plugin to redirect all "lwc" imports to a mock file. The mock file is mostly a re-export. * chore(deps): bump @types/jasmine
1 parent 6ea26d2 commit 47645d8

File tree

13 files changed

+64
-26
lines changed

13 files changed

+64
-26
lines changed

packages/@lwc/integration-karma/test/api/sanitizeAttribute/index.spec.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,10 @@ const scenarios = [
3636

3737
scenarios.forEach(({ type, attrName, tagName, Ctor }) => {
3838
describe(`${type} ${attrName}`, () => {
39-
const originalSanitizeAttribute = LWC.sanitizeAttribute;
40-
39+
// Spy is created in a mock file and injected with the import map plugin
40+
const sanitizeAttributeSpy = LWC.sanitizeAttribute;
4141
afterEach(() => {
42-
// Reset original sanitizer after each test.
43-
LWC.sanitizeAttribute = originalSanitizeAttribute;
42+
sanitizeAttributeSpy.mockReset();
4443
});
4544

4645
it('uses the original passthrough sanitizer when not overridden', () => {
@@ -52,8 +51,6 @@ scenarios.forEach(({ type, attrName, tagName, Ctor }) => {
5251
});
5352

5453
it('receives the right parameters', () => {
55-
spyOn(LWC, 'sanitizeAttribute');
56-
5754
const elm = createElement(tagName, { is: Ctor });
5855
document.body.appendChild(elm);
5956

@@ -66,7 +63,7 @@ scenarios.forEach(({ type, attrName, tagName, Ctor }) => {
6663
});
6764

6865
it('replace the original attribute value with a string', () => {
69-
spyOn(LWC, 'sanitizeAttribute').and.returnValue('/bar');
66+
sanitizeAttributeSpy.mockReturnValue('/bar');
7067

7168
const elm = createElement(tagName, { is: Ctor });
7269
document.body.appendChild(elm);
@@ -76,7 +73,7 @@ scenarios.forEach(({ type, attrName, tagName, Ctor }) => {
7673
});
7774

7875
it('replace the original attribute value with undefined', () => {
79-
spyOn(LWC, 'sanitizeAttribute').and.returnValue(undefined);
76+
sanitizeAttributeSpy.mockReturnValue(undefined);
8077

8178
const elm = createElement(tagName, { is: Ctor });
8279
document.body.appendChild(elm);
@@ -105,8 +102,6 @@ booleanTrueScenarios.forEach(({ attrName, tagName, Ctor }) => {
105102
describe(attrName, () => {
106103
// For boolean literals (e.g. `<use xlink:href>`), there is no reason to sanitize since it's empty
107104
it('does not sanitize when used as a boolean-true attribute', () => {
108-
spyOn(LWC, 'sanitizeAttribute');
109-
110105
const elm = createElement(tagName, { is: Ctor });
111106
document.body.appendChild(elm);
112107

packages/@lwc/integration-karma/test/mixed-shadow-mode/synthetic-behavior/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import GrandparentResetParentAnyChildReset from 'x/grandparentResetParentAnyChil
1515
import GrandparentResetParentResetChildAny from 'x/grandparentResetParentResetChildAny';
1616
import GrandparentResetParentResetChildReset from 'x/grandparentResetParentResetChildReset';
1717

18+
afterEach(() => {
19+
window.__lwcResetGlobalStylesheets();
20+
});
21+
1822
describe.skipIf(process.env.NATIVE_SHADOW)('synthetic behavior', () => {
1923
const scenarios = [
2024
{

packages/@lwc/integration-karma/test/rendering/style-specificity-important/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { createElement } from 'lwc';
22
import Component from 'x/component';
33

4+
afterEach(() => {
5+
window.__lwcResetGlobalStylesheets();
6+
});
7+
48
describe('important styling and style override', () => {
59
it('should render !important styles correctly', async () => {
610
const elm = createElement('x-component', { is: Component });

packages/@lwc/integration-karma/test/shadow-dom/stylesheet/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import Parent from 'x/parent';
44
import Host from 'x/host';
55
import MultiTemplates from 'x/multiTemplates';
66

7+
afterEach(() => {
8+
window.__lwcResetGlobalStylesheets();
9+
});
10+
711
describe('shadow encapsulation', () => {
812
it('should not style children elements', () => {
913
const elm = createElement('x-parent', { is: Parent });

packages/@lwc/integration-karma/test/synthetic-shadow/dom-manual-sharing-nodes/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { createElement } from 'lwc';
33
import Unstyled from 'x/unstyled';
44
import Styled from 'x/styled';
55

6+
afterEach(() => {
7+
window.__lwcResetGlobalStylesheets();
8+
});
9+
610
describe('dom manual sharing nodes', () => {
711
it('has correct styles when sharing nodes from styled to unstyled component', () => {
812
const unstyled = createElement('x-unstyled', { is: Unstyled });

packages/@lwc/integration-karma/test/template/directive-lwc-dom-manual/index.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ function waitForStyleToBeApplied() {
88
return Promise.resolve();
99
}
1010

11+
afterEach(() => {
12+
window.__lwcResetGlobalStylesheets();
13+
});
14+
1115
describe('dom mutation without the lwc:dom="manual" directive', () => {
1216
function testErrorOnDomMutation(method, fn) {
1317
it(`should log a warning when calling ${method} on an element without the lwc:dom="manual" directive only in synthetic mode`, () => {

packages/@lwc/integration-karma/test/template/directive-lwc-inner-html/index.spec.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,18 @@ let originalSanitizeHtmlContent;
77

88
beforeAll(() => {
99
originalSanitizeHtmlContent = getHooks().sanitizeHtmlContent;
10-
setHooks({
11-
sanitizeHtmlContent: (content) => content,
12-
});
10+
setHooks({ sanitizeHtmlContent: (content) => content });
1311
});
1412

1513
afterAll(() => {
16-
setHooks({
17-
sanitizeHtmlContent: originalSanitizeHtmlContent,
18-
});
14+
setHooks({ sanitizeHtmlContent: originalSanitizeHtmlContent });
15+
});
16+
17+
afterEach(() => {
18+
window.__lwcResetGlobalStylesheets();
1919
});
2020

21-
it('renders the content as HTML', () => {
21+
it('renders the content as HTML', async () => {
2222
const elm = createElement('x-inner-html', { is: XInnerHtml });
2323
elm.content = 'Hello <b>World</b>';
2424
document.body.appendChild(elm);

packages/@lwc/integration-not-karma/configs/base.mjs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { join } from 'node:path';
22
import { LWC_VERSION } from '@lwc/shared';
3+
import { importMapsPlugin } from '@web/dev-server-import-maps';
34
import * as options from '../helpers/options.mjs';
45

56
const pluck = (obj, keys) => Object.fromEntries(keys.map((k) => [k, obj[k]]));
@@ -31,6 +32,7 @@ export default {
3132
nodeResolve: true,
3233
rootDir: join(import.meta.dirname, '..'),
3334
plugins: [
35+
importMapsPlugin({ inject: { importMap: { imports: { lwc: './mocks/lwc.mjs' } } } }),
3436
{
3537
resolveImport({ source }) {
3638
if (source === 'test-utils') {

packages/@lwc/integration-not-karma/configs/integration.mjs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,12 @@ export default {
88
// FIXME: These tests are just symlinks to integration-karma for now so the git diff smaller
99
'test/**/*.spec.js',
1010

11-
// Cannot reassign properties of module
12-
'!test/api/sanitizeAttribute/index.spec.js',
13-
1411
// Hacky nonsense highly tailored to Karma
1512
'!test/custom-elements-registry/index.spec.js',
1613

1714
// Logging mismatches
1815
'!test/component/LightningElement.addEventListener/index.spec.js',
1916

20-
// Needs clean <head>
21-
'!test/light-dom/multiple-templates/index.spec.js',
22-
'!test/light-dom/style-global/index.spec.js',
23-
'!test/misc/clean-dom/index.spec.js',
24-
'!test/swapping/styles/index.spec.js',
25-
2617
// Implement objectContaining / arrayWithExactContents
2718
'!test/profiler/mutation-logging/index.spec.js',
2819
],

packages/@lwc/integration-not-karma/helpers/setup.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ hijackGlobal('afterEach', (afterEach) => {
106106
// FIXME: Boost test speed by moving this to only files that need it
107107
// Ensure the DOM is in a clean state
108108
document.body.replaceChildren();
109+
document.head.replaceChildren();
109110
});
110111
});
111112

0 commit comments

Comments
 (0)