Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
099ab86
test(wtr): use vitest spy instead of jasmine
wjhsf Sep 30, 2025
a249b96
test(wtr): add API version 66 coverage to CI
wjhsf Oct 6, 2025
1e50ff1
test(wtr): indent consistently
wjhsf Oct 6, 2025
715cac8
test(wtr): move base config into shared dir
wjhsf Oct 7, 2025
22cfa8d
test(wtr): run tests in multiple browsers
wjhsf Oct 7, 2025
af60a96
test(wtr): use build script to install playwright
wjhsf Oct 7, 2025
41676b5
chore: bundlesize
wjhsf Oct 7, 2025
1b44785
test(wtr): add type for param
wjhsf Oct 7, 2025
2072694
test(wtr): use sauce helper in CI
wjhsf Oct 7, 2025
423c051
test(wtr): add install to playwright setup
wjhsf Oct 7, 2025
7841184
test(wtr): enable saucelabs in all runs
wjhsf Oct 7, 2025
52915ff
test(wtr): kerjigger playwright again
wjhsf Oct 7, 2025
f17448b
test(wtr): rekerjigger playwright again
wjhsf Oct 7, 2025
6412646
test(wtr): make fake SSR file more clear
wjhsf Oct 7, 2025
e4092b4
test(wtr): install playwright deps in WTR CI
wjhsf Oct 7, 2025
5357cd7
test(wtr): and much rekerjiggering there was
wjhsf Oct 7, 2025
3fade97
test(wtr): isolate server-side LWC
wjhsf Oct 9, 2025
9e4ac3e
test(wtr): hack for nucleus
wjhsf Oct 9, 2025
465dd72
test(wtr): re-enable CTE tests @W-19098211 (#5535)
wjhsf Oct 14, 2025
5c81592
chore(ci): split hydration tests into engine-server and ssr-v2
wjhsf Oct 15, 2025
e928017
chore(ci): split integration tests into two groups
wjhsf Oct 15, 2025
1deb775
Merge branch 'master' into wjh/wtr-keep-on-enving
wjhsf Oct 15, 2025
f6ea8de
chore(ci): build first and cache result so parallel jobs are faster
wjhsf Oct 15, 2025
e83ec4e
test(wtr): check correct CI env var
wjhsf Oct 15, 2025
02c8206
test(wtr): use concurrency in CI
wjhsf Oct 15, 2025
8564bec
test(wtr): always run browsers concurrently
wjhsf Oct 15, 2025
e1288ce
chore(ci): give up on caching (for now?)
wjhsf Oct 15, 2025
b1fef23
test(wtr): try difference sauce config
wjhsf Oct 15, 2025
2aa45e1
chore(ci): don't needs: install-and-build
wjhsf Oct 15, 2025
9d59c9a
chore(ci): use distinct tunnel IDs for SauceLabs
wjhsf Oct 16, 2025
3b7657d
Merge branch 'master' into wjh/wtr-keep-on-enving
wjhsf Oct 16, 2025
45d38da
test(wtr): revert concurrency in CI
wjhsf Oct 16, 2025
199412f
test(wtr): disable tests that sauce doesn't like
wjhsf Oct 16, 2025
4672320
test(wtr): only run chrome in saucelabs
wjhsf Oct 17, 2025
41ce390
chore(ci): use env var for runs-on for easier updates
wjhsf Oct 17, 2025
3fc2bc2
chore(ci): use matrix values to ensure unique tunnel IDs
wjhsf Oct 17, 2025
570da42
Revert "chore(ci): use env var for runs-on for easier updates"
wjhsf Oct 17, 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
1 change: 1 addition & 0 deletions .github/workflows/web-test-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ jobs:
- run: API_VERSION=60 yarn test
- run: API_VERSION=61 yarn test
- run: API_VERSION=62 yarn test
- run: API_VERSION=66 yarn test
- run: DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 yarn test || true
- run: DISABLE_STATIC_CONTENT_OPTIMIZATION=1 yarn test
- run: ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL=1 yarn test
Expand Down
25 changes: 19 additions & 6 deletions packages/@lwc/engine-core/src/libs/signal-tracker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@ export function unsubscribeFromSignals(target: object) {

type CallbackFunction = () => void;

/**
* A normalized string representation of an error, because browsers behave differently
*/
const errorWithStack = (err: unknown): string => {
if (typeof err !== 'object' || err === null) {
return String(err);
}
const stack = 'stack' in err ? String(err.stack) : '';
const message = 'message' in err ? String(err.message) : '';
const constructor = err.constructor.name;
return stack.includes(message) ? stack : `${constructor}: ${message}\n${stack}`;
};

/**
* This class is used to keep track of the signals associated to a given object.
* It is used to prevent the LWC engine from subscribing duplicate callbacks multiple times
Expand All @@ -67,9 +80,9 @@ class SignalTracker {
}
} catch (err: any) {
logWarnOnce(
`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${
err?.stack ?? err
}`
`Attempted to subscribe to an object that has the shape of a signal but received the following error: ${errorWithStack(
err
)}`
);
}
}
Expand All @@ -79,9 +92,9 @@ class SignalTracker {
this.signalToUnsubscribeMap.forEach((unsubscribe) => unsubscribe());
} catch (err: any) {
logWarnOnce(
`Attempted to call a signal's unsubscribe callback but received the following error: ${
err?.stack ?? err
}`
`Attempted to call a signal's unsubscribe callback but received the following error: ${errorWithStack(
err
)}`
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/@lwc/integration-not-karma/configs/hydration.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as options from '../helpers/options.js';
import createConfig from './base.js';
import createConfig from './shared/base-config.js';
import hydrationTestPlugin from './plugins/serve-hydration.js';

const SHADOW_MODE = options.SHADOW_MODE_OVERRIDE ?? 'native';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { importMapsPlugin } from '@web/dev-server-import-maps';
import * as options from '../helpers/options.js';
import createConfig from './base.js';
import createConfig from './shared/base-config.js';
import testPlugin from './plugins/serve-integration.js';

const SHADOW_MODE = options.SHADOW_MODE_OVERRIDE ?? 'synthetic';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { join } from 'node:path';
import { LWC_VERSION } from '@lwc/shared';
import { resolvePathOutsideRoot } from '../helpers/utils.js';
import { resolvePathOutsideRoot } from '../../helpers/utils.js';
import { getBrowsers } from './browsers.js';

/**
* We want to convert from parsed options (true/false) to a `process.env` with only strings.
Expand Down Expand Up @@ -37,13 +38,15 @@ export default (options) => {
});

return {
browsers: getBrowsers(options),
browserLogs: false,
// FIXME: Parallelism breaks tests that rely on focus/requestAnimationFrame, because they often
// time out before they receive focus. But it also makes the full suite take 3x longer to run...
// Potential workaround: https://github.com/modernweb-dev/web/issues/2588
concurrency: 1,
browserLogs: false,
concurrentBrowsers: 3,
nodeResolve: true,
rootDir: join(import.meta.dirname, '..'),
rootDir: join(import.meta.dirname, '../..'),
plugins: [
{
name: 'lwc-base-plugin',
Expand All @@ -64,7 +67,8 @@ export default (options) => {
},
],
testRunnerHtml: (testFramework) =>
`<!DOCTYPE html>
`
<!DOCTYPE html>
<html>
<head>
<script type="module">
Expand All @@ -82,6 +86,7 @@ export default (options) => {
<script type="module" src="./helpers/setup.js"></script>
<script type="module" src="${testFramework}"></script>
</head>
</html>`,
</html>
`,
};
};
56 changes: 56 additions & 0 deletions packages/@lwc/integration-not-karma/configs/shared/browsers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { playwrightLauncher } from '@web/test-runner-playwright';
import { createSauceLabsLauncher } from '@web/test-runner-saucelabs';

/** @type {(options: typeof import('../../helpers/options.js')) => import("@web/test-runner").BrowserLauncher[]} */
export function getBrowsers(options) {
if (options.IS_CI) {
if (!options.SAUCE_USERNAME || !options.SAUCE_ACCESS_KEY || !options.SAUCE_TUNNEL_ID) {
throw new Error(
`SAUCE_USERNAME, SAUCE_ACCESS_KEY, and SAUCE_TUNNEL_ID must be configured in CI`
);
}
const sauceLabsLauncher = createSauceLabsLauncher(
{
user: options.SAUCE_USERNAME,
key: options.SAUCE_ACCESS_KEY,
},
{
tunnelName: options.SAUCE_TUNNEL_ID,
}
);
return [
sauceLabsLauncher({
browserName: 'chrome',
browserVersion: 'latest',
}),
sauceLabsLauncher({
browserName: 'firefox',
browserVersion: 'latest',
}),
sauceLabsLauncher({
browserName: 'safari',
browserVersion: 'latest',
platformName: 'macOS 15', // Update this with new Mac releases
}),
...(options.LEGACY_BROWSERS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somewhat misleading, how much does things change in (2 versions prior to latest?) to call them legacy?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a silly name, but it's what we did with the Karma tests.

? [
sauceLabsLauncher({
browserName: 'chrome',
browserVersion: 'latest-2',
}),
sauceLabsLauncher({
browserName: 'safari',
browserVersion: 'latest-2',
platformName: 'macOS 13', // Should be 2 behind latest
}),
]
: []),
];
} else {
return [
playwrightLauncher({ product: 'chromium' }),
playwrightLauncher({ product: 'firefox' }),
playwrightLauncher({ product: 'webkit' }),
];
}
}
6 changes: 5 additions & 1 deletion packages/@lwc/integration-not-karma/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "8.22.4",
"type": "module",
"scripts": {
"build": "playwright install",
"start": "web-test-runner --manual",
"test": "web-test-runner --config configs/integration.js",
"test:hydration": "web-test-runner --config configs/hydration.js"
Expand All @@ -21,7 +22,10 @@
"@web/dev-server-import-maps": "^0.2.1",
"@web/dev-server-rollup": "^0.6.4",
"@web/test-runner": "^0.20.2",
"chai": "^6.2.0"
"@web/test-runner-playwright": "^0.11.1",
"@web/test-runner-saucelabs": "^0.13.0",
"chai": "^6.2.0",
"playwright": "^1.56.0"
},
"volta": {
"extends": "../../../package.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ it('CustomElementConstructor cannot be `new`ed before being defined', () => {
new UndefinedComponent.CustomElementConstructor();
};
expect(func).toThrowError(TypeError);
expect(func).toThrowError(/(Illegal constructor|does not define a custom element)/);
expect(func).toThrowError(
/(Illegal constructor|does not define a custom element|is not a valid custom element constructor)/
);
});

it('CustomElementConstructor can be `new`ed after being defined', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Throws from 'x/throws';
// Note for testing purposes the signal implementation uses LWC module resolution to simplify things.
// In production the signal will come from a 3rd party library.
import { Signal } from 'x/signal';
import { jasmine } from '../../../helpers/jasmine.js';
import { fn as mockFn } from '@vitest/spy';
import { resetDOM } from '../../../helpers/reset.js';

describe('signal protocol', () => {
Expand Down Expand Up @@ -190,7 +190,7 @@ describe('signal protocol', () => {

it('does not subscribe if the signal shape is incorrect', async () => {
const elm = createElement('x-child', { is: Child });
const subscribe = jasmine.createSpy();
const subscribe = mockFn();
// Note the signals property is value's' and not value
const signal = { values: 'initial value', subscribe };
elm.signal = signal;
Expand All @@ -202,7 +202,7 @@ describe('signal protocol', () => {

it('does not subscribe if the signal is not added as trusted signal', async () => {
const elm = createElement('x-child', { is: Child });
const subscribe = jasmine.createSpy();
const subscribe = mockFn();
// Note this follows the shape of the signal implementation
// but it's not added as a trusted signal (add using lwc.addTrustedSignal)
const signal = {
Expand Down
56 changes: 53 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2091,9 +2091,11 @@

"@lwc/eslint-plugin-lwc-internal@link:./scripts/eslint-plugin":
version "0.0.0"
uid ""

"@lwc/test-utils-lwc-internals@link:./scripts/test-utils":
version "0.0.0"
uid ""

"@napi-rs/[email protected]":
version "0.2.4"
Expand Down Expand Up @@ -4026,6 +4028,35 @@
dependencies:
"@web/test-runner-core" "^0.13.0"

"@web/test-runner-playwright@^0.11.1":
version "0.11.1"
resolved "https://registry.yarnpkg.com/@web/test-runner-playwright/-/test-runner-playwright-0.11.1.tgz#d993112ae2126eb74c1c5a171d6ea44c2dd24b4e"
integrity sha512-l9tmX0LtBqMaKAApS4WshpB87A/M8sOHZyfCobSGuYqnREgz5rqQpX314yx+4fwHXLLTa5N64mTrawsYkLjliw==
dependencies:
"@web/test-runner-core" "^0.13.0"
"@web/test-runner-coverage-v8" "^0.8.0"
playwright "^1.53.0"

"@web/test-runner-saucelabs@^0.13.0":
version "0.13.0"
resolved "https://registry.yarnpkg.com/@web/test-runner-saucelabs/-/test-runner-saucelabs-0.13.0.tgz#66b50d4cf6ca29163e8c67e0d6a0b5863ac69172"
integrity sha512-RHVDIFVaiOoxydigx1S4wrA20wjjLF9IAxlT7HxYHxO1qx1UIuWLabd6jEGlxluC0xFhuBJLm+zFj8zMEXJNyg==
dependencies:
"@web/test-runner-webdriver" "^0.9.0"
internal-ip "^6.2.0"
nanoid "^3.1.25"
saucelabs "^9.0.0"
webdriver "^9.0.0"
webdriverio "^9.0.0"

"@web/test-runner-webdriver@^0.9.0":
version "0.9.0"
resolved "https://registry.yarnpkg.com/@web/test-runner-webdriver/-/test-runner-webdriver-0.9.0.tgz#18fb3299ddc258a2782028de19f21ee4c27895c5"
integrity sha512-G2io6ph0v/sX0U/DEgh/EUHsLsq8/Gs/uUw8N7rcUaXSdIFCUbxlwzx/qZv2ZKY52q84oYUyeOhViNZ2OqYl6Q==
dependencies:
"@web/test-runner-core" "^0.13.0"
webdriverio "^9.0.0"

"@web/test-runner@^0.20.2":
version "0.20.2"
resolved "https://registry.yarnpkg.com/@web/test-runner/-/test-runner-0.20.2.tgz#3045de8f14eb9f9b8aa51aa7fd9849dd95bb0a93"
Expand Down Expand Up @@ -7605,6 +7636,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==

[email protected]:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==

fsevents@~2.3.2, fsevents@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
Expand Down Expand Up @@ -11279,6 +11315,20 @@ pkg-up@^4.0.0:
dependencies:
find-up "^6.2.0"

[email protected]:
version "1.56.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.56.0.tgz#14b40ea436551b0bcefe19c5bfb8d1804c83739c"
integrity sha512-1SXl7pMfemAMSDn5rkPeZljxOCYAmQnYLBTExuh6E8USHXGSX3dx6lYZN/xPpTz1vimXmPA9CDnILvmJaB8aSQ==

playwright@^1.53.0, playwright@^1.56.0:
version "1.56.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.56.0.tgz#71c533c61da33e95812f8c6fa53960e073548d9a"
integrity sha512-X5Q1b8lOdWIE4KAoHpW3SE8HvUB+ZZsUoN64ZhjnN8dOb1UpujxBtENGiZFE+9F/yhzJwYa+ca3u43FeLbboHA==
dependencies:
playwright-core "1.56.0"
optionalDependencies:
fsevents "2.3.2"

portfinder@^1.0.32:
version "1.0.37"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.37.tgz#92b754ef89a11801c8efe4b0e5cd845b0064c212"
Expand Down Expand Up @@ -12132,7 +12182,7 @@ [email protected]:
tunnel "0.0.6"
yargs "^17.0.1"

saucelabs@^9.0.1:
saucelabs@^9.0.0, saucelabs@^9.0.1:
version "9.0.2"
resolved "https://registry.yarnpkg.com/saucelabs/-/saucelabs-9.0.2.tgz#99f6170f3d789fcb0be2f270f7d37a9d7cdf5187"
integrity sha512-37QGEOgp9BP1re6S06qpNcBZ0Hw+ZSkZkDepbXHT9VjYoRQwRzUoLtKqE4yyVeK7dzcQXQapmTGF1kp1jO2VDw==
Expand Down Expand Up @@ -13856,7 +13906,7 @@ [email protected]:
ky "^0.30.0"
lodash.merge "^4.6.1"

[email protected]:
[email protected], webdriver@^9.0.0:
version "9.20.0"
resolved "https://registry.yarnpkg.com/webdriver/-/webdriver-9.20.0.tgz#518fa61abd0b0435509548ef54fb0824f0fa04fd"
integrity sha512-Kk+AGV1xWLNHVpzUynQJDULMzbcO3IjXo3s0BzfC30OpGxhpaNmoazMQodhtv0Lp242Mb1VYXD89dCb4oAHc4w==
Expand Down Expand Up @@ -13906,7 +13956,7 @@ [email protected]:
serialize-error "^8.0.0"
webdriver "7.19.5"

[email protected], webdriverio@^9.19.2:
[email protected], webdriverio@^9.0.0, webdriverio@^9.19.2:
version "9.20.0"
resolved "https://registry.yarnpkg.com/webdriverio/-/webdriverio-9.20.0.tgz#46f45268f2c4021a18045a7e7dfd738225514ece"
integrity sha512-cqaXfahTzCFaQLlk++feZaze6tAsW8OSdaVRgmOGJRII1z2A4uh4YGHtusTpqOiZAST7OBPqycOwfh01G/Ktbg==
Expand Down
Loading