Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: refine test setup #2560

Merged
merged 1 commit into from
Apr 8, 2024
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
5 changes: 1 addition & 4 deletions src/components/core/mixins/hydration-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,7 @@ const litElementHydrateSupport = 'litElementHydrateSupport';
* a production module.
* TODO: Should this be solved in a different way or removed in a production build?
*/
const hydrationSuppressed =
isServer ||
document.head.querySelector('meta[name="testGroup"]')?.getAttribute('content') ===
'e2e-ssr-non-hydrated';
const hydrationSuppressed = isServer || (globalThis as any).testGroup === 'e2e-ssr-non-hydrated';

/**
* This mixin extends a base class with functionality to check if hydration is completed.
Expand Down
17 changes: 5 additions & 12 deletions src/components/core/testing/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,30 @@ import { isServer } from 'lit';

/**
* This is a custom implementation.
* In the `web-test-runner.config` we add a meta tag with some useful meta-data
* In the `web-test-runner.config` we add data attributes to the body with additional information.
*/
export const isTestEnvironment = (): boolean =>
!isServer && !!document.head.querySelector('meta[name="testEnvironment"]');
export const isTestEnvironment = (): boolean => !isServer && 'testEnv' in globalThis;

/**
* This is a custom implementation.
* True if the `testEnvironment` meta tag has the `debug` attribute
*/
export const isDebugEnvironment = (): boolean =>
!isServer &&
isTestEnvironment() &&
!!document.head.querySelector('meta[name="testEnvironment"]')?.hasAttribute('debug');
!isServer && (globalThis as any).testEnv === 'debug';

/**
* This is a custom implementation.
* Returns true, if this is run in the SSR with hydration test group.
*/
export const isHydratedSsr = (): boolean =>
!isServer &&
document.head.querySelector('meta[name="testGroup"]')?.getAttribute('content') ===
'e2e-ssr-hydrated';
!isServer && (globalThis as any).testGroup === 'e2e-ssr-hydrated';

/**
* This is a custom implementation.
* Returns true, if this is run in the SSR without hydration test group.
*/
export const isNonHydratedSsr = (): boolean =>
!isServer &&
document.head.querySelector('meta[name="testGroup"]')?.getAttribute('content') ===
'e2e-ssr-non-hydrated';
!isServer && (globalThis as any).testGroup === 'e2e-ssr-non-hydrated';

/**
* This is a custom implementation.
Expand Down
4 changes: 2 additions & 2 deletions src/components/popover/popover/popover.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ describe(`sbb-popover with ${fixture.name}`, () => {
await sendMouse({
type: 'click',
position: [
interactiveElementPosition.x + interactiveElementPosition.width / 2,
interactiveElementPosition.y + interactiveElementPosition.height / 2,
Math.round(interactiveElementPosition.x + interactiveElementPosition.width / 2),
Math.round(interactiveElementPosition.y + interactiveElementPosition.height / 2),
],
});
await waitForCondition(() => didCloseEventSpy.events.length === 1);
Expand Down
19 changes: 10 additions & 9 deletions src/components/toast/toast.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,27 +150,28 @@ describe(`sbb-toast with ${fixture.name}`, () => {
});

it('closes other toasts on open', async () => {
const root = await fixture<SbbToastElement>(
html`<div>
<sbb-toast id="toast1" disable-animation></sbb-toast>
<sbb-toast id="toast2" disable-animation></sbb-toast>
</div>`,
element = await fixture<SbbToastElement>(
html`
<div>
<sbb-toast id="toast1" disable-animation></sbb-toast>
<sbb-toast id="toast2" disable-animation></sbb-toast>
</div>
`,
{ modules: ['./toast.ts'] },
);

const toast1 = root.querySelector('#toast1')! as SbbToastElement;
const toast2 = root.querySelector('#toast2')! as SbbToastElement;
const [toast1, toast2] = Array.from(element.querySelectorAll('sbb-toast'));

// Open the first toast
toast1.open();
await waitForLitRender(root);
await waitForLitRender(element);

await waitForCondition(() => toast1.getAttribute('data-state') === 'opened');
expect(toast1).to.have.attribute('data-state', 'opened');

// Open the second toast and expect the first to be closed
toast2.open();
await waitForLitRender(root);
await waitForLitRender(element);

await waitForCondition(() => toast1.getAttribute('data-state') === 'closed');
await waitForCondition(() => toast2.getAttribute('data-state') === 'opened');
Expand Down
11 changes: 6 additions & 5 deletions tools/web-test-runner/vite-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,20 @@ export function vitePlugin() {
// This configuration is necessary, as vite will otherwise detect dependencies
// that can be optimized. This will cause vite to reload, which leads to
// 'Could not import your test module.' errors, that happen randomly.
// Excluding the dependencies, prevents this from happening at the cost of slightly
// Disabling discovery prevents this from happening at the cost of slightly
// increased test times.
optimizeDeps: {
noDiscovery: true,
},
});
await viteServer.listen();

const vitePort = viteServer.config.server.port;
const viteProtocol = viteServer.config.server.https ? 'https' : 'http';

const baseUrl = `http${viteServer.config.server.https ? 's' : ''}://localhost:${viteServer.config.server.port}`;
app.use(async (ctx) => {
const response = await fetch(`${viteProtocol}://localhost:${vitePort}${ctx.originalUrl}`);
const url = baseUrl + ctx.originalUrl;
// Retry once on failure.
// This can happen when too many http requests are being handled by the operating system.
const response = await fetch(url).catch(() => Promise.resolve().then(() => fetch(url)));
ctx.set(Object.fromEntries(response.headers));
ctx.body = await response.text();
ctx.status = response.status;
Expand Down
26 changes: 17 additions & 9 deletions web-test-runner.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ const firefox = process.argv.includes('--firefox');
const webkit = process.argv.includes('--webkit');
const concurrency = process.argv.includes('--parallel') ? {} : { concurrency: 1 };

const globalCss = sass.compile('./src/components/core/styles/global.scss', {
loadPaths: ['.', './node_modules/'],
});
const stylesCompiler = new sass.initCompiler();
const renderStyles = () =>
stylesCompiler.compile('./src/components/core/styles/global.scss', {
loadPaths: ['.', './node_modules/'],
}).css;

const browsers = isCIEnvironment
? [
Expand Down Expand Up @@ -52,9 +54,11 @@ const testRunnerHtml = (testFramework, _config, group) => `
<!DOCTYPE html>
<html>
<head>
<meta name="testEnvironment" ${isDebugMode ? 'debug' : ''}>
<meta name="testGroup" content="${groupNameOverride ?? group?.name ?? 'default'}">
<style type="text/css">${globalCss.css}</style>
<style type="text/css">${renderStyles()}</style>
<script>
globalThis.testEnv = '${isDebugMode ? 'debug' : ''}';
globalThis.testGroup = '${groupNameOverride ?? group?.name ?? 'default'}';
</script>
</head>
<body>
<script type="module" src="/src/components/core/testing/test-setup.ts"></script>
Expand All @@ -70,6 +74,12 @@ function resolveConcurrency() {
return Math.floor(localCpus.length / factor);
}

// A list of log messages, that should not be printed to the test console.
const suppressedLogs = [
'Lit is in dev mode. Not recommended for production! See https://lit.dev/msg/dev-mode for more information.',
'[vite] connecting...',
];

/** @type {import('@web/test-runner').TestRunnerConfig} */
export default {
files: ['src/**/*.{e2e,spec}.ts'],
Expand All @@ -96,8 +106,6 @@ export default {
coverageConfig: {
exclude: ['**/node_modules/**/*', '**/assets/*.svg', '**/*.scss'],
},
filterBrowserLogs: (log) =>
log.args[0] !==
'Lit is in dev mode. Not recommended for production! See https://lit.dev/msg/dev-mode for more information.',
filterBrowserLogs: (log) => suppressedLogs.includes(log.args[0]),
testRunnerHtml,
};
Loading