@qoretechnologies/reqore 0.78.5-pr.708.gd1c403a → 0.78.5-pr.708.gfe16b52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +6 -0
- package/package.json +2 -2
- package/vitest.config.ts +87 -36
package/.claude/CLAUDE.md
CHANGED
|
@@ -184,6 +184,12 @@ release on npm.
|
|
|
184
184
|
- **Location:** `src/stories/` (e.g. `Collection.stories.tsx`).
|
|
185
185
|
- **Pattern:** ArgTypes for props, canvas controls, visual testing via Chromatic.
|
|
186
186
|
- **Command:** `yarn build-storybook` builds the static site.
|
|
187
|
+
- **Touch stories:** a story whose play calls `withTouchScreen` (`src/stories/utils/touchScreen.ts`)
|
|
188
|
+
carries `tags: ['touch']`. `yarn test:stories` runs those stories in their own Vitest project
|
|
189
|
+
(`storybook-touch`), and so their own browser page, after the others; an untagged one fails with
|
|
190
|
+
the reason. Chromium cannot give a page its mouse back after touch emulation: it takes the
|
|
191
|
+
machine's hover and pointer, and a Linux CI runner has no mouse, so every later story in the
|
|
192
|
+
same page would find `(hover: none)`. This never shows on a Mac, which always reports a mouse.
|
|
187
193
|
|
|
188
194
|
### Verifying a visual fix locally with Qlip — reqore mechanics
|
|
189
195
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qoretechnologies/reqore",
|
|
3
|
-
"version": "0.78.5-pr.708.
|
|
3
|
+
"version": "0.78.5-pr.708.gfe16b52",
|
|
4
4
|
"description": "ReQore is a highly theme-able and modular UI library for React",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"test": "vitest run --project unit",
|
|
17
17
|
"test:watch": "vitest --project unit",
|
|
18
18
|
"test:ci": "vitest run --project unit --reporter=json --outputFile=tests.json",
|
|
19
|
-
"test:stories": "vitest run --project storybook",
|
|
19
|
+
"test:stories": "vitest run --project storybook --project storybook-touch",
|
|
20
20
|
"precheck": "yarn run lint && yarn run test && yarn build:test:prod && yarn build:test",
|
|
21
21
|
"build": "./node_modules/typescript/bin/tsc --project tsconfig.prod.json",
|
|
22
22
|
"build:test": "./node_modules/typescript/bin/tsc --noEmit",
|
package/vitest.config.ts
CHANGED
|
@@ -1,14 +1,67 @@
|
|
|
1
1
|
import { qlipVitestPlugin } from '@qoretechnologies/qlip';
|
|
2
2
|
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
|
|
3
3
|
import { playwright } from '@vitest/browser-playwright';
|
|
4
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { defineConfig, mergeConfig } from 'vitest/config';
|
|
7
|
+
import { configDefaults, defineConfig, mergeConfig } from 'vitest/config';
|
|
7
8
|
import viteConfig from './vite.config';
|
|
8
9
|
|
|
9
10
|
const dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const qlipUploadToken = process.env.QLIP_UPLOAD_TOKEN;
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Story files with no story tagged `touch`, relative to the project root. The touch project leaves them out,
|
|
15
|
+
* so it does not load every story module only to skip it. Read from the files themselves: tagging a story
|
|
16
|
+
* is all it takes to run it on a touch screen.
|
|
17
|
+
*/
|
|
18
|
+
const storyFilesWithoutTouch = (): string[] =>
|
|
19
|
+
readdirSync(path.join(dirname, 'src'), { recursive: true, encoding: 'utf8' })
|
|
20
|
+
.filter((file) => file.endsWith('.stories.tsx'))
|
|
21
|
+
.map((file) => path.join('src', file).split(path.sep).join('/'))
|
|
22
|
+
.filter(
|
|
23
|
+
(file) =>
|
|
24
|
+
!/\btags:\s*\[[^\]]*['"]touch['"]/.test(readFileSync(path.join(dirname, file), 'utf8'))
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// One plugin for both story projects, so they make one qlip build: one build id, and one upload at the end
|
|
28
|
+
// of the run (the plugin registers its reporter once, however many projects load it).
|
|
29
|
+
const qlip = qlipVitestPlugin({
|
|
30
|
+
auto: true,
|
|
31
|
+
captureOnError: true,
|
|
32
|
+
disableAnimations: true,
|
|
33
|
+
pauseAnimationsAtEnd: true,
|
|
34
|
+
viewport: { width: 1920, height: 1080 },
|
|
35
|
+
// serverUrl omitted — defaults to https://qlip.qoretechnologies.com
|
|
36
|
+
...(qlipUploadToken ? { upload: { uploadToken: qlipUploadToken } } : {}),
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// A new object for each project: Vitest names a project's browser instances on the objects themselves.
|
|
40
|
+
const storyBrowser = () => ({
|
|
41
|
+
enabled: true,
|
|
42
|
+
// Vitest 4's @vitest/browser-playwright no longer applies
|
|
43
|
+
// `browser.viewport` to the Playwright context (the line is
|
|
44
|
+
// commented out in the provider), so the context silently falls
|
|
45
|
+
// back to Playwright's 1280×720 default and every capture is
|
|
46
|
+
// clamped to it — while the manifest still records qlip's
|
|
47
|
+
// 1920×1080, yielding blurry, mislabeled snapshots. Pass the
|
|
48
|
+
// viewport through the provider's `contextOptions` (which IS
|
|
49
|
+
// applied) so the browser window matches qlip's capture viewport
|
|
50
|
+
// 1:1 and screenshots come out at their true resolution.
|
|
51
|
+
provider: playwright({
|
|
52
|
+
contextOptions: { viewport: { width: 1920, height: 1080 } },
|
|
53
|
+
}),
|
|
54
|
+
headless: true,
|
|
55
|
+
instances: [{ browser: 'chromium' as const }],
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const storyTest = {
|
|
59
|
+
setupFiles: ['./.storybook/vitest.setup.ts'],
|
|
60
|
+
// Some interaction stories deliberately render slow content and the shared
|
|
61
|
+
// play-function helpers wait up to ~17s; give them headroom.
|
|
62
|
+
testTimeout: 30000,
|
|
63
|
+
};
|
|
64
|
+
|
|
12
65
|
export default mergeConfig(
|
|
13
66
|
viteConfig,
|
|
14
67
|
defineConfig({
|
|
@@ -16,52 +69,50 @@ export default mergeConfig(
|
|
|
16
69
|
projects: [
|
|
17
70
|
// Component/interaction tests: run every story in a real browser via Playwright.
|
|
18
71
|
// Replaces the former @storybook/test-runner.
|
|
72
|
+
//
|
|
73
|
+
// Stories run in two projects, and so in two browser pages. A story tagged `touch` holds the page as a
|
|
74
|
+
// phone (`withTouchScreen` in src/stories/utils/touchScreen.ts), and Chromium cannot hand that page back
|
|
75
|
+
// as it was: turning its touch emulation off takes the hover and pointer the machine reports, not the
|
|
76
|
+
// ones the browser was launched with. Playwright launches its headless Chromium as a mouse
|
|
77
|
+
// (`--blink-settings=primaryHoverType=2,…,primaryPointerType=4`); a Linux runner reports no mouse, so in
|
|
78
|
+
// CI every story after a touch story in the same page found `(hover: none)` - the hover-only actions
|
|
79
|
+
// shown, the Marquee and NavRail deaf to hover, Table's row menu at the touch size. On a Mac the machine
|
|
80
|
+
// reports a mouse, so the same run passes there.
|
|
19
81
|
{
|
|
20
82
|
extends: true,
|
|
21
83
|
plugins: [
|
|
22
|
-
|
|
23
|
-
auto: true,
|
|
24
|
-
captureOnError: true,
|
|
25
|
-
disableAnimations: true,
|
|
26
|
-
pauseAnimationsAtEnd: true,
|
|
27
|
-
viewport: { width: 1920, height: 1080 },
|
|
28
|
-
// serverUrl omitted — defaults to https://qlip.qoretechnologies.com
|
|
29
|
-
...(qlipUploadToken ? { upload: { uploadToken: qlipUploadToken } } : {}),
|
|
30
|
-
}),
|
|
84
|
+
qlip,
|
|
31
85
|
storybookTest({
|
|
32
86
|
configDir: path.join(dirname, '.storybook'),
|
|
33
87
|
storybookScript: 'yarn storybook --no-open',
|
|
88
|
+
tags: { exclude: ['touch'] },
|
|
34
89
|
}),
|
|
35
90
|
],
|
|
36
91
|
test: {
|
|
37
92
|
name: 'storybook',
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
93
|
+
browser: storyBrowser(),
|
|
94
|
+
...storyTest,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
// The stories tagged `touch`, in their own page, after the others (one file at a time: the touch
|
|
98
|
+
// screen and the narrowed frame belong to the page).
|
|
99
|
+
{
|
|
100
|
+
extends: true,
|
|
101
|
+
plugins: [
|
|
102
|
+
qlip,
|
|
103
|
+
storybookTest({
|
|
104
|
+
configDir: path.join(dirname, '.storybook'),
|
|
105
|
+
storybookScript: 'yarn storybook --no-open',
|
|
106
|
+
tags: { include: ['touch'] },
|
|
107
|
+
}),
|
|
108
|
+
],
|
|
109
|
+
test: {
|
|
110
|
+
name: 'storybook-touch',
|
|
111
|
+
exclude: [...configDefaults.exclude, ...storyFilesWithoutTouch()],
|
|
43
112
|
fileParallelism: false,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
// `browser.viewport` to the Playwright context (the line is
|
|
48
|
-
// commented out in the provider), so the context silently falls
|
|
49
|
-
// back to Playwright's 1280×720 default and every capture is
|
|
50
|
-
// clamped to it — while the manifest still records qlip's
|
|
51
|
-
// 1920×1080, yielding blurry, mislabeled snapshots. Pass the
|
|
52
|
-
// viewport through the provider's `contextOptions` (which IS
|
|
53
|
-
// applied) so the browser window matches qlip's capture viewport
|
|
54
|
-
// 1:1 and screenshots come out at their true resolution.
|
|
55
|
-
provider: playwright({
|
|
56
|
-
contextOptions: { viewport: { width: 1920, height: 1080 } },
|
|
57
|
-
}),
|
|
58
|
-
headless: true,
|
|
59
|
-
instances: [{ browser: 'chromium' }],
|
|
60
|
-
},
|
|
61
|
-
setupFiles: ['./.storybook/vitest.setup.ts'],
|
|
62
|
-
// Some interaction stories deliberately render slow content and the shared
|
|
63
|
-
// play-function helpers wait up to ~17s; give them headroom.
|
|
64
|
-
testTimeout: 30000,
|
|
113
|
+
sequence: { groupOrder: 1 },
|
|
114
|
+
browser: storyBrowser(),
|
|
115
|
+
...storyTest,
|
|
65
116
|
},
|
|
66
117
|
},
|
|
67
118
|
// Unit tests: the former Jest suite, now on Vitest + jsdom.
|