Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 0 additions & 1 deletion packages/@lwc/integration-not-karma/configs/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
10 changes: 1 addition & 9 deletions packages/@lwc/integration-not-karma/configs/hydration.js
Original file line number Diff line number Diff line change
Expand Up @@ -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],
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ 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) {
return content;
},
});

const ROOT_DIR = path.join(import.meta.dirname, '../..');

let guid = 0;
const COMPONENT_UNDER_TEST = 'main';

Expand Down Expand Up @@ -100,7 +99,7 @@ function throwOnUnexpectedConsoleCalls(runnable, expectedConsoleCalls = {}) {
};
}
try {
runnable();
return runnable();
Copy link
Contributor

Choose a reason for hiding this comment

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

🔔 TIL: even if we return in try catch, finally still gets executed

} finally {
Object.assign(console, originals);
}
Expand All @@ -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(
`(() => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The returned value when running a script is the result of the last statement of the script. Using an IIFE1 allows us to avoid mucking around with the context object.

1 Technically we can just do LWC.renderComponent() without wrapping it, but most people are probably unfamiliar with vm.Script. I think that using a more familiar pattern makes it more clear what's going on.

${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) {
Expand Down Expand Up @@ -178,52 +172,41 @@ 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));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

We don't need all the extra bundling when import(configFile) works just fine.


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
);

// FIXME: can we turn these IIFEs into ESM imports?
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);
Expand Down
5 changes: 0 additions & 5 deletions packages/@lwc/integration-not-karma/helpers/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
);
Expand All @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down