diff --git a/packages/dashboard/test/visual/lumo/dashboard.test.ts b/packages/dashboard/test/visual/lumo/dashboard.test.ts
new file mode 100644
index 0000000000..1b7a62acb1
--- /dev/null
+++ b/packages/dashboard/test/visual/lumo/dashboard.test.ts
@@ -0,0 +1,131 @@
+import { fixtureSync, nextFrame } from '@vaadin/testing-helpers';
+import { sendKeys } from '@web/test-runner-commands';
+import { visualDiff } from '@web/test-runner-visual-regression';
+import '../../../theme/lumo/vaadin-dashboard.js';
+import { html, render } from 'lit';
+import type { Dashboard } from '../../../src/vaadin-dashboard.js';
+import {
+ describeBidirectional,
+ fireDragStart,
+ fireResizeOver,
+ fireResizeStart,
+ getDraggable,
+ getElementFromCell,
+ getResizeHandle,
+} from '../../helpers.js';
+
+describe('dashboard', () => {
+ let focusElement: HTMLInputElement;
+ let element: Dashboard;
+ let div: HTMLDivElement;
+
+ beforeEach(() => {
+ div = document.createElement('div');
+
+ fixtureSync(`
+
+ `);
+
+ focusElement = fixtureSync(``);
+ focusElement.focus();
+ });
+
+ describeBidirectional(`widgets and section`, () => {
+ function getName(name: string) {
+ return `${document.dir || 'ltr'}-${name}`;
+ }
+
+ beforeEach(async () => {
+ element = fixtureSync(``, div);
+
+ element.renderer = (wrapper) => {
+ render(
+ html`
+ Header content
+ Content
+ `,
+ wrapper,
+ );
+ };
+
+ element.items = [
+ { title: 'Widget 1', colspan: 1 },
+ { title: 'Widget 2', colspan: 1 },
+ {
+ title: 'Section title',
+ items: [{ colspan: 1, rowspan: 1 }, { colspan: 1 }],
+ },
+ ];
+ await nextFrame();
+ });
+
+ it('default', async () => {
+ await visualDiff(div, getName('default'));
+ });
+
+ it('focused widget', async () => {
+ await sendKeys({ press: 'Tab' });
+ await visualDiff(div, getName('focused-widget'));
+ });
+
+ it('selected widget', async () => {
+ await sendKeys({ press: 'Tab' });
+ await sendKeys({ press: 'Enter' });
+ await visualDiff(div, getName('selected-widget'));
+ });
+
+ it('resize mode', async () => {
+ const firstWidget = getElementFromCell(element, 0, 0)!;
+ const resizeHandle = getResizeHandle(firstWidget) as HTMLElement;
+ resizeHandle.click();
+ await nextFrame();
+ await visualDiff(div, getName('resize-mode'));
+ });
+
+ it('move mode', async () => {
+ const firstWidget = getElementFromCell(element, 0, 0)!;
+ const moveHandle = getDraggable(firstWidget) as HTMLElement;
+ moveHandle.click();
+ await nextFrame();
+ await visualDiff(div, getName('move-mode'));
+ });
+
+ it('dragged widget', async () => {
+ fireDragStart(getElementFromCell(element, 0, 0)!);
+ await nextFrame();
+
+ await visualDiff(div, getName('dragged-widget'));
+ });
+
+ it('resized widget', async () => {
+ fireResizeStart(getElementFromCell(element, 0, 0)!);
+ await nextFrame();
+ fireResizeOver(getElementFromCell(element, 0, 0)!, 'end');
+ await nextFrame();
+
+ await visualDiff(div, getName('resized-widget'));
+ });
+
+ it('no gap', async () => {
+ element.style.setProperty('--vaadin-dashboard-gap', '0px');
+ await nextFrame();
+ await visualDiff(div, getName('no-gap'));
+ });
+
+ it('non-editable', async () => {
+ element.editable = false;
+ await visualDiff(div, getName('non-editable'));
+ });
+ });
+});
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-default.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-default.png
new file mode 100644
index 0000000000..63f87c0449
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-default.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-dragged-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-dragged-widget.png
new file mode 100644
index 0000000000..252af35c1d
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-dragged-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-focused-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-focused-widget.png
new file mode 100644
index 0000000000..19468dbcb9
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-focused-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-move-mode.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-move-mode.png
new file mode 100644
index 0000000000..4bdf917b17
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-move-mode.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-no-gap.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-no-gap.png
new file mode 100644
index 0000000000..fc341c36a4
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-no-gap.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-non-editable.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-non-editable.png
new file mode 100644
index 0000000000..a52b7bc614
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-non-editable.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resize-mode.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resize-mode.png
new file mode 100644
index 0000000000..f24f66578b
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resize-mode.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resized-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resized-widget.png
new file mode 100644
index 0000000000..d21e64c8b4
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-resized-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-selected-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-selected-widget.png
new file mode 100644
index 0000000000..fe6922ce57
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/ltr-selected-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-default.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-default.png
new file mode 100644
index 0000000000..2409de5a9f
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-default.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-dragged-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-dragged-widget.png
new file mode 100644
index 0000000000..8c1fe5b959
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-dragged-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-focused-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-focused-widget.png
new file mode 100644
index 0000000000..b43c320b2f
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-focused-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-move-mode.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-move-mode.png
new file mode 100644
index 0000000000..7636ba2107
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-move-mode.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-no-gap.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-no-gap.png
new file mode 100644
index 0000000000..52906303a6
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-no-gap.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-non-editable.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-non-editable.png
new file mode 100644
index 0000000000..36757ab20c
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-non-editable.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resize-mode.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resize-mode.png
new file mode 100644
index 0000000000..d509717a4f
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resize-mode.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resized-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resized-widget.png
new file mode 100644
index 0000000000..0afe421f60
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-resized-widget.png differ
diff --git a/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-selected-widget.png b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-selected-widget.png
new file mode 100644
index 0000000000..6e9edc16b2
Binary files /dev/null and b/packages/dashboard/test/visual/lumo/screenshots/dashboard/baseline/rtl-selected-widget.png differ
diff --git a/packages/dashboard/test/visual/material/dashboard.test.ts b/packages/dashboard/test/visual/material/dashboard.test.ts
new file mode 100644
index 0000000000..fd40e6bc9e
--- /dev/null
+++ b/packages/dashboard/test/visual/material/dashboard.test.ts
@@ -0,0 +1,3 @@
+describe('dashboard', () => {
+ // Dashboard has no material theme
+});
diff --git a/wtr-utils.js b/wtr-utils.js
index 86d579c029..931fe56aee 100644
--- a/wtr-utils.js
+++ b/wtr-utils.js
@@ -7,6 +7,7 @@ const glob = require('glob');
const { execSync } = require('child_process');
const { createSauceLabsLauncher } = require('@web/test-runner-saucelabs');
const { visualRegressionPlugin } = require('@web/test-runner-visual-regression/plugin');
+const { esbuildPlugin } = require('@web/dev-server-esbuild');
const HIDDEN_WARNINGS = [
' Unable to autoconfigure form because the data structure is unknown. Either specify `include` or ensure at least one item is available beforehand.',
@@ -206,7 +207,7 @@ const getScreenshotFileName = ({ name, testFile }, type, diff) => {
} else if (testFile.includes('icons')) {
folder = 'icons/test/visual/screenshots';
} else {
- const match = testFile.match(/\/packages\/(.+)\.test\.js/u);
+ const match = testFile.match(/\/packages\/(.+)\.test\.(js|ts)/u);
folder = match[1].replace(/(lumo|material)/u, '$1/screenshots');
}
return path.join(folder, type, diff ? `${name}-diff` : name);
@@ -327,6 +328,7 @@ const createVisualTestsConfig = (theme, browserVersion) => {
}),
],
plugins: [
+ esbuildPlugin({ ts: true }),
setWindowHeightPlugin(),
visualRegressionPlugin({
baseDir: 'packages',