Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
e2c7afe
test(wtr): run all the flavors and see what happens
wjhsf Sep 26, 2025
0c81acb
test(wtr): prefer DISABLE_SYNTHETIC over duplicate env var name
wjhsf Sep 26, 2025
716f7b5
test(wtr): fix hydration tests
wjhsf Sep 26, 2025
f2934f8
test(wtr): create `process.env` with only string values
wjhsf Sep 26, 2025
95d3b4b
test(wtr): split integration and hydration tests into separate jobs
wjhsf Sep 26, 2025
46c3d56
Revert "test(wtr): prefer DISABLE_SYNTHETIC over duplicate env var name"
wjhsf Sep 26, 2025
8c15e71
test(wtr): revert to using original env var
wjhsf Sep 26, 2025
373bcf1
test(wtr): make integration and hydration tests have different defaul…
wjhsf Sep 26, 2025
0526e49
test(wtr): fix tests running in native shadow mode
wjhsf Sep 26, 2025
5dbe1e9
test(wtr): make working tests fail for real in CI if they break
wjhsf Sep 26, 2025
0734767
test(wtr): avoid accidentally not running tests again
wjhsf Sep 26, 2025
39920e1
test(wtr): enable FORCE_NATIVE_SHADOW_MODE_FOR_TEST in CI
wjhsf Sep 26, 2025
ee9bc59
test(wtr): enable DISABLE_DETACHED_REHYDRATION=1 in CI
wjhsf Sep 26, 2025
ca7f8ee
test(wtr): enable more test scenarios in CI
wjhsf Sep 29, 2025
5b35d40
test(wtr): split CI job into groups
wjhsf Sep 29, 2025
1ccbdae
Merge branch 'master' into wjh/wtr-env-vars
wjhsf Sep 29, 2025
71f8185
test(wtr): remove matrix config from job that doesn't need it
wjhsf Sep 29, 2025
e525359
test(wtr): enable API_VERSION tests in CI and alphabetize list
wjhsf Sep 29, 2025
da8a3af
test(wtr): use vitest spy instead of jasmine spy
wjhsf Sep 29, 2025
d1af772
test(wtr): fix broken test assertion
wjhsf Sep 29, 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
67 changes: 64 additions & 3 deletions .github/workflows/web-test-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ env:
NODE_VERSION: '20.19.4'

jobs:
# Starting with the basics, just get tests running in CI
# TODO: add env var combos we use for Karma tests
# TODO: upload result artifacts
# TODO: make it saucy 🥫
wtr-group-1:
integration-tests:
runs-on: ubuntu-22.04
env:
SAUCE_TUNNEL_ID: github-action-tunnel-wtr-${{github.run_id}}-group-1
Expand Down Expand Up @@ -51,4 +49,67 @@ jobs:
# region: us

- run: yarn test
- run: SHADOW_MODE_OVERRIDE=native yarn test
- run: LEGACY_BROWSERS=1 yarn test || true
- run: FORCE_NATIVE_SHADOW_MODE_FOR_TEST=1 yarn test || true
- run: DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 yarn test || true
- run: DISABLE_DETACHED_REHYDRATION=1 yarn test || true
- run: DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 DISABLE_DETACHED_REHYDRATION=1 yarn test || true
- run: API_VERSION=58 yarn test || true
- run: API_VERSION=58 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: API_VERSION=59 yarn test || true
- run: API_VERSION=59 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: API_VERSION=60 yarn test || true
- run: API_VERSION=60 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: API_VERSION=61 yarn test || true
- run: API_VERSION=61 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: API_VERSION=62 yarn test || true
- run: API_VERSION=62 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER=1 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER=1 SHADOW_MODE_OVERRIDE=native DISABLE_STATIC_CONTENT_OPTIMIZATION=1 yarn test || true
- run: ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL=1 yarn test || true
- run: ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL=1 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: DISABLE_STATIC_CONTENT_OPTIMIZATION=1 yarn test || true
- run: DISABLE_STATIC_CONTENT_OPTIMIZATION=1 SHADOW_MODE_OVERRIDE=native yarn test || true
- run: NODE_ENV_FOR_TEST=production yarn test || true
- run: NODE_ENV_FOR_TEST=production SHADOW_MODE_OVERRIDE=native yarn test || true
hydration-tests:
runs-on: ubuntu-22.04
env:
SAUCE_TUNNEL_ID: github-action-tunnel-wtr-${{github.run_id}}-group-1
defaults:
run:
working-directory: ./packages/@lwc/integration-not-karma
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'

- name: Install dependencies
run: yarn install --frozen-lockfile
working-directory: ./

# - uses: saucelabs/sauce-connect-action@v3.0.0
# with:
# username: ${{ secrets.SAUCE_USERNAME }}
# accessKey: ${{ secrets.SAUCE_ACCESS_KEY }}
# tunnelName: ${{ env.SAUCE_TUNNEL_ID }}
# region: us
- run: ENGINE_SERVER=1 yarn test:hydration || true
- run: ENGINE_SERVER=1 SHADOW_MODE_OVERRIDE=synthetic yarn test:hydration || true
- run: ENGINE_SERVER=1 NODE_ENV_FOR_TEST=production yarn test:hydration || true
- run: ENGINE_SERVER=1 DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 yarn test:hydration || true
- run: ENGINE_SERVER=1 DISABLE_STATIC_CONTENT_OPTIMIZATION=1 yarn test:hydration || true
- run: ENGINE_SERVER=1 DISABLE_DETACHED_REHYDRATION=1 yarn test:hydration || true
- run: ENGINE_SERVER=1 DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 DISABLE_DETACHED_REHYDRATION=1 yarn test:hydration || true
- run: yarn test:hydration
- run: SHADOW_MODE_OVERRIDE=synthetic yarn test:hydration
- run: NODE_ENV_FOR_TEST=production yarn test:hydration || true
- run: DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE=1 yarn test:hydration || true
- run: DISABLE_STATIC_CONTENT_OPTIMIZATION=1 yarn test:hydration || true
104 changes: 60 additions & 44 deletions packages/@lwc/integration-not-karma/configs/base.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,70 @@
import { join } from 'node:path';
import { LWC_VERSION } from '@lwc/shared';
import * as options from '../helpers/options.js';
import { resolvePathOutsideRoot } from '../helpers/utils.js';

/**
* We want to convert from parsed options (true/false) to a `process.env` with only strings.
* This drops `false` values and converts everything else to a string.
*/
const envify = (obj) => {
const clone = {};
for (const [key, val] of Object.entries(obj)) {
if (val !== false) {
clone[key] = String(val);
}
}
return clone;
};
const pluck = (obj, keys) => Object.fromEntries(keys.map((k) => [k, obj[k]]));
const maybeImport = (file, condition) => (condition ? `await import('${file}');` : '');

/** `process.env` to inject into test environment. */
const env = {
...pluck(options, [
'API_VERSION',
'DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE',
'DISABLE_STATIC_CONTENT_OPTIMIZATION',
'DISABLE_SYNTHETIC',
'ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL',
'ENGINE_SERVER',
'FORCE_NATIVE_SHADOW_MODE_FOR_TEST',
'NATIVE_SHADOW',
'DISABLE_DETACHED_REHYDRATION',
]),
LWC_VERSION,
NODE_ENV: options.NODE_ENV_FOR_TEST,
};
/** @type {() => import("@web/test-runner").TestRunnerConfig} */
export default (options) => {
/** `process.env` to inject into test environment. */
const env = envify({
...pluck(options, [
'API_VERSION',
'DISABLE_DETACHED_REHYDRATION',
'DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE',
'DISABLE_STATIC_CONTENT_OPTIMIZATION',
'ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL',
'ENGINE_SERVER',
'FORCE_NATIVE_SHADOW_MODE_FOR_TEST',
'NATIVE_SHADOW',
]),
LWC_VERSION,
NODE_ENV: options.NODE_ENV_FOR_TEST,
});

/** @type {import("@web/test-runner").TestRunnerConfig} */
export default {
// 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,
nodeResolve: true,
rootDir: join(import.meta.dirname, '..'),
plugins: [
{
name: 'lwc-base-plugin',
resolveImport({ source }) {
if (source === 'wire-service') {
return resolvePathOutsideRoot('../wire-service/dist/index.js');
}
},
async transform(ctx) {
if (ctx.type === 'application/javascript') {
// FIXME: copy/paste Nolan's spiel about why we do this ugly thing
return ctx.body.replace(/process\.env\.NODE_ENV === 'test-karma-lwc'/g, 'true');
}
return {
// 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,
nodeResolve: true,
rootDir: join(import.meta.dirname, '..'),
plugins: [
{
name: 'lwc-base-plugin',
resolveImport({ source }) {
if (source === 'wire-service') {
return resolvePathOutsideRoot('../wire-service/dist/index.js');
}
},
async transform(ctx) {
if (ctx.type === 'application/javascript') {
// FIXME: copy/paste Nolan's spiel about why we do this ugly thing
return ctx.body.replace(
/process\.env\.NODE_ENV === 'test-karma-lwc'/g,
'true'
);
}
},
},
},
],
testRunnerHtml: (testFramework) =>
`<!DOCTYPE html>
],
testRunnerHtml: (testFramework) =>
`<!DOCTYPE html>
<html>
<head>
<script type="module">
Expand All @@ -61,11 +76,12 @@ export default {
])
)};

${maybeImport('@lwc/synthetic-shadow', !options.DISABLE_SYNTHETIC)}
${maybeImport('@lwc/synthetic-shadow', !options.NATIVE_SHADOW)}
${maybeImport('@lwc/aria-reflection', options.ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL)}
</script>
<script type="module" src="./helpers/setup.js"></script>
<script type="module" src="${testFramework}"></script>
</head>
</html>`,
};
};
12 changes: 9 additions & 3 deletions packages/@lwc/integration-not-karma/configs/hydration.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
// Use native shadow by default in hydration tests; MUST be set before imports
process.env.DISABLE_SYNTHETIC ??= 'true';
import baseConfig from './base.js';
import * as options from '../helpers/options.js';
import createConfig from './base.js';
import hydrationTestPlugin from './plugins/serve-hydration.js';

const SHADOW_MODE = options.SHADOW_MODE_OVERRIDE ?? 'native';

const baseConfig = createConfig({
...options,
NATIVE_SHADOW: SHADOW_MODE === 'native' || options.FORCE_NATIVE_SHADOW_MODE_FOR_TEST,
});

/** @type {import("@web/test-runner").TestRunnerConfig} */
export default {
...baseConfig,
Expand Down
10 changes: 9 additions & 1 deletion packages/@lwc/integration-not-karma/configs/integration.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { importMapsPlugin } from '@web/dev-server-import-maps';
import baseConfig from './base.js';
import * as options from '../helpers/options.js';
import createConfig from './base.js';
import testPlugin from './plugins/serve-integration.js';

const SHADOW_MODE = options.SHADOW_MODE_OVERRIDE ?? 'synthetic';

const baseConfig = createConfig({
...options,
NATIVE_SHADOW: SHADOW_MODE === 'native' || options.FORCE_NATIVE_SHADOW_MODE_FOR_TEST,
});

/** @type {import("@web/test-runner").TestRunnerConfig} */
export default {
...baseConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export function runTest(configPath, componentPath, ssrRendered) {
let Component;

beforeAll(async () => {
testConfig = await import(configPath);
Component = await import(componentPath);
testConfig = (await import(configPath)).default;
Component = (await import(componentPath)).default;
Comment on lines +55 to +56
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops! We were using the wrong object, so none of the tests were actually executing. Fortunately, all the tests are still passing with this fixed. I added the else clause below to prevent this accident from happening again.

setFeatureFlags(testConfig.requiredFeatureFlags, true);
});

Expand Down Expand Up @@ -93,6 +93,8 @@ export function runTest(configPath, componentPath, ssrRendered) {
container,
selector,
});
} else {
throw new Error(`Missing test or advancedTest function in ${configPath}.`);
}
});
}
14 changes: 9 additions & 5 deletions packages/@lwc/integration-not-karma/helpers/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import { HIGHEST_API_VERSION } from '@lwc/shared';

export const LEGACY_BROWSERS = Boolean(process.env.LEGACY_BROWSERS);

export const DISABLE_SYNTHETIC = Boolean(process.env.DISABLE_SYNTHETIC);

export const FORCE_NATIVE_SHADOW_MODE_FOR_TEST = Boolean(
process.env.FORCE_NATIVE_SHADOW_MODE_FOR_TEST
);
Expand All @@ -36,20 +34,26 @@ export const ENGINE_SERVER = Boolean(process.env.ENGINE_SERVER);

// --- Test config --- //

/**
* Integration tests default to synthetic shadow mode, while hydration tests default to native.
* This should be set to "native" or "synthetic" to override the default mode.
* @type {'native'|'synthetic'|undefined}
*/
// NOTE: NATIVE_SHADOW is not defined here because integration/hydration have different defaults
export const SHADOW_MODE_OVERRIDE = process.env.SHADOW_MODE_OVERRIDE;

export const API_VERSION = process.env.API_VERSION
? parseInt(process.env.API_VERSION, 10)
: HIGHEST_API_VERSION;

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

export const NATIVE_SHADOW = DISABLE_SYNTHETIC || FORCE_NATIVE_SHADOW_MODE_FOR_TEST;

/** Unique directory name that encodes the flags that the tests were executed with. */
export const COVERAGE_DIR_FOR_OPTIONS =
Object.entries({
API_VERSION,
DISABLE_STATIC_CONTENT_OPTIMIZATION,
DISABLE_SYNTHETIC,
SHADOW_MODE_OVERRIDE,
DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER,
ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL,
FORCE_NATIVE_SHADOW_MODE_FOR_TEST,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default {
expect(child.shadowRoot.synthetic).toBeUndefined();

// sanity check that the env var is working
if (process.env.DISABLE_SYNTHETIC) {
if (process.env.NATIVE_SHADOW) {
expect(document.body.attachShadow.toString()).toContain('[native code');
} else {
expect(document.body.attachShadow.toString()).not.toContain('[native code');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@ beforeEach(() => {
document.body.appendChild(elm);
});

afterEach(() => {
document.body.removeChild(elm);
});

describe.runIf(
ENABLE_ELEMENT_INTERNALS_AND_FACE &&
process.env.NATIVE_SHADOW &&
Expand Down
Loading