Skip to content

Commit 0fefe67

Browse files
authored
test(wtr): split up utils (#5479)
* 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
1 parent a96e8d9 commit 0fefe67

File tree

59 files changed

+147
-173
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+147
-173
lines changed

eslint.config.mjs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,25 @@ export default tseslint.config(
355355
},
356356
},
357357
{
358-
files: ['packages/@lwc/integration-karma/**', 'packages/@lwc/integration-not-karma/**'],
358+
files: ['packages/@lwc/integration-not-karma/**'],
359+
360+
languageOptions: {
361+
globals: {
362+
lwcRuntimeFlags: true,
363+
process: true,
364+
TestUtils: true,
365+
...globals.browser,
366+
...globals.jasmine,
367+
},
368+
},
369+
370+
rules: {
371+
'no-var': 'off',
372+
'prefer-rest-params': 'off',
373+
},
374+
},
375+
{
376+
files: ['packages/@lwc/integration-karma/**'],
359377

360378
languageOptions: {
361379
globals: {

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import path from 'node:path';
22
import vm from 'node:vm';
33
import fs from 'node:fs/promises';
4+
import { fileURLToPath } from 'node:url';
45
import { rollup } from 'rollup';
56
import lwcRollupPlugin from '@lwc/rollup-plugin';
67
import { DISABLE_STATIC_CONTENT_OPTIMIZATION, ENGINE_SERVER } from '../../helpers/options.js';
@@ -39,7 +40,7 @@ async function getCompiledModule(dir, compileForSSR) {
3940
targetSSR: !!compileForSSR,
4041
modules: [{ dir: path.join(ROOT_DIR, dir) }],
4142
experimentalDynamicComponent: {
42-
loader: 'test-utils',
43+
loader: fileURLToPath(new URL('../../helpers/loader.js', import.meta.url)),
4344
strict: true,
4445
},
4546
enableDynamicComponents: true,
@@ -198,6 +199,7 @@ async function wrapHydrationTest(filePath) {
198199

199200
// FIXME: can we turn these IIFEs into ESM imports?
200201
return `
202+
import * as LWC from 'lwc';
201203
import { runTest } from '/helpers/test-hydrate.js';
202204
import config from '/${filePath}?original=1';
203205
${onlyFileExists ? 'it.only' : 'it'}('${filePath}', async () => {

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import {
1010
DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER,
1111
} from '../../helpers/options.js';
1212

13-
const UTILS = fileURLToPath(new URL('../../helpers/utils.js', import.meta.url));
14-
1513
/** Cache reused between each compilation to speed up the compilation time. */
1614
let cache;
1715

@@ -25,7 +23,7 @@ const createRollupPlugin = (input, options) => {
2523
// Sourcemaps don't work with Istanbul coverage
2624
sourcemap: !process.env.COVERAGE,
2725
experimentalDynamicComponent: {
28-
loader: UTILS,
26+
loader: fileURLToPath(new URL('../../helpers/dynamic-loader', import.meta.url)),
2927
strict: true,
3028
},
3129
enableDynamicComponents: true,
@@ -88,7 +86,16 @@ const transform = async (ctx) => {
8886

8987
// Rollup should not attempt to resolve the engine and the test utils, Karma takes care of injecting it
9088
// globally in the page before running the tests.
91-
external: ['lwc', 'wire-service', '@test/loader', UTILS],
89+
external: [
90+
'lwc',
91+
'wire-service',
92+
'@test/loader',
93+
// Some helper files export functions that mutate a global state. The setup file calls
94+
// some of those functions and does not get bundled. Including the helper files in the
95+
// bundle would create a separate global state, causing tests to fail. We don't need to
96+
// mark _all_ helpers as external, but we do anyway for ease of maintenance.
97+
/\/helpers\/\w+\.js$/,
98+
],
9299

93100
onwarn(warning, warn) {
94101
// Ignore warnings from our own Rollup plugin

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { API_VERSION } from './options.js';
22

3-
// These values are based on the API versions in @lwc/shared/api-version
4-
export const LOWERCASE_SCOPE_TOKENS = API_VERSION >= 59,
3+
export const // These values are based on the API versions in @lwc/shared/api-version
4+
LOWERCASE_SCOPE_TOKENS = API_VERSION >= 59,
55
USE_COMMENTS_FOR_FRAGMENT_BOOKENDS = API_VERSION >= 60,
66
USE_FRAGMENTS_FOR_LIGHT_DOM_SLOTS = API_VERSION >= 60,
77
DISABLE_OBJECT_REST_SPREAD_TRANSFORMATION = API_VERSION >= 60,
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Helpers for testing lwc:dynamic
2+
const register = new Map();
3+
/**
4+
* Called by compiled components to, well, load another component. The path to this file is
5+
* specified by the `experimentalDynamicComponent.loader` rollup plugin option.
6+
*/
7+
export const load = async (id) => await Promise.resolve(register.get(id));
8+
export const registerForLoad = (name, Ctor) => register.set(name, Ctor);
9+
export const clearRegister = () => register.clear();

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ export const API_VERSION = process.env.API_VERSION
4040

4141
export const NODE_ENV_FOR_TEST = process.env.NODE_ENV_FOR_TEST || 'development';
4242

43-
export const GREP = process.env.GREP;
44-
4543
export const NATIVE_SHADOW = DISABLE_SYNTHETIC || FORCE_NATIVE_SHADOW_MODE_FOR_TEST;
4644

4745
/** Unique directory name that encodes the flags that the tests were executed with. */

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
// This import ensures that the global `Mocha` object is present for mutation.
22
import { JestAsymmetricMatchers, JestChaiExpect, JestExtend } from '@vitest/expect';
33
import * as chai from 'chai';
4-
import * as LWC from 'lwc';
54
import { spyOn, fn } from '@vitest/spy';
65
import { registerCustomMatchers } from './matchers/index.js';
76
import * as TestUtils from './utils.js';
7+
import { initSignals } from './signals.js';
8+
9+
initSignals();
810

911
// FIXME: As a relic of the Karma tests, some test files rely on the global object,
1012
// rather than importing from `test-utils`.
@@ -47,8 +49,6 @@ function jasmineSpyAdapter(spy) {
4749

4850
// expose so we don't need to import `expect` in every test file
4951
globalThis.expect = chai.expect;
50-
// Expose globals for karma compat
51-
globalThis.LWC = LWC;
5252
globalThis.spyOn = (object, prop) => jasmineSpyAdapter(spyOn(object, prop));
5353
globalThis.jasmine = {
5454
any: expect.any,

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { setTrustedSignalSet } from 'lwc';
22

33
const signalValidator = new WeakSet();
4-
setTrustedSignalSet(signalValidator);
4+
5+
export function initSignals() {
6+
setTrustedSignalSet(signalValidator);
7+
}
58

69
export function addTrustedSignal(signal) {
710
signalValidator.add(signal);

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

Lines changed: 16 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
11
/*
22
* An as yet uncategorized mishmash of helpers, relics of Karma
33
*/
4-
import * as LWC from 'lwc';
5-
import {
6-
ariaAttributes,
7-
ariaProperties,
8-
ariaPropertiesMapping,
9-
nonPolyfilledAriaProperties,
10-
nonStandardAriaProperties,
11-
} from './aria.js';
12-
import { setHooks, getHooks } from './hooks.js';
13-
import { spyConsole } from './console.js';
14-
import {
15-
DISABLE_OBJECT_REST_SPREAD_TRANSFORMATION,
16-
ENABLE_ELEMENT_INTERNALS_AND_FACE,
17-
ENABLE_THIS_DOT_HOST_ELEMENT,
18-
ENABLE_THIS_DOT_STYLE,
19-
IS_SYNTHETIC_SHADOW_LOADED,
20-
LOWERCASE_SCOPE_TOKENS,
21-
TEMPLATE_CLASS_NAME_OBJECT_BINDING,
22-
USE_COMMENTS_FOR_FRAGMENT_BOOKENDS,
23-
USE_FRAGMENTS_FOR_LIGHT_DOM_SLOTS,
24-
USE_LIGHT_DOM_SLOT_FORWARDING,
25-
} from './constants.js';
26-
import { addTrustedSignal } from './signals.js';
4+
import { __unstable__ReportingControl } from 'lwc';
275

286
// Listen for errors thrown directly by the callback
297
function directErrorListener(callback) {
@@ -63,7 +41,7 @@ function windowErrorListener(callback) {
6341
// 2) We're using native lifecycle callbacks, so the error is thrown asynchronously and can
6442
// only be caught with window.addEventListener('error')
6543
// - Note native lifecycle callbacks are all thrown asynchronously.
66-
function customElementCallbackReactionErrorListener(callback) {
44+
export function customElementCallbackReactionErrorListener(callback) {
6745
return lwcRuntimeFlags.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE
6846
? directErrorListener(callback)
6947
: windowErrorListener(callback);
@@ -74,19 +52,19 @@ function customElementCallbackReactionErrorListener(callback) {
7452
* @param dispatcher
7553
* @param runtimeEvents List of runtime events to filter by. If no list is provided, all events will be dispatched.
7654
*/
77-
function attachReportingControlDispatcher(dispatcher, runtimeEvents) {
78-
LWC.__unstable__ReportingControl.attachDispatcher((eventName, payload) => {
55+
export function attachReportingControlDispatcher(dispatcher, runtimeEvents) {
56+
__unstable__ReportingControl.attachDispatcher((eventName, payload) => {
7957
if (!runtimeEvents || runtimeEvents.includes(eventName)) {
8058
dispatcher(eventName, payload);
8159
}
8260
});
8361
}
8462

85-
function detachReportingControlDispatcher() {
86-
LWC.__unstable__ReportingControl.detachDispatcher();
63+
export function detachReportingControlDispatcher() {
64+
__unstable__ReportingControl.detachDispatcher();
8765
}
8866

89-
function extractDataIds(root) {
67+
export function extractDataIds(root) {
9068
const nodes = {};
9169

9270
function processElement(elm) {
@@ -120,7 +98,7 @@ function extractDataIds(root) {
12098
return nodes;
12199
}
122100

123-
function extractShadowDataIds(shadowRoot) {
101+
export function extractShadowDataIds(shadowRoot) {
124102
const nodes = {};
125103

126104
// Add the shadow root here even if they don't have [data-id] attributes. This reference is
@@ -140,36 +118,24 @@ function extractShadowDataIds(shadowRoot) {
140118
return nodes;
141119
}
142120

143-
let register = {};
144-
function load(id) {
145-
return Promise.resolve(register[id]);
146-
}
147-
148-
function registerForLoad(name, Ctor) {
149-
register[name] = Ctor;
150-
}
151-
function clearRegister() {
152-
register = {};
153-
}
154-
155121
// #986 - childNodes on the host element returns a fake shadow comment node on IE11 for debugging purposes. This method
156122
// filters this node.
157-
function getHostChildNodes(host) {
123+
export function getHostChildNodes(host) {
158124
return Array.prototype.slice.call(host.childNodes).filter(function (n) {
159125
return !(n.nodeType === Node.COMMENT_NODE && n.tagName.startsWith('#shadow-root'));
160126
});
161127
}
162128

163-
function isSyntheticShadowRootInstance(sr) {
129+
export function isSyntheticShadowRootInstance(sr) {
164130
return Boolean(sr && sr.synthetic);
165131
}
166132

167-
function isNativeShadowRootInstance(sr) {
133+
export function isNativeShadowRootInstance(sr) {
168134
return Boolean(sr && !sr.synthetic);
169135
}
170136

171137
// Keep traversing up the prototype chain until a property descriptor is found
172-
function getPropertyDescriptor(object, prop) {
138+
export function getPropertyDescriptor(object, prop) {
173139
do {
174140
const descriptor = Object.getOwnPropertyDescriptor(object, prop);
175141
if (descriptor) {
@@ -216,13 +182,13 @@ function stringifyArg(arg) {
216182
}
217183
}
218184

219-
const expectConsoleCalls = createExpectConsoleCallsFunc(false);
220-
const expectConsoleCallsDev = createExpectConsoleCallsFunc(true);
185+
export const expectConsoleCalls = createExpectConsoleCallsFunc(false);
186+
export const expectConsoleCallsDev = createExpectConsoleCallsFunc(true);
221187

222188
// Utility to handle unhandled rejections or errors without allowing Jasmine to handle them first.
223189
// Captures both onunhandledrejection and onerror events, since you might want both depending on
224190
// native vs synthetic lifecycle timing differences.
225-
function catchUnhandledRejectionsAndErrors(onUnhandledRejectionOrError) {
191+
export function catchUnhandledRejectionsAndErrors(onUnhandledRejectionOrError) {
226192
let originalOnError;
227193

228194
const onError = (e) => {
@@ -257,7 +223,7 @@ function catchUnhandledRejectionsAndErrors(onUnhandledRejectionOrError) {
257223

258224
// Succeeds if the given DOM element is equivalent to the given HTML in terms of nodes and elements. This is
259225
// basically the same as `expect(element.outerHTML).toBe(html)` except that it works despite bugs in synthetic shadow.
260-
function expectEquivalentDOM(element, html) {
226+
export function expectEquivalentDOM(element, html) {
261227
const fragment = Document.parseHTMLUnsafe(html);
262228

263229
// When the fragment is parsed, the string "abc" is considered one text node. Whereas the engine
@@ -314,41 +280,3 @@ function expectEquivalentDOM(element, html) {
314280

315281
expectEquivalent(element, fragment.body.firstChild);
316282
}
317-
318-
export {
319-
clearRegister,
320-
extractDataIds,
321-
extractShadowDataIds,
322-
getHostChildNodes,
323-
isNativeShadowRootInstance,
324-
isSyntheticShadowRootInstance,
325-
load,
326-
registerForLoad,
327-
getHooks,
328-
setHooks,
329-
spyConsole,
330-
customElementCallbackReactionErrorListener,
331-
ariaPropertiesMapping,
332-
ariaProperties,
333-
ariaAttributes,
334-
nonStandardAriaProperties,
335-
nonPolyfilledAriaProperties,
336-
getPropertyDescriptor,
337-
attachReportingControlDispatcher,
338-
detachReportingControlDispatcher,
339-
IS_SYNTHETIC_SHADOW_LOADED,
340-
expectConsoleCalls,
341-
expectConsoleCallsDev,
342-
catchUnhandledRejectionsAndErrors,
343-
addTrustedSignal,
344-
expectEquivalentDOM,
345-
LOWERCASE_SCOPE_TOKENS,
346-
USE_COMMENTS_FOR_FRAGMENT_BOOKENDS,
347-
USE_FRAGMENTS_FOR_LIGHT_DOM_SLOTS,
348-
DISABLE_OBJECT_REST_SPREAD_TRANSFORMATION,
349-
ENABLE_ELEMENT_INTERNALS_AND_FACE,
350-
USE_LIGHT_DOM_SLOT_FORWARDING,
351-
ENABLE_THIS_DOT_HOST_ELEMENT,
352-
ENABLE_THIS_DOT_STYLE,
353-
TEMPLATE_CLASS_NAME_OBJECT_BINDING,
354-
};

packages/@lwc/integration-not-karma/test/accessibility/non-standard-aria-props/index.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { createElement } from 'lwc';
22
import Light from 'x/light';
33
import Shadow from 'x/shadow';
4+
import { nonStandardAriaProperties } from '../../../helpers/aria.js';
45
import {
56
attachReportingControlDispatcher,
67
detachReportingControlDispatcher,
7-
nonStandardAriaProperties,
88
} from '../../../helpers/utils.js';
99

1010
// This test only works if the ARIA reflection polyfill is loaded

0 commit comments

Comments
 (0)