diff --git a/packages/@lwc/integration-not-karma/configs/base.js b/packages/@lwc/integration-not-karma/configs/base.js index 4b08ac144f..ea4e4459ff 100644 --- a/packages/@lwc/integration-not-karma/configs/base.js +++ b/packages/@lwc/integration-not-karma/configs/base.js @@ -14,7 +14,6 @@ const env = { 'DISABLE_STATIC_CONTENT_OPTIMIZATION', 'DISABLE_SYNTHETIC', 'ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL', - 'ENABLE_SYNTHETIC_SHADOW_IN_HYDRATION', 'ENGINE_SERVER', 'FORCE_NATIVE_SHADOW_MODE_FOR_TEST', 'NATIVE_SHADOW', diff --git a/packages/@lwc/integration-not-karma/configs/hydration.js b/packages/@lwc/integration-not-karma/configs/hydration.js index 547844d317..67a2419850 100644 --- a/packages/@lwc/integration-not-karma/configs/hydration.js +++ b/packages/@lwc/integration-not-karma/configs/hydration.js @@ -6,14 +6,6 @@ import hydrationTestPlugin from './plugins/serve-hydration.js'; /** @type {import("@web/test-runner").TestRunnerConfig} */ export default { ...baseConfig, - files: [ - // FIXME: These tests are just symlinks to integration-karma for now so the git diff smaller - 'test-hydration/**/*.spec.js', - // FIXME: hits timeout? - '!test-hydration/light-dom/scoped-styles/replace-scoped-styles-with-dynamic-templates/index.spec.js', - // FIXME: This uses ENABLE_SYNTHETIC_SHADOW_IN_MIGRATION to detect status, - // we should just use DISABLE_SYNTHETIC instead - '!test-hydration/synthetic-shadow/index.spec.js', - ], + files: ['test-hydration/**/*.spec.js'], plugins: [...baseConfig.plugins, hydrationTestPlugin], }; diff --git a/packages/@lwc/integration-not-karma/configs/plugins/serve-hydration.js b/packages/@lwc/integration-not-karma/configs/plugins/serve-hydration.js index ebb724d9a2..1e495f3033 100644 --- a/packages/@lwc/integration-not-karma/configs/plugins/serve-hydration.js +++ b/packages/@lwc/integration-not-karma/configs/plugins/serve-hydration.js @@ -4,14 +4,11 @@ import fs from 'node:fs/promises'; import { rollup } from 'rollup'; import lwcRollupPlugin from '@lwc/rollup-plugin'; import { DISABLE_STATIC_CONTENT_OPTIMIZATION, ENGINE_SERVER } from '../../helpers/options.js'; -const lwcSsr = await (ENGINE_SERVER ? import('@lwc/engine-server') : import('@lwc/ssr-runtime')); - -const ROOT_DIR = path.join(import.meta.dirname, '../..'); - -const context = { - LWC: lwcSsr, - moduleOutput: null, -}; +/** LWC SSR module to use when server-side rendering components. */ +const lwcSsr = await (ENGINE_SERVER + ? // Using import('literal') rather than import(variable) so static analysis tools work + import('@lwc/engine-server') + : import('@lwc/ssr-runtime')); lwcSsr.setHooks({ sanitizeHtmlContent(content) { @@ -19,6 +16,8 @@ lwcSsr.setHooks({ }, }); +const ROOT_DIR = path.join(import.meta.dirname, '../..'); + let guid = 0; const COMPONENT_UNDER_TEST = 'main'; @@ -100,7 +99,7 @@ function throwOnUnexpectedConsoleCalls(runnable, expectedConsoleCalls = {}) { }; } try { - runnable(); + return runnable(); } finally { Object.assign(console, originals); } @@ -117,31 +116,26 @@ function throwOnUnexpectedConsoleCalls(runnable, expectedConsoleCalls = {}) { * So, script runs, generates markup, & we get that markup out and return it for use * in client-side tests. */ -async function getSsrCode(moduleCode, testConfig, filename, expectedSSRConsoleCalls) { +async function getSsrCode(moduleCode, testConfig, filePath, expectedSSRConsoleCalls) { const script = new vm.Script( - // FIXME: Can these IIFEs be converted to ESM imports? - // No, vm.Script doesn't support that. But might be doable with experimental vm.Module - ` - ${testConfig}; - config = config || {}; - ${moduleCode}; - moduleOutput = LWC.renderComponent( + `(() => { + ${testConfig} + ${moduleCode} + return LWC.renderComponent( 'x-${COMPONENT_UNDER_TEST}-${guid++}', Main, config.props || {}, false, 'sync' ); - `, - { filename } + })()`, + { filename: `[SSR] ${filePath}` } ); - throwOnUnexpectedConsoleCalls(() => { - vm.createContext(context); - script.runInContext(context); - }, expectedSSRConsoleCalls); - - return await context.moduleOutput; + return throwOnUnexpectedConsoleCalls( + () => script.runInContext(vm.createContext({ LWC: lwcSsr })), + expectedSSRConsoleCalls + ); } async function getTestConfig(input) { @@ -178,37 +172,27 @@ async function existsUp(dir, file) { * This function wraps those configs in the test code to be executed. */ async function wrapHydrationTest(filePath) { - const suiteDir = path.dirname(filePath); - - // Wrap all the tests into a describe block with the file stricture name - const describeTitle = path.relative(ROOT_DIR, suiteDir).split(path.sep).join(' '); - - const testCode = await getTestConfig(filePath); - - // Create a temporary module to evaluate the bundled code and extract config properties for test configuration - const configModule = new vm.Script(testCode); - const configContext = { config: {} }; - vm.createContext(configContext); - configModule.runInContext(configContext); - const { expectedSSRConsoleCalls, requiredFeatureFlags } = configContext.config; - - requiredFeatureFlags?.forEach((featureFlag) => { - lwcSsr.setFeatureFlagForTest(featureFlag, true); - }); + const { + default: { expectedSSRConsoleCalls, requiredFeatureFlags }, + } = await import(path.join(ROOT_DIR, filePath)); try { + requiredFeatureFlags?.forEach((featureFlag) => { + lwcSsr.setFeatureFlagForTest(featureFlag, true); + }); + + const suiteDir = path.dirname(filePath); // You can add an `.only` file alongside an `index.spec.js` file to make it `fdescribe()` const onlyFileExists = await existsUp(suiteDir, '.only'); - const describeFn = onlyFileExists ? 'describe.only' : 'describe'; const componentDefCSR = await getCompiledModule(suiteDir, false); const componentDefSSR = ENGINE_SERVER ? componentDefCSR : await getCompiledModule(suiteDir, true); const ssrOutput = await getSsrCode( componentDefSSR, - testCode, - path.join(suiteDir, 'ssr.js'), + await getTestConfig(filePath), + filePath, expectedSSRConsoleCalls ); @@ -216,14 +200,13 @@ async function wrapHydrationTest(filePath) { return ` import { runTest } from '/helpers/test-hydrate.js'; import config from '/${filePath}?original=1'; - ${describeFn}("${describeTitle}", () => { - it('test', async () => { - const ssrRendered = ${JSON.stringify(ssrOutput) /* escape quotes */}; - // Component code, IIFE set as Main - ${componentDefCSR}; - return await runTest(ssrRendered, Main, config); - }) - });`; + ${onlyFileExists ? 'it.only' : 'it'}('${filePath}', async () => { + const ssrRendered = ${JSON.stringify(ssrOutput) /* escape quotes */}; + // Component code, IIFE set as Main + ${componentDefCSR}; + return await runTest(ssrRendered, Main, config); + }); + `; } finally { requiredFeatureFlags?.forEach((featureFlag) => { lwcSsr.setFeatureFlagForTest(featureFlag, false); diff --git a/packages/@lwc/integration-not-karma/helpers/options.js b/packages/@lwc/integration-not-karma/helpers/options.js index a18ae6df4a..477f534963 100644 --- a/packages/@lwc/integration-not-karma/helpers/options.js +++ b/packages/@lwc/integration-not-karma/helpers/options.js @@ -26,10 +26,6 @@ export const DISABLE_STATIC_CONTENT_OPTIMIZATION = Boolean( process.env.DISABLE_STATIC_CONTENT_OPTIMIZATION ); -export const ENABLE_SYNTHETIC_SHADOW_IN_HYDRATION = Boolean( - process.env.ENABLE_SYNTHETIC_SHADOW_IN_HYDRATION -); - export const DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE = Boolean( process.env.DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE ); @@ -56,7 +52,6 @@ export const COVERAGE_DIR_FOR_OPTIONS = DISABLE_SYNTHETIC, DISABLE_SYNTHETIC_SHADOW_SUPPORT_IN_COMPILER, ENABLE_ARIA_REFLECTION_GLOBAL_POLYFILL, - ENABLE_SYNTHETIC_SHADOW_IN_HYDRATION, FORCE_NATIVE_SHADOW_MODE_FOR_TEST, LEGACY_BROWSERS, NODE_ENV_FOR_TEST, diff --git a/packages/@lwc/integration-not-karma/test-hydration/synthetic-shadow/index.spec.js b/packages/@lwc/integration-not-karma/test-hydration/synthetic-shadow/index.spec.js index 24177ac54f..7932c8bf9e 100644 --- a/packages/@lwc/integration-not-karma/test-hydration/synthetic-shadow/index.spec.js +++ b/packages/@lwc/integration-not-karma/test-hydration/synthetic-shadow/index.spec.js @@ -22,10 +22,10 @@ export default { expect(child.shadowRoot.synthetic).toBeUndefined(); // sanity check that the env var is working - if (process.env.ENABLE_SYNTHETIC_SHADOW_IN_HYDRATION) { - expect(document.body.attachShadow.toString()).not.toContain('[native code'); - } else { + if (process.env.DISABLE_SYNTHETIC) { expect(document.body.attachShadow.toString()).toContain('[native code'); + } else { + expect(document.body.attachShadow.toString()).not.toContain('[native code'); } expect(consoleCalls.warn).toHaveSize(0);