Skip to content

Commit 9e4d8af

Browse files
test(wtr): remove console spy util (#5512)
* test(wtr): update tests to use relative path to utils instead of weird fake module * test(wtr): revert removing TestUtils * test(wtr): remove useless describe There's no setup/teardown needed, it's a single test, and WTR provides per-file encapsulation * test(wtr): replace IIFE script with module import * test(wtr): clean up SSR execution script working toward just importing and executing things, but not quite there yet * test(wtr): always use DISABLE_SYNTHETIC two env vars for the same goal is unnecessary * test(wtr): enable all hydration tests I think the last one was a concurrency related timeout, which was previously addressed. * test(wtr): remove side effect from signals helper helper files shouldn't have side effects; all setup should be in the setup file * test(wtr): import directly from file, not from barrel exporter * test(wtr): change bulk export statement to individual exports * test(wtr): remove unnecessary aria re-export * test(wtr): fix a few more ARIA util imports * chore: move comment for nicer aesthetic * test(wtr): remove unused option * test(wtr): fix another ARIA util import * test(wtr): import directly from hooks file rather than utils * test(wtr): import directly from signals file rather than utils * test(wtr): import directly from console helper rather than utils * test(wtr): import directly from constants helper rather than utils * test(wtr): only import what is needed from LWC * test(wtr): split lwc:dynamic load helpers into separate file * test(wtr): avoid relying on global LWC * test(wtr): remove unnecessary wrapping of hydration test config * test(wtr): remove test-utils logic from resolveImport no longer necessary * test(wtr): move plugin from shared config to only config that uses it * test(wtr): remove useless guid all tests are run in isolation * test(wtr): remove unnecessary test-utils global * test(wtr): clean up component definition * test(wtr): change component in test from IIFE to import * test(wtr): shift logic out of wrapper into static test runner file we want to keep the generated wrappers as thin as possible and use regular js files as much as possible * test(wtr): make test setup/teardown more idiomatic * test(wtr): clean up module compilation * chore(wtr): make dependency on @vitest/spy explicit * test(wtr): remove console suppression It was originally implemented to suppress distracting warnings in Karma tests, but WTR's log output is different / managed differently. * test(wtr): clean up names and comments * test(wtr): move and rename file * test(wtr): remove usage of global TestUtils from hydration tests * test(wtr): remove LWC import from utils It breaks hydration tests if there's an import from LWC. * test(wtr): remove unused external deps * test(wtr): use imports instead of jasmine globals * chore(eslint): remove unused rule config * fix: attribute cte syntax in integration tests * test(wtr): fix case in import mismatched case passes locally, but causes issues in CI * test(wtr): re-enable tests that used to fail in CI they should all work now * test(wtr): enable browser logs * test(wtr): name plugins helpful when debugging * test(wtr): rename variables and document functions for clarity * test(wtr): convert promise chains to async/await * test(wtr): load code from known url, rather than sniffing script tag * test(wtr): convert LWC from iife to fake cjs * test(wtr): remove unnecessary wrapping * test(wtr): data can be data, not a function * test(wtr): replace `evaluate` with functions that require less wrapping * test(wtr): only fetch scripts once * test(wtr): john was here * test(wtr): add line breaks and vars for clarity * test(wtr): rename variable it's just one code blob now, not multiple scripts * test(wtr): fix param pass through * test(wtr): more cleanup * test(wtr): remove outdated comment * test(wtr): avoid shadowing global var ensures we never accidentally use the wrong one * test(wtr): enable custom element registry tests * test(wtr): hoist function definition * chore: use vitest spy instead of custom hack * test(wtr): use vitest spy instead of custom * test(wtr): convert test to async/await * test(wtr): use vitest spy instead of custom * test(wtr): move util into only file that uses it --------- Co-authored-by: John Hefferman <jhefferman@salesforce.com>
1 parent a853060 commit 9e4d8af

File tree

12 files changed

+221
-181
lines changed

12 files changed

+221
-181
lines changed

packages/@lwc/integration-not-karma/configs/plugins/serve-integration.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,8 @@ const createRollupPlugin = (input, options) => {
3232
enableStaticContentOptimization: !DISABLE_STATIC_CONTENT_OPTIMIZATION,
3333
disableSyntheticShadowSupport: DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER,
3434
apiVersion: API_VERSION,
35-
modules: [
36-
{
37-
// Assume `ctx.path` is a component file, e.g. modules/x/foo/foo.js
38-
dir: path.resolve(input, '../../..'),
39-
},
40-
],
35+
// Assume `ctx.path` is a component file, e.g. modules/x/foo/foo.js
36+
modules: [{ dir: path.resolve(input, '../../..') }],
4137
...options,
4238
});
4339
};
@@ -85,6 +81,7 @@ const transform = async (ctx) => {
8581
plugins: [customLwcRollupPlugin],
8682

8783
external: [
84+
'@vitest/spy',
8885
'lwc',
8986
'wire-service',
9087
// Some helper files export functions that mutate a global state. The setup file calls

packages/@lwc/integration-not-karma/configs/plugins/test-hydration.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { spyOn } from '@vitest/spy';
12
import * as LWC from 'lwc';
2-
import { spyConsole } from '../../helpers/console';
33
import { setHooks } from '../../helpers/hooks';
44

55
setHooks({ sanitizeHtmlContent: (content) => content });
@@ -8,6 +8,28 @@ function parseStringToDom(html) {
88
return Document.parseHTMLUnsafe(html).body.firstChild;
99
}
1010

11+
/**
12+
* A much simplified version of the spies originally used for Karma.
13+
* Should probably be eventually replaced with individual spies.
14+
*/
15+
export function spyConsole() {
16+
const log = spyOn(console, 'log');
17+
const warn = spyOn(console, 'warn');
18+
const error = spyOn(console, 'error');
19+
return {
20+
calls: {
21+
log: log.mock.calls,
22+
warn: warn.mock.calls,
23+
error: error.mock.calls,
24+
},
25+
reset() {
26+
log.mockRestore();
27+
warn.mockRestore();
28+
error.mockRestore();
29+
},
30+
};
31+
}
32+
1133
function appendTestTarget(ssrText) {
1234
const div = document.createElement('div');
1335
const testTarget = parseStringToDom(ssrText);

packages/@lwc/integration-not-karma/helpers/console.js

Lines changed: 0 additions & 23 deletions
This file was deleted.

packages/@lwc/integration-not-karma/test/api/CustomElementConstructor-getter/index.spec.js

Lines changed: 23 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import AttrChanged from 'x/attrChanged';
99
import ReflectCamel from 'x/reflectCamel';
1010
import WithChildElmsHasSlot from 'x/withChildElmsHasSlot';
1111
import WithChildElmsHasSlotLight from 'x/withChildElmsHasSlotLight';
12-
import { spyConsole } from '../../../helpers/console.js';
12+
import { spyOn } from '@vitest/spy';
1313
import { USE_COMMENTS_FOR_FRAGMENT_BOOKENDS } from '../../../helpers/constants.js';
1414

1515
const vFragBookend = USE_COMMENTS_FOR_FRAGMENT_BOOKENDS ? '<!---->' : '';
@@ -69,19 +69,9 @@ it('should create custom element if it exists before customElements.define', ()
6969
describe('non-empty custom element', () => {
7070
let consoleSpy;
7171
beforeEach(() => {
72-
consoleSpy = spyConsole();
72+
consoleSpy = spyOn(console, 'warn').mockImplementation(() => {});
7373
});
74-
afterEach(() => {
75-
consoleSpy.reset();
76-
});
77-
78-
function expectWarnings(expectedWarnings) {
79-
const observedWarnings = consoleSpy.calls.warn
80-
.flat()
81-
.map((err) => (err instanceof Error ? err.message : err));
82-
83-
expect(observedWarnings).toEqual(expectedWarnings);
84-
}
74+
afterEach(() => consoleSpy.mockRestore());
8575

8676
it('should log error if non-native-shadow custom element has children', () => {
8777
const elm = document.createElement('test-custom-element-preexisting2');
@@ -93,11 +83,11 @@ describe('non-empty custom element', () => {
9383
class extends WithChildElms.CustomElementConstructor {}
9484
);
9585
if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
96-
expectWarnings([
97-
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
98-
]);
86+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
87+
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
88+
);
9989
} else {
100-
expectWarnings([]);
90+
expect(consoleSpy).not.toHaveBeenCalled();
10191
}
10292

10393
expect(elm.shadowRoot.childNodes.length).toBe(1);
@@ -123,11 +113,11 @@ describe('non-empty custom element', () => {
123113
);
124114

125115
if (process.env.NODE_ENV !== 'production') {
126-
expectWarnings([
127-
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
128-
]);
116+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
117+
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
118+
);
129119
} else {
130-
expectWarnings([]);
120+
expect(consoleSpy).not.toHaveBeenCalled();
131121
}
132122

133123
expect(elm.innerHTML).toBe(`${vFragBookend}${vFragBookend}`);
@@ -143,11 +133,11 @@ describe('non-empty custom element', () => {
143133
class extends WithChildElmsHasSlot.CustomElementConstructor {}
144134
);
145135
if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
146-
expectWarnings([
147-
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
148-
]);
136+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
137+
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
138+
);
149139
} else {
150-
expectWarnings([]);
140+
expect(consoleSpy).not.toHaveBeenCalled();
151141
}
152142

153143
expect(elm.shadowRoot.childNodes.length).toBe(1);
@@ -174,11 +164,11 @@ describe('non-empty custom element', () => {
174164
);
175165

176166
if (process.env.NODE_ENV === 'production') {
177-
expectWarnings([]);
167+
expect(consoleSpy).not.toHaveBeenCalled();
178168
} else {
179-
expectWarnings([
180-
'Found an existing shadow root for the custom element "Child". Call `hydrateComponent` instead.',
181-
]);
169+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
170+
'Found an existing shadow root for the custom element "Child". Call `hydrateComponent` instead.'
171+
);
182172
}
183173
expect(elm.shadowRoot.innerHTML).toBe('<div></div>');
184174
});
@@ -194,11 +184,11 @@ describe('non-empty custom element', () => {
194184
document.body.appendChild(elm);
195185

196186
if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
197-
expectWarnings([
198-
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
199-
]);
187+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
188+
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
189+
);
200190
} else {
201-
expectWarnings([]);
191+
expect(consoleSpy).not.toHaveBeenCalled();
202192
}
203193

204194
expect(elm.childNodes.length).toBe(1);

packages/@lwc/integration-not-karma/test/component/LightningElement.addEventListener/index.spec.js

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { createElement } from 'lwc';
33
import EventHandler from 'x/eventHandler';
44
import EventHandlerOptions from 'x/eventHandlerOptions';
55
import AdditionWhileDispatch from 'x/additionWhileDispatch';
6-
import { spyConsole } from '../../../helpers/console.js';
6+
import { spyOn } from '@vitest/spy';
77

88
it('should be able to attach an event listener on the host element', () => {
99
let thisValue;
@@ -39,12 +39,11 @@ it('should warn when passing a 3rd parameter to the event handler', () => {
3939

4040
describe('event handler is not a function', () => {
4141
let consoleSpy;
42-
beforeEach(() => {
43-
consoleSpy = spyConsole();
44-
});
45-
afterEach(() => {
46-
consoleSpy.reset();
42+
beforeAll(() => {
43+
consoleSpy = spyOn(console, 'error');
4744
});
45+
afterEach(() => consoleSpy.mockReset());
46+
afterAll(() => consoleSpy.mockRestore());
4847

4948
it('should log an error if event handler is not a function', () => {
5049
const elm = createElement('x-event-handler', { is: EventHandler });
@@ -54,11 +53,10 @@ describe('event handler is not a function', () => {
5453
}).toThrowCallbackReactionError(/Expected an EventListener but received undefined/);
5554

5655
if (process.env.NODE_ENV === 'production') {
57-
expect(consoleSpy.calls.error.length).toEqual(0);
56+
expect(consoleSpy).not.toHaveBeenCalled();
5857
} else {
59-
expect(consoleSpy.calls.error.length).toEqual(1);
60-
expect(consoleSpy.calls.error[0][0].message).toContain(
61-
'Invalid second argument for this.addEventListener()'
58+
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
59+
expect.stringContaining('Invalid second argument for this.addEventListener()')
6260
);
6361
}
6462
});

packages/@lwc/integration-not-karma/test/component/dynamic-imports/index.spec.js

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import LwcDynamicSlotted from 'x/lwcDynamicSlotted';
1010
import ContainerFoo from 'x/containerFoo';
1111
import ContainerBar from 'x/containerBar';
1212

13-
import { spyConsole } from '../../../helpers/console.js';
13+
import { spyOn } from '@vitest/spy';
1414
import { registerForLoad, clearRegister } from '../../../helpers/dynamic-loader.js';
1515

1616
beforeEach(() => {
@@ -116,12 +116,10 @@ it('should not cache DOM elements using lwc:dynamic', async () => {
116116

117117
describe('slotted content using lwc:dynamic', () => {
118118
let consoleSpy;
119-
beforeEach(() => {
120-
consoleSpy = spyConsole();
121-
});
122-
afterEach(() => {
123-
consoleSpy.reset();
119+
beforeAll(() => {
120+
consoleSpy = spyOn(console, 'error');
124121
});
122+
afterAll(() => consoleSpy.mockRestore());
125123

126124
it('reallocate slotted content after changing constructor', async () => {
127125
const elm = createElement('x-dynamic-slotted', { is: LwcDynamicSlotted });
@@ -136,7 +134,7 @@ describe('slotted content using lwc:dynamic', () => {
136134
// `slot-bar` is not rendered in synthetic shadow
137135
expect(elm.shadowRoot.querySelector('[data-id="slot-bar"]').assignedSlot).toBe(null);
138136
}
139-
expect(consoleSpy.calls.error.length).toEqual(0);
137+
expect(consoleSpy).not.toHaveBeenCalled();
140138

141139
// Swap construstor and check if nodes have been reallocated.
142140
elm.ctor = ContainerBar;
@@ -150,7 +148,7 @@ describe('slotted content using lwc:dynamic', () => {
150148
// `slot-foo` is not rendered in synthetic shadow
151149
expect(elm.shadowRoot.querySelector('[data-id="slot-foo"]').assignedSlot).toBe(null);
152150
}
153-
expect(consoleSpy.calls.error.length).toEqual(0);
151+
expect(consoleSpy).not.toHaveBeenCalled();
154152
});
155153
});
156154

@@ -242,12 +240,10 @@ it('should not cache DOM elements', async () => {
242240

243241
describe('slotted content', () => {
244242
let consoleSpy;
245-
beforeEach(() => {
246-
consoleSpy = spyConsole();
247-
});
248-
afterEach(() => {
249-
consoleSpy.reset();
243+
beforeAll(() => {
244+
consoleSpy = spyOn(console, 'error');
250245
});
246+
afterAll(() => consoleSpy.mockRestore());
251247

252248
it('reallocate slotted content after changing constructor', async () => {
253249
const elm = createElement('x-dynamic-slotted', { is: DynamicSlotted });
@@ -262,7 +258,7 @@ describe('slotted content', () => {
262258
// `slot-bar` is not rendered in synthetic shadow
263259
expect(elm.shadowRoot.querySelector('[data-id="slot-bar"]').assignedSlot).toBe(null);
264260
}
265-
expect(consoleSpy.calls.error.length).toEqual(0);
261+
expect(consoleSpy).not.toHaveBeenCalled();
266262

267263
// Swap constructor and check if nodes have been reallocated.
268264
elm.ctor = ContainerBar;
@@ -276,6 +272,6 @@ describe('slotted content', () => {
276272
// `slot-foo` is not rendered in synthetic shadow
277273
expect(elm.shadowRoot.querySelector('[data-id="slot-foo"]').assignedSlot).toBe(null);
278274
}
279-
expect(consoleSpy.calls.error.length).toEqual(0);
275+
expect(consoleSpy).not.toHaveBeenCalled();
280276
});
281277
});

0 commit comments

Comments
 (0)