@public-ui/visual-tests 1.7.0-rc.8 → 1.7.0-rc.9
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/README.md +23 -144
- package/package.json +2 -2
- package/playwright.config.js +59 -0
- package/src/index.js +53 -0
- package/tests/sample-app.routes.js +80 -0
- package/tests/theme-snapshots.spec.js +47 -0
- package/src/index.ts +0 -33
- package/src/migrate/index.ts +0 -127
- package/src/migrate/runner/abstract-task.ts +0 -64
- package/src/migrate/runner/task-runner.ts +0 -163
- package/src/migrate/runner/tasks/common/GenericRenamePropertyTask.ts +0 -85
- package/src/migrate/runner/tasks/common/LabelExpertSlot.ts +0 -96
- package/src/migrate/runner/tasks/common/RemovePropertyNameTask.ts +0 -104
- package/src/migrate/runner/tasks/common/RenamePropertyNameTask.ts +0 -31
- package/src/migrate/runner/tasks/test/index.ts +0 -16
- package/src/migrate/runner/tasks/test/test-dummy.ts +0 -20
- package/src/migrate/runner/tasks/test/test-version-1.3.ts +0 -7
- package/src/migrate/runner/tasks/test/test-version-current.ts +0 -7
- package/src/migrate/runner/tasks/test/test-version-next-2.ts +0 -7
- package/src/migrate/runner/tasks/test/test-version-next-3.ts +0 -7
- package/src/migrate/runner/tasks/test/test-version-zero.ts +0 -7
- package/src/migrate/runner/tasks/v1/abbr.ts +0 -3
- package/src/migrate/runner/tasks/v1/accordion.ts +0 -3
- package/src/migrate/runner/tasks/v1/badge.ts +0 -6
- package/src/migrate/runner/tasks/v1/breadcrumb.ts +0 -3
- package/src/migrate/runner/tasks/v1/button-link.ts +0 -6
- package/src/migrate/runner/tasks/v1/button.ts +0 -8
- package/src/migrate/runner/tasks/v1/card.ts +0 -4
- package/src/migrate/runner/tasks/v1/details.ts +0 -3
- package/src/migrate/runner/tasks/v1/icon.ts +0 -5
- package/src/migrate/runner/tasks/v1/index.ts +0 -151
- package/src/migrate/runner/tasks/v1/input-checkbox.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-color.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-date.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-email.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-number.ts +0 -4
- package/src/migrate/runner/tasks/v1/input-radio.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-range.ts +0 -3
- package/src/migrate/runner/tasks/v1/input-text.ts +0 -3
- package/src/migrate/runner/tasks/v1/link-button.ts +0 -15
- package/src/migrate/runner/tasks/v1/link-group.ts +0 -7
- package/src/migrate/runner/tasks/v1/link.ts +0 -15
- package/src/migrate/runner/tasks/v1/logo.ts +0 -3
- package/src/migrate/runner/tasks/v1/modal.ts +0 -3
- package/src/migrate/runner/tasks/v1/nav.ts +0 -7
- package/src/migrate/runner/tasks/v1/pagination.ts +0 -3
- package/src/migrate/runner/tasks/v1/progress.ts +0 -3
- package/src/migrate/runner/tasks/v1/quote.ts +0 -3
- package/src/migrate/runner/tasks/v1/select.ts +0 -4
- package/src/migrate/runner/tasks/v1/skip-nav.ts +0 -3
- package/src/migrate/runner/tasks/v1/span.ts +0 -3
- package/src/migrate/runner/tasks/v1/split-button.ts +0 -3
- package/src/migrate/runner/tasks/v1/table.ts +0 -3
- package/src/migrate/runner/tasks/v1/tabs.ts +0 -4
- package/src/migrate/runner/tasks/v1/toast.ts +0 -3
- package/src/migrate/runner/tasks/v1/version.ts +0 -3
- package/src/migrate/runner/types.ts +0 -2
- package/src/migrate/shares/reuse.ts +0 -182
- package/src/migrate/types.ts +0 -2
- package/src/types.ts +0 -23
package/README.md
CHANGED
|
@@ -1,168 +1,47 @@
|
|
|
1
|
-
# KoliBri -
|
|
1
|
+
# KoliBri - Visual Tests
|
|
2
2
|
|
|
3
3
|
## Motivation
|
|
4
4
|
|
|
5
|
-
The `KoliBri`
|
|
5
|
+
The `KoliBri` Visual Tests provide a way to add visual regression testing to **theme** modules.
|
|
6
|
+
It takes screenshots of every component defined in the [React Sample App](https://github.com/public-ui/kolibri/tree/develop/packages/samples/react) with the theme applied and compares them to their references.
|
|
6
7
|
|
|
7
8
|
## Installation
|
|
8
9
|
|
|
9
|
-
You can install the `KoliBri`
|
|
10
|
+
You can install the `KoliBri` Visual Tests with `npm`, `pnpm` or `yarn`:
|
|
10
11
|
|
|
11
12
|
```bash
|
|
12
|
-
npm i -
|
|
13
|
-
pnpm i -
|
|
14
|
-
yarn add -
|
|
13
|
+
npm i -D @public-ui/visual-tests
|
|
14
|
+
pnpm i -D @public-ui/visual-tests
|
|
15
|
+
yarn add -D @public-ui/visual-tests
|
|
15
16
|
```
|
|
16
17
|
|
|
17
18
|
## Usage
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
Add the following npm scripts to the theme's `package.json`:
|
|
20
21
|
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
| . ' | .-. | | | ,--. | .-. \ | .--' ,--.
|
|
29
|
-
| |\ \ | '-' | | | | | | '--' / | | | |
|
|
30
|
-
`--' `--´ `---´ `--' `--' `------´ `--' `--'
|
|
31
|
-
🚹 The accessible HTML-Standard | 👉 https://public-ui.github.io
|
|
32
|
-
|
|
33
|
-
Usage: kolibri [options] [command]
|
|
34
|
-
|
|
35
|
-
CLI for executing some helpful commands for KoliBri projects.
|
|
36
|
-
|
|
37
|
-
Options:
|
|
38
|
-
-V, --version output the version number
|
|
39
|
-
-h, --help display help for command
|
|
40
|
-
|
|
41
|
-
Commands:
|
|
42
|
-
migrate [options] <string> This command migrates KoliBri code to the current version.
|
|
43
|
-
help [command] display help for command
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Migrate
|
|
47
|
-
|
|
48
|
-
With the `migrate` command you can migrate your project to the latest version of `KoliBri`.
|
|
49
|
-
|
|
50
|
-
Actually the following migrations are available:
|
|
51
|
-
|
|
52
|
-
- Component renaming ✓
|
|
53
|
-
- Component removal ⏰
|
|
54
|
-
- Property renaming ✓
|
|
55
|
-
- Property removal ✓
|
|
56
|
-
- Property type change ⏰
|
|
57
|
-
- Logic refactoring ⏰
|
|
58
|
-
- Expert-Slot refactoring ⏰
|
|
59
|
-
- `.vscode/settings.json` add IntelliSense for HTML ⏰
|
|
60
|
-
- `.gitignore` exclude `.kolibri.migrate.json` ⏰
|
|
61
|
-
- `.tsconfig` add `@public-ui/components` to `types` array ⏰
|
|
62
|
-
|
|
63
|
-
#### How does it work?
|
|
64
|
-
|
|
65
|
-
1. The migration command will check your project for clear `git history` and the `installed version` of `KoliBri`. Now it loads all available migration tasks.
|
|
66
|
-
2. Tasks in the correct version range will be executed one by one. Otherwise they will be skipped.
|
|
67
|
-
3. After that the `package.json` will be updated with the new version of `KoliBri` and execute the `npm install` command.
|
|
68
|
-
4. If there are any pending tasks, the migration command will be executed again. Otherwise the migration is finished.
|
|
69
|
-
5. Now you can check the result and commit the changes.
|
|
70
|
-
|
|
71
|
-
> **Note:** You can reset the migration with `git reset --hard HEAD~1` or by discarding the affected files.
|
|
72
|
-
|
|
73
|
-
#### Help
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
kolibri migrate --help
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
#### Execute
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
kolibri migrate <path>
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"scripts": {
|
|
25
|
+
"test": "THEME_MODULE=src/index THEME_EXPORT=THEME_NAME kolibri-visual-test",
|
|
26
|
+
"test-update": "THEME_MODULE=src/index THEME_EXPORT=THEME_NAME kolibri-visual-test --update-snapshots"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
83
29
|
```
|
|
84
30
|
|
|
85
|
-
|
|
31
|
+
- `THEME_MODULE` defines the relative path to the TypeScript module containing the the theme definitions. Without file extension.
|
|
32
|
+
- `THEME_EXPERT` defines the name of the export within the the module. (e.g., `export const THEME_NAME = {/**/};`) Defaults to `default`.
|
|
86
33
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
| `--ignore-uncommitted-changes` | Allows execution with uncommitted changes | boolean | false |
|
|
90
|
-
| `--remove-mode` | Prefix property name or delete property | `delete` \| `prefix` | `prefix` |
|
|
34
|
+
Run the tests with `npm test`. The first time, this will create a new folder `snapshots` which is supposed to be committed to the repository.
|
|
35
|
+
In the following runs, new screenshots will be compared to this reference.
|
|
91
36
|
|
|
92
|
-
|
|
37
|
+
To update the reference screenshots call `npm run test-update`.
|
|
93
38
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
**Troubleshooting:** If you have problems with migration, you can exclude some tasks with the configuration by setting the `false` flag (see `kol-select`).
|
|
39
|
+
It's also recommended to automatically run the tests before packing/publishing the module:
|
|
97
40
|
|
|
98
41
|
```json
|
|
99
42
|
{
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"kol-abbr-rename-property-_title-to-_label": true,
|
|
103
|
-
"kol-accordion-rename-property-_heading-to-_label": true,
|
|
104
|
-
"kol-badge-rename-property-_icon-only-to-_hide-label": true,
|
|
105
|
-
"kol-badge-remove-property-_hide-label": true,
|
|
106
|
-
"kol-badge-remove-property-_icon-only": true,
|
|
107
|
-
"kol-breadcrumb-rename-property-_aria-label-to-_label": true,
|
|
108
|
-
"kol-button-link-remove-property-_aria-current": true,
|
|
109
|
-
"kol-button-link-remove-property-_aria-label": true,
|
|
110
|
-
"kol-button-link-rename-property-_icon-only-to-_hide-label": true,
|
|
111
|
-
"kol-button-remove-property-_aria-current": true,
|
|
112
|
-
"kol-button-remove-property-_aria-label": true,
|
|
113
|
-
"kol-button-rename-property-_icon-only-to-_hide-label": true,
|
|
114
|
-
"kol-card-rename-property-_heading-to-_label": true,
|
|
115
|
-
"kol-card-rename-property-_headline-to-_label": true,
|
|
116
|
-
"kol-details-rename-property-_summary-to-_label": true,
|
|
117
|
-
"kol-icon-remove-property-_part": true,
|
|
118
|
-
"kol-icon-rename-property-_aria-label-to-_label": true,
|
|
119
|
-
"kol-checkbox-rename-property-_type-to-_variant": true,
|
|
120
|
-
"kol-color-rename-property-_list-to-_suggestions": true,
|
|
121
|
-
"kol-date-rename-property-_list-to-_suggestions": true,
|
|
122
|
-
"kol-input-email-rename-property-_list-to-_suggestions": true,
|
|
123
|
-
"kol-input-number-rename-property-_list-to-_suggestions": true,
|
|
124
|
-
"kol-input-radio-rename-property-_list-to-_options": true,
|
|
125
|
-
"kol-input-range-rename-property-_list-to-_suggestions": true,
|
|
126
|
-
"kol-input-text-rename-property-_list-to-_suggestions": true,
|
|
127
|
-
"kol-link-group-rename-property-_aria-label-to-_label": true,
|
|
128
|
-
"kol-link-group-remove-property-_ordered": true,
|
|
129
|
-
"kol-nav-rename-property-_aria-label-to-_label": true,
|
|
130
|
-
"kol-nav-rename-property-_compact-to-_hide-label": true,
|
|
131
|
-
"kol-nav-remove-property-_has-compact-button": true,
|
|
132
|
-
"kol-pagination-rename-property-_count-to-_total": true,
|
|
133
|
-
"kol-progress-rename-property-_type-to-_variant": true,
|
|
134
|
-
"kol-quote-rename-property-_caption-to-_label": true,
|
|
135
|
-
"kol-select-rename-property-_height-to-_rows": false,
|
|
136
|
-
"kol-select-rename-property-_list-to-_options": false,
|
|
137
|
-
"kol-skip-nav-rename-property-_aria-label-to-_label": true,
|
|
138
|
-
"kol-span-rename-property-_icon-only-to-_hide-label": true,
|
|
139
|
-
"kol-split-button-remove-property-_aria-label": true,
|
|
140
|
-
"kol-table-rename-property-_caption-to-_label": true,
|
|
141
|
-
"kol-tabs-rename-property-_aria-label-to-_label": true,
|
|
142
|
-
"kol-tabs-rename-property-_tab-align-to-_align": true,
|
|
143
|
-
"kol-toast-rename-property-_heading-to-_label": true,
|
|
144
|
-
"kol-version-rename-property-_version-to-_label": true
|
|
145
|
-
}
|
|
43
|
+
"scripts": {
|
|
44
|
+
"prepack": "npm test"
|
|
146
45
|
}
|
|
147
46
|
}
|
|
148
47
|
```
|
|
149
|
-
|
|
150
|
-
## Troubleshooting
|
|
151
|
-
|
|
152
|
-
If the migration failed, you can reset the migration with `git reset --hard HEAD~1`.
|
|
153
|
-
|
|
154
|
-
Use the configuration (`.kolibri.config.json`) to exclude some tasks.
|
|
155
|
-
|
|
156
|
-
If there are multiple obsolete properties that have been migrated to just one new property, the new property may appear multiple times in the tag. You can then decide which variant to use and remove all other variants accordingly.
|
|
157
|
-
|
|
158
|
-
Maybe it can help to prepare your code in the tricky places for migration.
|
|
159
|
-
|
|
160
|
-
Please give us feedback, if you have problems with the migration: [GitHub Issues](https://github.com/public-ui/kolibri/issues/new?assignees=&labels=useful+hint&projects=&template=7_feedback.md&title=%F0%9F%92%A1+CLI%3A+)
|
|
161
|
-
|
|
162
|
-
## Dry run
|
|
163
|
-
|
|
164
|
-
You have always the possibility of a dry run. Because before the migration will be executed, you need a clean git history of you project.
|
|
165
|
-
|
|
166
|
-
After the migration you can check the result with `git status` and `git diff`.
|
|
167
|
-
|
|
168
|
-
Is anything wrong, you can reset the migration with `git reset --hard HEAD~1` or by discarding the affected files.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@public-ui/visual-tests",
|
|
3
|
-
"version": "1.7.0-rc.
|
|
3
|
+
"version": "1.7.0-rc.9",
|
|
4
4
|
"license": "EUPL-1.2",
|
|
5
5
|
"homepage": "https://public-ui.github.io",
|
|
6
6
|
"repository": "https://github.com/public-ui/kolibri",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@playwright/test": "1.37.1",
|
|
29
|
-
"@public-ui/sample-react": "1.7.0-rc.
|
|
29
|
+
"@public-ui/sample-react": "1.7.0-rc.9",
|
|
30
30
|
"http-server": "14.1.1",
|
|
31
31
|
"portfinder": "1.0.32"
|
|
32
32
|
},
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { defineConfig, devices } from '@playwright/test';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as process from 'process';
|
|
4
|
+
|
|
5
|
+
const PORT = Number(process.env.KOLIBRI_VISUAL_TEST_PORT);
|
|
6
|
+
const URL = `http://127.0.0.1:${PORT}`;
|
|
7
|
+
|
|
8
|
+
console.log('Serving React Sample app:', URL);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* See https://playwright.dev/docs/test-configuration.
|
|
12
|
+
*/
|
|
13
|
+
export default defineConfig({
|
|
14
|
+
testDir: './tests',
|
|
15
|
+
snapshotDir: path.join(process.env.KOLIBRI_CWD, 'snapshots'),
|
|
16
|
+
// snapshotPathTemplate: '',
|
|
17
|
+
outputDir: path.join(process.env.KOLIBRI_CWD, 'test-results'),
|
|
18
|
+
/* Run tests in files in parallel */
|
|
19
|
+
fullyParallel: true,
|
|
20
|
+
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
|
21
|
+
forbidOnly: !!process.env.CI,
|
|
22
|
+
/* Retry on CI only */
|
|
23
|
+
retries: 0, // process.env.CI ? 2 : 0,
|
|
24
|
+
/* Opt out of parallel tests on CI. */
|
|
25
|
+
workers: process.env.CI ? 1 : undefined,
|
|
26
|
+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
|
27
|
+
reporter: 'line',
|
|
28
|
+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
|
29
|
+
use: {
|
|
30
|
+
/* Base URL to use in actions like `await page.goto('/')`. */
|
|
31
|
+
baseURL: URL,
|
|
32
|
+
|
|
33
|
+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
|
34
|
+
trace: 'on-first-retry',
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
/* Configure projects for major browsers */
|
|
38
|
+
projects: [
|
|
39
|
+
// {
|
|
40
|
+
// name: 'chrome',
|
|
41
|
+
// use: { ...devices['Desktop Chrome'] },
|
|
42
|
+
// },
|
|
43
|
+
// {
|
|
44
|
+
// name: 'edge',
|
|
45
|
+
// use: { ...devices['Desktop Edge'] },
|
|
46
|
+
// },
|
|
47
|
+
{
|
|
48
|
+
name: 'firefox',
|
|
49
|
+
use: { ...devices['Desktop Firefox'] },
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
|
|
53
|
+
/* Run your local dev server before starting the tests */
|
|
54
|
+
webServer: {
|
|
55
|
+
command: `http-server ${process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH} -p ${PORT}`,
|
|
56
|
+
url: URL,
|
|
57
|
+
reuseExistingServer: false,
|
|
58
|
+
},
|
|
59
|
+
});
|
package/src/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import child_process from 'node:child_process';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import * as crypto from 'crypto';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import portfinder from 'portfinder';
|
|
7
|
+
import * as process from 'process';
|
|
8
|
+
|
|
9
|
+
process.env.KOLIBRI_CWD = process.cwd();
|
|
10
|
+
const tempDir = process.env.RUNNER_TEMP || process.env.TMPDIR; // TODO: Check on Windows
|
|
11
|
+
|
|
12
|
+
if (!process.env.THEME_MODULE) {
|
|
13
|
+
throw new Error('Environment variable THEME_MODULE not specified.');
|
|
14
|
+
}
|
|
15
|
+
if (!tempDir) {
|
|
16
|
+
throw new Error('Neither environment variable RUNNER_TEMP or TMPDIR specified.');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
process.env.THEME_MODULE = path.join(process.cwd(), process.env.THEME_MODULE); // Use current working directory (i.e. the theme folder) to complete module path
|
|
20
|
+
const visualsTestModulePath = fileURLToPath(new URL('..', import.meta.url));
|
|
21
|
+
const binaryPath = fileURLToPath(new URL('../node_modules/.bin', import.meta.url));
|
|
22
|
+
const buildPath = path.join(tempDir, `kolibri-visual-testing-build-${crypto.randomUUID()}`);
|
|
23
|
+
process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH = buildPath;
|
|
24
|
+
|
|
25
|
+
console.log('Building React Sample App …');
|
|
26
|
+
child_process.execFileSync(path.join(binaryPath, 'kolibri-sample-react-test-build'), [buildPath], {
|
|
27
|
+
encoding: 'utf-8',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
console.log(`React Sample App build finished. Directory:`, buildPath);
|
|
31
|
+
|
|
32
|
+
void (async () => {
|
|
33
|
+
process.env.KOLIBRI_VISUAL_TEST_PORT = String(await portfinder.getPortPromise());
|
|
34
|
+
|
|
35
|
+
const playwright = child_process.spawn(path.join(binaryPath, 'playwright'), ['test', ...process.argv.slice(2)], {
|
|
36
|
+
cwd: visualsTestModulePath,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
playwright.stdout.on('data', (data) => {
|
|
40
|
+
console.log('Playwright: ' + data.toString());
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
playwright.stderr.on('data', (data) => {
|
|
44
|
+
console.log('Playwright stderr: ' + data.toString());
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
playwright.on('exit', (code) => {
|
|
48
|
+
console.log(`Playwright test finished with exit code ${code}.`);
|
|
49
|
+
console.log('Cleaning up build folder …');
|
|
50
|
+
fs.rmSync(buildPath, { recursive: true, force: true });
|
|
51
|
+
process.exit(code ?? 1);
|
|
52
|
+
});
|
|
53
|
+
})();
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export const ROUTES = [
|
|
2
|
+
'/handout/basic',
|
|
3
|
+
'/abbr/basic',
|
|
4
|
+
'/accordion/basic',
|
|
5
|
+
'/accordion/header',
|
|
6
|
+
'/accordion/headlines',
|
|
7
|
+
'/accordion/list',
|
|
8
|
+
'/alert/basic',
|
|
9
|
+
'/alert/card-msg',
|
|
10
|
+
'/alert/html',
|
|
11
|
+
'/avatar/basic',
|
|
12
|
+
'/badge/basic',
|
|
13
|
+
'/badge/button',
|
|
14
|
+
'/breadcrumb/basic',
|
|
15
|
+
'/button/basic',
|
|
16
|
+
'/button/hide-label',
|
|
17
|
+
'/button/icons',
|
|
18
|
+
'/button/width',
|
|
19
|
+
'/button-link/basic',
|
|
20
|
+
'/button-link/icons',
|
|
21
|
+
'/button-link/image',
|
|
22
|
+
'/button-link/target',
|
|
23
|
+
'/button-group/basic',
|
|
24
|
+
'/card/basic',
|
|
25
|
+
'/card/confirm',
|
|
26
|
+
'/card/flex',
|
|
27
|
+
'/card/selection',
|
|
28
|
+
'/details/basic',
|
|
29
|
+
'/heading/badge',
|
|
30
|
+
'/heading/basic',
|
|
31
|
+
'/heading/paragraph',
|
|
32
|
+
'/icon/basic',
|
|
33
|
+
'/indented-text/basic',
|
|
34
|
+
'/input-checkbox/basic',
|
|
35
|
+
'/input-color/basic',
|
|
36
|
+
'/input-date/basic',
|
|
37
|
+
'/input-email/basic',
|
|
38
|
+
'/input-file/basic',
|
|
39
|
+
'/input-number/basic',
|
|
40
|
+
'/input-password/basic',
|
|
41
|
+
'/input-password/show-password',
|
|
42
|
+
'/input-radio/basic',
|
|
43
|
+
'/input-radio/horizontal',
|
|
44
|
+
'/input-radio/select',
|
|
45
|
+
'/input-range/basic',
|
|
46
|
+
'/input-text/basic',
|
|
47
|
+
'/input-text/hidden-label',
|
|
48
|
+
'/input-text/blur',
|
|
49
|
+
'/input-text/focus',
|
|
50
|
+
'/link/basic',
|
|
51
|
+
'/link/icons',
|
|
52
|
+
'/link/image',
|
|
53
|
+
'/link/target',
|
|
54
|
+
'/link-button/basic',
|
|
55
|
+
'/nav/basic',
|
|
56
|
+
'/nav/active',
|
|
57
|
+
'/nav/aria-current',
|
|
58
|
+
'/nav/horizontal',
|
|
59
|
+
'/pagination/basic',
|
|
60
|
+
'/popover/basic',
|
|
61
|
+
'/progress/basic',
|
|
62
|
+
'/select/basic',
|
|
63
|
+
'/skip-nav/basic',
|
|
64
|
+
'/spin/basic',
|
|
65
|
+
'/spin/cycle',
|
|
66
|
+
'/spin/custom',
|
|
67
|
+
'/split-button/basic',
|
|
68
|
+
'/table/badge-size',
|
|
69
|
+
'/table/render-cell',
|
|
70
|
+
'/table/sort-data',
|
|
71
|
+
'/textarea/basic',
|
|
72
|
+
'/textarea/adjust-height',
|
|
73
|
+
'/textarea/disabled',
|
|
74
|
+
'/textarea/placeholder',
|
|
75
|
+
'/textarea/readonly',
|
|
76
|
+
'/textarea/resize',
|
|
77
|
+
'/textarea/rows',
|
|
78
|
+
'/version/basic',
|
|
79
|
+
'/version/context',
|
|
80
|
+
];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { test, expect } from '@playwright/test';
|
|
2
|
+
import { ROUTES } from './sample-app.routes.js';
|
|
3
|
+
|
|
4
|
+
// https://github.com/microsoft/playwright/issues/7575#issuecomment-1288164474
|
|
5
|
+
export const configureSnapshotPath =
|
|
6
|
+
() =>
|
|
7
|
+
({}, testInfo) => {
|
|
8
|
+
const originalSnapshotPath = testInfo.snapshotPath;
|
|
9
|
+
testInfo.snapshotPath = (snapshotName) => {
|
|
10
|
+
const result = originalSnapshotPath
|
|
11
|
+
.apply(testInfo, [snapshotName])
|
|
12
|
+
|
|
13
|
+
// Remove browser name from snapshot name
|
|
14
|
+
// .replace('-chromium', '')
|
|
15
|
+
// .replace('-firefox', '')
|
|
16
|
+
|
|
17
|
+
// Remove os name from snapshot name
|
|
18
|
+
.replace('-darwin', '')
|
|
19
|
+
.replace('-linux', '')
|
|
20
|
+
.replace('-windows', '')
|
|
21
|
+
|
|
22
|
+
// Remove test counter from snapshot name
|
|
23
|
+
.replace('-1-', '-');
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
test.beforeEach(configureSnapshotPath());
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @todo stabilize and re-enable test
|
|
32
|
+
*/
|
|
33
|
+
const blocklist = [];
|
|
34
|
+
|
|
35
|
+
ROUTES.filter((route) => !blocklist.includes(route)).forEach((route) => {
|
|
36
|
+
test(`snapshot for ${route}`, async ({ page }) => {
|
|
37
|
+
await page.goto(`/#${route}?hideMenus`, { waitUntil: 'networkidle' });
|
|
38
|
+
await page.setViewportSize({
|
|
39
|
+
width: 1920,
|
|
40
|
+
height: 1280,
|
|
41
|
+
});
|
|
42
|
+
await expect(page).toHaveScreenshot({
|
|
43
|
+
// fullPage: true,
|
|
44
|
+
maxDiffPixelRatio: 0.03,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
package/src/index.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import gradient from 'gradient-string';
|
|
5
|
-
|
|
6
|
-
import migrate from './migrate';
|
|
7
|
-
import { getVersionOfPublicUiKoliBriCli } from './migrate/shares/reuse';
|
|
8
|
-
|
|
9
|
-
const versionOfPublicUiKoliBriCli = getVersionOfPublicUiKoliBriCli();
|
|
10
|
-
|
|
11
|
-
const banner = gradient.atlas.multiline(
|
|
12
|
-
`
|
|
13
|
-
,--. ,--. ,--. ,--. ,-----. ,--.
|
|
14
|
-
| .' / ,---. | | \`--' | |) /_ ,--.--. \`--'
|
|
15
|
-
| . ' | .-. | | | ,--. | .-. \\ | .--' ,--.
|
|
16
|
-
| |\\ \\ | '-' | | | | | | '--' / | | | |
|
|
17
|
-
\`--' \`--´ \`---´ \`--' \`--' \`------´ \`--' \`--'
|
|
18
|
-
🚹 The accessible HTML-Standard | 👉 https://public-ui.github.io | ${versionOfPublicUiKoliBriCli}
|
|
19
|
-
`,
|
|
20
|
-
{
|
|
21
|
-
interpolation: 'hsv',
|
|
22
|
-
},
|
|
23
|
-
);
|
|
24
|
-
console.log(banner);
|
|
25
|
-
|
|
26
|
-
const program = new Command();
|
|
27
|
-
|
|
28
|
-
program.name('kolibri').description('CLI for executing some helpful commands for KoliBri projects.').version(versionOfPublicUiKoliBriCli);
|
|
29
|
-
|
|
30
|
-
// Add commands
|
|
31
|
-
migrate(program);
|
|
32
|
-
|
|
33
|
-
program.parse();
|
package/src/migrate/index.ts
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import { exec } from 'child_process';
|
|
2
|
-
import { Command, Option } from 'commander';
|
|
3
|
-
import fs from 'fs';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
import { Configuration } from '../types';
|
|
7
|
-
import { TaskRunner } from './runner/task-runner';
|
|
8
|
-
import { testTasks } from './runner/tasks/test';
|
|
9
|
-
import { v1Tasks } from './runner/tasks/v1';
|
|
10
|
-
import {
|
|
11
|
-
getContentOfProjectPkgJson,
|
|
12
|
-
getPackageManagerInstallCommand,
|
|
13
|
-
getVersionOfPublicUiComponents,
|
|
14
|
-
getVersionOfPublicUiKoliBriCli,
|
|
15
|
-
logAndCreateError,
|
|
16
|
-
MODIFIED_FILES,
|
|
17
|
-
setRemoveMode,
|
|
18
|
-
} from './shares/reuse';
|
|
19
|
-
import { REMOVE_MODE, RemoveMode } from './types';
|
|
20
|
-
|
|
21
|
-
type MigrateOption = {
|
|
22
|
-
ignoreUncommittedChanges: boolean;
|
|
23
|
-
removeMode: RemoveMode;
|
|
24
|
-
testTasks: boolean;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* This function is used to register the migrate command.
|
|
29
|
-
* @param {Command} program The program object to register the command
|
|
30
|
-
*/
|
|
31
|
-
export default function (program: Command): void {
|
|
32
|
-
program
|
|
33
|
-
.command('migrate')
|
|
34
|
-
.description('This command migrates KoliBri code to the current version.')
|
|
35
|
-
.argument('[string]', 'Source code folder to migrate', 'src')
|
|
36
|
-
.addOption(new Option('--ignore-uncommitted-changes', 'Allows execution with uncommitted changes').default(false))
|
|
37
|
-
.addOption(new Option('--remove-mode <mode>', 'Prefix property name or delete property').choices(REMOVE_MODE).default('prefix'))
|
|
38
|
-
.addOption(new Option('--test-tasks', 'Run additional test tasks').default(false).hideHelp())
|
|
39
|
-
.action((baseDir: string, options: MigrateOption) => {
|
|
40
|
-
exec('git status --porcelain', (err, stdout) => {
|
|
41
|
-
if (err) {
|
|
42
|
-
console.error(`exec error: ${err.message}`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!options.ignoreUncommittedChanges && stdout) {
|
|
47
|
-
throw logAndCreateError('There are uncommitted changes');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
setRemoveMode(options.removeMode);
|
|
51
|
-
|
|
52
|
-
const versionOfPublicUiComponents = getVersionOfPublicUiComponents();
|
|
53
|
-
const versionOfPublicUiKoliBriCli = getVersionOfPublicUiKoliBriCli();
|
|
54
|
-
|
|
55
|
-
console.log(`
|
|
56
|
-
Current version of @public-ui/components: ${versionOfPublicUiComponents}
|
|
57
|
-
Source folder to migrate: ${baseDir}
|
|
58
|
-
`);
|
|
59
|
-
|
|
60
|
-
const configFile = path.resolve(process.cwd(), '.kolibri.config.json');
|
|
61
|
-
let config: Configuration = {};
|
|
62
|
-
if (fs.existsSync(configFile)) {
|
|
63
|
-
try {
|
|
64
|
-
config = JSON.parse(fs.readFileSync(configFile, 'utf8')) as Configuration;
|
|
65
|
-
} catch (e) {
|
|
66
|
-
// ignore
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const runner = new TaskRunner(baseDir, versionOfPublicUiKoliBriCli, versionOfPublicUiComponents, config);
|
|
71
|
-
runner.registerTasks(v1Tasks);
|
|
72
|
-
|
|
73
|
-
if (options.testTasks) {
|
|
74
|
-
runner.registerTasks(testTasks);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
let version = versionOfPublicUiComponents;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Runs the task runner in a loop until all tasks are completed.
|
|
81
|
-
*/
|
|
82
|
-
function runLoop() {
|
|
83
|
-
runner.run();
|
|
84
|
-
if (version !== runner.getPendingMinVersion()) {
|
|
85
|
-
version = runner.getPendingMinVersion();
|
|
86
|
-
let packageJson = getContentOfProjectPkgJson();
|
|
87
|
-
packageJson = packageJson.replace(/"(@public-ui\/[^"]+)":\s*".*"/g, `"$1": "${version}"`);
|
|
88
|
-
fs.writeFileSync(path.resolve(process.cwd(), 'package.json'), packageJson);
|
|
89
|
-
runner.setProjectVersion(version);
|
|
90
|
-
|
|
91
|
-
console.log(`- Update @public-ui/* to version ${version}`);
|
|
92
|
-
exec(getPackageManagerInstallCommand(), (err) => {
|
|
93
|
-
if (err) {
|
|
94
|
-
console.error(`exec error: ${err.message}`);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
runLoop();
|
|
98
|
-
});
|
|
99
|
-
} else {
|
|
100
|
-
console.log(`
|
|
101
|
-
Status of all executed Tasks:`);
|
|
102
|
-
|
|
103
|
-
const status = runner.getStatus(true);
|
|
104
|
-
fs.writeFileSync(configFile, JSON.stringify(status.config, null, 2));
|
|
105
|
-
|
|
106
|
-
console.log(`
|
|
107
|
-
Modified files: ${MODIFIED_FILES.size}`);
|
|
108
|
-
MODIFIED_FILES.forEach((file) => {
|
|
109
|
-
console.log(`- ${file}`);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
console.log(`
|
|
113
|
-
After the code migration has gone through, the code formatting may no longer be as desired. Therefore, please reformat your code afterwards if necessary.
|
|
114
|
-
|
|
115
|
-
Afterwards, it may be that functions or themes in newer major versions have changed or are no longer included. This should be checked finally and corrected manually if necessary.
|
|
116
|
-
|
|
117
|
-
Is anything wrong, you can reset the migration with "git reset --hard HEAD~1" or by discarding the affected files. For more information read the troubleshooting section in the README.`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const status = runner.getStatus();
|
|
122
|
-
console.log(`
|
|
123
|
-
Execute ${status.total} registered tasks...`);
|
|
124
|
-
runLoop();
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import semver from 'semver';
|
|
2
|
-
|
|
3
|
-
import { FILE_EXTENSIONS, FileExtension } from '../../types';
|
|
4
|
-
import { logAndCreateError } from '../shares/reuse';
|
|
5
|
-
import { TaskStatus } from './types';
|
|
6
|
-
|
|
7
|
-
export type TaskOptions = {
|
|
8
|
-
dependentTasks?: AbstractTask[];
|
|
9
|
-
description?: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export abstract class AbstractTask {
|
|
13
|
-
private status: TaskStatus = 'pending';
|
|
14
|
-
|
|
15
|
-
protected static readonly instances: Map<string, AbstractTask> = new Map();
|
|
16
|
-
|
|
17
|
-
protected readonly description?: string;
|
|
18
|
-
|
|
19
|
-
protected constructor(
|
|
20
|
-
protected readonly identifier: string,
|
|
21
|
-
protected readonly title: string,
|
|
22
|
-
protected readonly extensions: FileExtension[],
|
|
23
|
-
protected readonly versionRange: string,
|
|
24
|
-
protected readonly dependentTasks: AbstractTask[] = [],
|
|
25
|
-
options: TaskOptions = {},
|
|
26
|
-
) {
|
|
27
|
-
this.description = options.description;
|
|
28
|
-
this.extensions = this.extensions.filter((ext) => FILE_EXTENSIONS.includes(ext));
|
|
29
|
-
|
|
30
|
-
if (!semver.validRange(this.versionRange)) {
|
|
31
|
-
throw logAndCreateError(`[${this.identifier}] Invalid semver range version: ${this.versionRange}`);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
public getDependentTasks(): AbstractTask[] {
|
|
36
|
-
return this.dependentTasks;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
public getDescription(): string | undefined {
|
|
40
|
-
return this.description;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
public getIdentifier(): string {
|
|
44
|
-
return this.identifier;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
public setStatus(status: TaskStatus): void {
|
|
48
|
-
this.status = status;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
public getStatus(): TaskStatus {
|
|
52
|
-
return this.status;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
public getTitle(): string {
|
|
56
|
-
return this.title;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
public getVersionRange(): string {
|
|
60
|
-
return this.versionRange;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public abstract run(baseDir: string): void;
|
|
64
|
-
}
|