Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
8c7ed79
test(wtr): update tests to use relative path to utils
wjhsf Aug 28, 2025
e2f88d5
test(wtr): revert removing TestUtils
wjhsf Sep 2, 2025
81275d0
test(wtr): remove useless describe
wjhsf Sep 2, 2025
39533d3
test(wtr): replace IIFE script with module import
wjhsf Sep 2, 2025
33e58c8
test(wtr): clean up SSR execution script
wjhsf Sep 2, 2025
d0b8003
test(wtr): always use DISABLE_SYNTHETIC
wjhsf Sep 3, 2025
976c002
test(wtr): enable all hydration tests
wjhsf Sep 3, 2025
8d39505
Merge branch 'master' into wjh/wtr-hyd
wjhsf Sep 4, 2025
c66afad
test(wtr): remove side effect from signals helper
wjhsf Sep 4, 2025
f1c50b0
test(wtr): import directly from file, not from barrel exporter
wjhsf Sep 4, 2025
7a73bf0
test(wtr): change bulk export statement to individual exports
wjhsf Sep 4, 2025
9b7b21b
test(wtr): remove unnecessary aria re-export
wjhsf Sep 4, 2025
9deaca2
test(wtr): fix a few more ARIA util imports
wjhsf Sep 4, 2025
1cf1275
chore: move comment for nicer aesthetic
wjhsf Sep 4, 2025
7fc137c
test(wtr): remove unused option
wjhsf Sep 4, 2025
ae937cc
test(wtr): fix another ARIA util import
wjhsf Sep 4, 2025
9250dd5
test(wtr): import directly from hooks file rather than utils
wjhsf Sep 4, 2025
d4280e8
test(wtr): import directly from signals file rather than utils
wjhsf Sep 4, 2025
bbffbf3
test(wtr): import directly from console helper rather than utils
wjhsf Sep 4, 2025
1ef88ed
test(wtr): import directly from constants helper rather than utils
wjhsf Sep 4, 2025
02f8ed1
test(wtr): only import what is needed from LWC
wjhsf Sep 4, 2025
7a5260a
test(wtr): split lwc:dynamic load helpers into separate file
wjhsf Sep 4, 2025
1a08a62
test(wtr): avoid relying on global LWC
wjhsf Sep 4, 2025
f14c829
Merge branch 'master' into wjh/wtr-smaller-utils
wjhsf Sep 9, 2025
289deeb
Merge branch 'master' into wjh/wtr-smaller-utils
wjhsf Sep 9, 2025
b97f783
test(wtr): remove unnecessary wrapping of hydration test config
wjhsf Sep 9, 2025
3cdb65c
test(wtr): remove test-utils logic from resolveImport
wjhsf Sep 9, 2025
7009a26
test(wtr): move plugin from shared config to only config that uses it
wjhsf Sep 9, 2025
19c1090
test(wtr): remove useless guid
wjhsf Sep 9, 2025
5e75329
test(wtr): remove unnecessary test-utils global
wjhsf Sep 9, 2025
497bfa8
test(wtr): clean up component definition
wjhsf Sep 9, 2025
8ff59c5
test(wtr): change component in test from IIFE to import
wjhsf Sep 11, 2025
885ce57
test(wtr): shift logic out of wrapper into static test runner file
wjhsf Sep 11, 2025
aa47c49
test(wtr): make test setup/teardown more idiomatic
wjhsf Sep 11, 2025
6185811
test(wtr): clean up module compilation
wjhsf Sep 11, 2025
ec0186f
chore(wtr): make dependency on @vitest/spy explicit
wjhsf Sep 11, 2025
3463450
test(wtr): remove console suppression
wjhsf Sep 11, 2025
7c0eb0a
test(wtr): clean up names and comments
wjhsf Sep 11, 2025
d91c8aa
Merge branch 'master' into wjh/wtr-clean-hydration
wjhsf Sep 11, 2025
371032d
Merge branch 'master' into wjh/wtr-clean-hydration
wjhsf Sep 12, 2025
c47a44d
test(wtr): move and rename file
wjhsf Sep 12, 2025
639f754
Merge branch 'master' into wjh/wtr-clean-hydration
wjhsf Sep 12, 2025
c21a895
test(wtr): remove usage of global TestUtils from hydration tests
wjhsf Sep 12, 2025
d041a23
test(wtr): remove LWC import from utils
wjhsf Sep 12, 2025
cb6213c
test(wtr): remove unused external deps
wjhsf Sep 12, 2025
76efacb
test(wtr): use imports instead of jasmine globals
wjhsf Sep 12, 2025
e86cbc4
chore(eslint): remove unused rule config
wjhsf Sep 12, 2025
136f47b
fix: attribute cte syntax in integration tests
jhefferman-sfdc Sep 16, 2025
6e31af9
test(wtr): fix case in import
wjhsf Sep 16, 2025
9805b58
test(wtr): re-enable tests that used to fail in CI
wjhsf Sep 16, 2025
67f727b
test(wtr): enable browser logs
wjhsf Sep 16, 2025
370da4c
Merge remote-tracking branch 'origin/jhefferman/fix-cte-integration-t…
wjhsf Sep 16, 2025
22822f7
test(wtr): name plugins
wjhsf Sep 16, 2025
654aef7
test(wtr): rename variables and document functions for clarity
wjhsf Sep 16, 2025
bc09749
test(wtr): convert promise chains to async/await
wjhsf Sep 16, 2025
99d6b27
Merge branch 'master' into wjh/wtr-spam
wjhsf Sep 16, 2025
c494abe
test(wtr): load code from known url, rather than sniffing script tag
wjhsf Sep 16, 2025
02ca871
test(wtr): convert LWC from iife to fake cjs
wjhsf Sep 17, 2025
85610ff
test(wtr): remove unnecessary wrapping
wjhsf Sep 17, 2025
96fa673
Merge branch 'master' into wjh/wtr-spam
wjhsf Sep 22, 2025
bcba665
test(wtr): data can be data, not a function
wjhsf Sep 22, 2025
b79d66b
test(wtr): replace `evaluate` with functions that require less wrapping
wjhsf Sep 22, 2025
3437c71
test(wtr): only fetch scripts once
wjhsf Sep 22, 2025
23491ec
test(wtr): john was here
wjhsf Sep 22, 2025
947612f
test(wtr): add line breaks and vars for clarity
wjhsf Sep 22, 2025
9fa8504
test(wtr): rename variable
wjhsf Sep 22, 2025
97ee6e9
test(wtr): fix param pass through
wjhsf Sep 22, 2025
159d046
test(wtr): more cleanup
wjhsf Sep 22, 2025
2e8abcf
test(wtr): remove outdated comment
wjhsf Sep 23, 2025
d9eda1d
test(wtr): avoid shadowing global var
wjhsf Sep 23, 2025
43818d5
test(wtr): enable custom element registry tests
wjhsf Sep 23, 2025
ec5293d
Merge branch 'master' into wjh/wtr-spam
wjhsf Sep 23, 2025
225da98
test(wtr): hoist function definition
wjhsf Sep 23, 2025
e967569
chore: use vitest spy instead of custom hack
wjhsf Sep 23, 2025
7112bc7
test(wtr): use vitest spy instead of custom
wjhsf Sep 23, 2025
bd7ee75
test(wtr): convert test to async/await
wjhsf Sep 23, 2025
6764ad9
Merge branch 'wjh/wtr-async-await' into wjh/no-spy-console
wjhsf Sep 23, 2025
f729461
test(wtr): use vitest spy instead of custom
wjhsf Sep 24, 2025
8eece7c
test(wtr): move util into only file that uses it
wjhsf Sep 24, 2025
fe48d42
Merge branch 'master' into wjh/no-spy-console
wjhsf Sep 24, 2025
a97effd
Merge branch 'master' into wjh/no-spy-console
wjhsf Sep 25, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,8 @@ const createRollupPlugin = (input, options) => {
enableStaticContentOptimization: !DISABLE_STATIC_CONTENT_OPTIMIZATION,
disableSyntheticShadowSupport: DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER,
apiVersion: API_VERSION,
modules: [
{
// Assume `ctx.path` is a component file, e.g. modules/x/foo/foo.js
dir: path.resolve(input, '../../..'),
},
],
// Assume `ctx.path` is a component file, e.g. modules/x/foo/foo.js
modules: [{ dir: path.resolve(input, '../../..') }],
...options,
});
};
Expand Down Expand Up @@ -85,6 +81,7 @@ const transform = async (ctx) => {
plugins: [customLwcRollupPlugin],

external: [
'@vitest/spy',
'lwc',
'wire-service',
// Some helper files export functions that mutate a global state. The setup file calls
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { spyOn } from '@vitest/spy';
import * as LWC from 'lwc';
import { spyConsole } from '../../helpers/console';
import { setHooks } from '../../helpers/hooks';

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

/**
* A much simplified version of the spies originally used for Karma.
* Should probably be eventually replaced with individual spies.
*/
export function spyConsole() {
const log = spyOn(console, 'log');
const warn = spyOn(console, 'warn');
const error = spyOn(console, 'error');
return {
calls: {
log: log.mock.calls,
warn: warn.mock.calls,
error: error.mock.calls,
},
reset() {
log.mockRestore();
warn.mockRestore();
error.mockRestore();
},
};
}

function appendTestTarget(ssrText) {
const div = document.createElement('div');
const testTarget = parseStringToDom(ssrText);
Expand Down
23 changes: 0 additions & 23 deletions packages/@lwc/integration-not-karma/helpers/console.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import AttrChanged from 'x/attrChanged';
import ReflectCamel from 'x/reflectCamel';
import WithChildElmsHasSlot from 'x/withChildElmsHasSlot';
import WithChildElmsHasSlotLight from 'x/withChildElmsHasSlotLight';
import { spyConsole } from '../../../helpers/console.js';
import { spyOn } from '@vitest/spy';
import { USE_COMMENTS_FOR_FRAGMENT_BOOKENDS } from '../../../helpers/constants.js';

const vFragBookend = USE_COMMENTS_FOR_FRAGMENT_BOOKENDS ? '<!---->' : '';
Expand Down Expand Up @@ -69,19 +69,9 @@ it('should create custom element if it exists before customElements.define', ()
describe('non-empty custom element', () => {
let consoleSpy;
beforeEach(() => {
consoleSpy = spyConsole();
consoleSpy = spyOn(console, 'warn').mockImplementation(() => {});
});
afterEach(() => {
consoleSpy.reset();
});

function expectWarnings(expectedWarnings) {
const observedWarnings = consoleSpy.calls.warn
.flat()
.map((err) => (err instanceof Error ? err.message : err));

expect(observedWarnings).toEqual(expectedWarnings);
}
afterEach(() => consoleSpy.mockRestore());

it('should log error if non-native-shadow custom element has children', () => {
const elm = document.createElement('test-custom-element-preexisting2');
Expand All @@ -93,11 +83,11 @@ describe('non-empty custom element', () => {
class extends WithChildElms.CustomElementConstructor {}
);
if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
expectWarnings([
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
]);
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
);
} else {
expectWarnings([]);
expect(consoleSpy).not.toHaveBeenCalled();
}

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

if (process.env.NODE_ENV !== 'production') {
expectWarnings([
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
]);
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
);
} else {
expectWarnings([]);
expect(consoleSpy).not.toHaveBeenCalled();
}

expect(elm.innerHTML).toBe(`${vFragBookend}${vFragBookend}`);
Expand All @@ -143,11 +133,11 @@ describe('non-empty custom element', () => {
class extends WithChildElmsHasSlot.CustomElementConstructor {}
);
if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
expectWarnings([
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
]);
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
);
} else {
expectWarnings([]);
expect(consoleSpy).not.toHaveBeenCalled();
}

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

if (process.env.NODE_ENV === 'production') {
expectWarnings([]);
expect(consoleSpy).not.toHaveBeenCalled();
} else {
expectWarnings([
'Found an existing shadow root for the custom element "Child". Call `hydrateComponent` instead.',
]);
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
'Found an existing shadow root for the custom element "Child". Call `hydrateComponent` instead.'
);
}
expect(elm.shadowRoot.innerHTML).toBe('<div></div>');
});
Expand All @@ -194,11 +184,11 @@ describe('non-empty custom element', () => {
document.body.appendChild(elm);

if (process.env.NODE_ENV !== 'production' && !process.env.NATIVE_SHADOW) {
expectWarnings([
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.',
]);
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
'Light DOM and synthetic shadow custom elements cannot have child nodes. Ensure the element is empty, including whitespace.'
);
} else {
expectWarnings([]);
expect(consoleSpy).not.toHaveBeenCalled();
}

expect(elm.childNodes.length).toBe(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { createElement } from 'lwc';
import EventHandler from 'x/eventHandler';
import EventHandlerOptions from 'x/eventHandlerOptions';
import AdditionWhileDispatch from 'x/additionWhileDispatch';
import { spyConsole } from '../../../helpers/console.js';
import { spyOn } from '@vitest/spy';

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

describe('event handler is not a function', () => {
let consoleSpy;
beforeEach(() => {
consoleSpy = spyConsole();
});
afterEach(() => {
consoleSpy.reset();
beforeAll(() => {
consoleSpy = spyOn(console, 'error');
});
afterEach(() => consoleSpy.mockReset());
afterAll(() => consoleSpy.mockRestore());

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

if (process.env.NODE_ENV === 'production') {
expect(consoleSpy.calls.error.length).toEqual(0);
expect(consoleSpy).not.toHaveBeenCalled();
} else {
expect(consoleSpy.calls.error.length).toEqual(1);
expect(consoleSpy.calls.error[0][0].message).toContain(
'Invalid second argument for this.addEventListener()'
expect(consoleSpy).toHaveBeenCalledExactlyOnceWith(
expect.stringContaining('Invalid second argument for this.addEventListener()')
);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import LwcDynamicSlotted from 'x/lwcDynamicSlotted';
import ContainerFoo from 'x/containerFoo';
import ContainerBar from 'x/containerBar';

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

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

describe('slotted content using lwc:dynamic', () => {
let consoleSpy;
beforeEach(() => {
consoleSpy = spyConsole();
});
afterEach(() => {
consoleSpy.reset();
beforeAll(() => {
consoleSpy = spyOn(console, 'error');
});
afterAll(() => consoleSpy.mockRestore());

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

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

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

describe('slotted content', () => {
let consoleSpy;
beforeEach(() => {
consoleSpy = spyConsole();
});
afterEach(() => {
consoleSpy.reset();
beforeAll(() => {
consoleSpy = spyOn(console, 'error');
});
afterAll(() => consoleSpy.mockRestore());

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

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