@public-ui/visual-tests 1.7.0-rc.7 → 1.7.0-rc.8
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 +144 -23
- package/package.json +12 -17
- package/src/index.ts +33 -0
- package/src/migrate/index.ts +127 -0
- package/src/migrate/runner/abstract-task.ts +64 -0
- package/src/migrate/runner/task-runner.ts +163 -0
- package/src/migrate/runner/tasks/common/GenericRenamePropertyTask.ts +85 -0
- package/src/migrate/runner/tasks/common/LabelExpertSlot.ts +96 -0
- package/src/migrate/runner/tasks/common/RemovePropertyNameTask.ts +104 -0
- package/src/migrate/runner/tasks/common/RenamePropertyNameTask.ts +31 -0
- package/src/migrate/runner/tasks/test/index.ts +16 -0
- package/src/migrate/runner/tasks/test/test-dummy.ts +20 -0
- package/src/migrate/runner/tasks/test/test-version-1.3.ts +7 -0
- package/src/migrate/runner/tasks/test/test-version-current.ts +7 -0
- package/src/migrate/runner/tasks/test/test-version-next-2.ts +7 -0
- package/src/migrate/runner/tasks/test/test-version-next-3.ts +7 -0
- package/src/migrate/runner/tasks/test/test-version-zero.ts +7 -0
- package/src/migrate/runner/tasks/v1/abbr.ts +3 -0
- package/src/migrate/runner/tasks/v1/accordion.ts +3 -0
- package/src/migrate/runner/tasks/v1/badge.ts +6 -0
- package/src/migrate/runner/tasks/v1/breadcrumb.ts +3 -0
- package/src/migrate/runner/tasks/v1/button-link.ts +6 -0
- package/src/migrate/runner/tasks/v1/button.ts +8 -0
- package/src/migrate/runner/tasks/v1/card.ts +4 -0
- package/src/migrate/runner/tasks/v1/details.ts +3 -0
- package/src/migrate/runner/tasks/v1/icon.ts +5 -0
- package/src/migrate/runner/tasks/v1/index.ts +151 -0
- package/src/migrate/runner/tasks/v1/input-checkbox.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-color.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-date.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-email.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-number.ts +4 -0
- package/src/migrate/runner/tasks/v1/input-radio.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-range.ts +3 -0
- package/src/migrate/runner/tasks/v1/input-text.ts +3 -0
- package/src/migrate/runner/tasks/v1/link-button.ts +15 -0
- package/src/migrate/runner/tasks/v1/link-group.ts +7 -0
- package/src/migrate/runner/tasks/v1/link.ts +15 -0
- package/src/migrate/runner/tasks/v1/logo.ts +3 -0
- package/src/migrate/runner/tasks/v1/modal.ts +3 -0
- package/src/migrate/runner/tasks/v1/nav.ts +7 -0
- package/src/migrate/runner/tasks/v1/pagination.ts +3 -0
- package/src/migrate/runner/tasks/v1/progress.ts +3 -0
- package/src/migrate/runner/tasks/v1/quote.ts +3 -0
- package/src/migrate/runner/tasks/v1/select.ts +4 -0
- package/src/migrate/runner/tasks/v1/skip-nav.ts +3 -0
- package/src/migrate/runner/tasks/v1/span.ts +3 -0
- package/src/migrate/runner/tasks/v1/split-button.ts +3 -0
- package/src/migrate/runner/tasks/v1/table.ts +3 -0
- package/src/migrate/runner/tasks/v1/tabs.ts +4 -0
- package/src/migrate/runner/tasks/v1/toast.ts +3 -0
- package/src/migrate/runner/tasks/v1/version.ts +3 -0
- package/src/migrate/runner/types.ts +2 -0
- package/src/migrate/shares/reuse.ts +182 -0
- package/src/migrate/types.ts +2 -0
- package/src/types.ts +23 -0
- package/dist/index.js +0 -43
- package/kolibri-visual-test.sh +0 -3
- package/playwright.config.ts +0 -59
- package/tests/theme-snapshots.spec.ts +0 -46
- package/tsconfig.json +0 -22
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RemovePropertyNameTask } from '../common/RemovePropertyNameTask';
|
|
2
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
3
|
+
|
|
4
|
+
export const LinkButtonRemovePropertyAriaControl = RemovePropertyNameTask.getInstance('kol-link-button', '_aria-control', '^1');
|
|
5
|
+
export const LinkButtonRenamePropertyAriaCurrentToListenAriaCurrent = RenamePropertyNameTask.getInstance(
|
|
6
|
+
'kol-link-button',
|
|
7
|
+
'_aria-current',
|
|
8
|
+
'_listen-aria-current',
|
|
9
|
+
'^1',
|
|
10
|
+
);
|
|
11
|
+
export const LinkButtonRemovePropertyAriaExpanded = RemovePropertyNameTask.getInstance('kol-link-button', '_aria-expanded', '^1');
|
|
12
|
+
export const LinkButtonRemovePropertyAriaLabel = RemovePropertyNameTask.getInstance('kol-link-button', '_aria-label', '^1');
|
|
13
|
+
export const LinkButtonRemovePropertyAriaSelected = RemovePropertyNameTask.getInstance('kol-link-button', '_aria-selected', '^1');
|
|
14
|
+
export const LinkButtonRemovePropertyDisabled = RemovePropertyNameTask.getInstance('kol-link-button', '_disabled', '^1');
|
|
15
|
+
export const LinkButtonRenamePropertyIconOnlyToHideLabel = RenamePropertyNameTask.getInstance('kol-link-button', '_icon-only', '_hide-label', '^1');
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RemovePropertyNameTask } from '../common/RemovePropertyNameTask';
|
|
2
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
3
|
+
|
|
4
|
+
export const LinkGroupRenamePropertyAriaLabelToLabel = RenamePropertyNameTask.getInstance('kol-link-group', '_aria-label', '_label', '^1');
|
|
5
|
+
export const LinkGroupRenamePropertyHeadingToLabel = RenamePropertyNameTask.getInstance('kol-link-group', '_heading', '_label', '^1');
|
|
6
|
+
export const LinkGroupRemovePropertyHeading = RemovePropertyNameTask.getInstance('kol-link-group', '_heading', '^1', [LinkGroupRenamePropertyHeadingToLabel]);
|
|
7
|
+
export const LinkGroupRemovePropertyOrdered = RemovePropertyNameTask.getInstance('kol-link-group', '_ordered', '^1');
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RemovePropertyNameTask } from '../common/RemovePropertyNameTask';
|
|
2
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
3
|
+
|
|
4
|
+
export const LinkRemovePropertyAriaControl = RemovePropertyNameTask.getInstance('kol-link', '_aria-control', '^1');
|
|
5
|
+
export const LinkRenamePropertyAriaCurrentToListenAriaCurrent = RenamePropertyNameTask.getInstance('kol-link', '_aria-current', '_listen-aria-current', '^1');
|
|
6
|
+
export const LinkRemovePropertyAriaExpanded = RemovePropertyNameTask.getInstance('kol-link', '_aria-expanded', '^1');
|
|
7
|
+
export const LinkRemovePropertyAriaLabel = RemovePropertyNameTask.getInstance('kol-link', '_aria-label', '^1');
|
|
8
|
+
export const LinkRemovePropertyAriaSelected = RemovePropertyNameTask.getInstance('kol-link', '_aria-selected', '^1');
|
|
9
|
+
export const LinkRemovePropertyDisabled = RemovePropertyNameTask.getInstance('kol-link', '_disabled', '^1');
|
|
10
|
+
// @todo: handle _icon-align in _icon
|
|
11
|
+
export const LinkRemovePropertyIconAlign = RemovePropertyNameTask.getInstance('kol-link', '_icon-align', '^1');
|
|
12
|
+
export const LinkRenamePropertyIconOnlyToHideLabel = RenamePropertyNameTask.getInstance('kol-link', '_icon-only', '_hide-label', '^1');
|
|
13
|
+
export const LinkRemovePropertySelector = RemovePropertyNameTask.getInstance('kol-link', '_selector', '^1');
|
|
14
|
+
export const LinkRemovePropertyStealth = RemovePropertyNameTask.getInstance('kol-link', '_stealth', '^1');
|
|
15
|
+
export const LinkRemovePropertyUseCase = RemovePropertyNameTask.getInstance('kol-link', '_use-case', '^1');
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RemovePropertyNameTask } from '../common/RemovePropertyNameTask';
|
|
2
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
3
|
+
|
|
4
|
+
export const NavRenamePropertyAriaLabelToLabel = RenamePropertyNameTask.getInstance('kol-nav', '_aria-label', '_label', '^1');
|
|
5
|
+
export const NavRenamePropertyCompactToHideLabel = RenamePropertyNameTask.getInstance('kol-nav', '_compact', '_hide-label', '^1');
|
|
6
|
+
export const NavRemovePropertyHasCompactButton = RemovePropertyNameTask.getInstance('kol-nav', '_has-compact-button', '^1');
|
|
7
|
+
export const NavRemovePropertyVariant = RemovePropertyNameTask.getInstance('kol-nav', '_variant', '^1');
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
2
|
+
|
|
3
|
+
export const SelectRenamePropertyHeightToRows = RenamePropertyNameTask.getInstance('kol-select', '_height', '_rows', '^1');
|
|
4
|
+
export const SelectRenamePropertyListToOptions = RenamePropertyNameTask.getInstance('kol-select', '_list', '_options', '^1');
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { RenamePropertyNameTask } from '../common/RenamePropertyNameTask';
|
|
2
|
+
|
|
3
|
+
export const TabsRenamePropertyAriaLabelToLabel = RenamePropertyNameTask.getInstance('kol-tabs', '_aria-label', '_label', '^1');
|
|
4
|
+
export const TabsRenamePropertyTabAlignToAlign = RenamePropertyNameTask.getInstance('kol-tabs', '_tab-align', '_align', '^1');
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
|
|
5
|
+
import { FileExtension, PackageJson } from '../../types';
|
|
6
|
+
import { RemoveMode } from '../types';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* This function is used to exit the process with an error message.
|
|
10
|
+
* @param {string} msg The error message
|
|
11
|
+
* @param {string} hint The hint message
|
|
12
|
+
* @returns {Error} The error object
|
|
13
|
+
*/
|
|
14
|
+
export function logAndCreateError(msg: string, hint?: string) {
|
|
15
|
+
const hintText = hint
|
|
16
|
+
? chalk.yellow(
|
|
17
|
+
`
|
|
18
|
+
ℹ️ `,
|
|
19
|
+
chalk.underline.bold(`Hinweis:`),
|
|
20
|
+
hint,
|
|
21
|
+
`
|
|
22
|
+
`,
|
|
23
|
+
)
|
|
24
|
+
: '';
|
|
25
|
+
console.log(
|
|
26
|
+
chalk.red(
|
|
27
|
+
chalk.underline.bold(`
|
|
28
|
+
Error:`),
|
|
29
|
+
`${msg}
|
|
30
|
+
`,
|
|
31
|
+
),
|
|
32
|
+
hintText,
|
|
33
|
+
`
|
|
34
|
+
👉 You can report this error to`,
|
|
35
|
+
chalk.blue(`https://github.com/public-ui/kolibri/issues/new?title=CLI:+`),
|
|
36
|
+
`
|
|
37
|
+
`,
|
|
38
|
+
);
|
|
39
|
+
// @todo process.exit(1); // makes `hint` undefined - ?!
|
|
40
|
+
return new Error();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Recursively searches for files with the specified extension in the specified directory.
|
|
45
|
+
* @param {string} dir The directory to search in
|
|
46
|
+
* @param {FileExtension | FileExtension[]} ext The extension to search for
|
|
47
|
+
* @returns {string[]} The found files
|
|
48
|
+
*/
|
|
49
|
+
export function filterFilesByExt(dir: string, ext: FileExtension | FileExtension[]): string[] {
|
|
50
|
+
ext = Array.isArray(ext) ? ext : [ext];
|
|
51
|
+
let files: string[] = [];
|
|
52
|
+
const dirPath = path.resolve(process.cwd(), dir);
|
|
53
|
+
fs.readdirSync(dirPath).forEach((file) => {
|
|
54
|
+
const fullPath = path.resolve(dir, file);
|
|
55
|
+
if (fs.lstatSync(fullPath).isDirectory()) {
|
|
56
|
+
files = files.concat(filterFilesByExt(fullPath, ext));
|
|
57
|
+
} else if (ext.includes(path.extname(fullPath).replace('.', '') as FileExtension)) {
|
|
58
|
+
files.push(fullPath);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return files;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* This function is used to get the version of the package.json as string.
|
|
66
|
+
* @param {string} offsetPath The offset path to the package.json
|
|
67
|
+
* @returns {string} The package.json as string
|
|
68
|
+
*/
|
|
69
|
+
function readPackageString(offsetPath: string): string {
|
|
70
|
+
offsetPath = path.resolve(offsetPath, 'package.json');
|
|
71
|
+
if (!fs.existsSync(offsetPath)) {
|
|
72
|
+
throw logAndCreateError(`The following "package.json" does not exists: ${offsetPath}`);
|
|
73
|
+
}
|
|
74
|
+
return fs.readFileSync(offsetPath, 'utf8');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* This function is used to get the version of the package.json.
|
|
79
|
+
* @param {string} offsetPath The offset path to the package.json
|
|
80
|
+
* @returns {PackageJson} The package.json as object
|
|
81
|
+
*/
|
|
82
|
+
function readPackageJson(offsetPath: string): PackageJson {
|
|
83
|
+
const content = readPackageString(offsetPath);
|
|
84
|
+
let json: Record<string, unknown>;
|
|
85
|
+
try {
|
|
86
|
+
json = JSON.parse(content) as Record<string, unknown>;
|
|
87
|
+
} catch (err) {
|
|
88
|
+
throw logAndCreateError(`The following "package.json" content could not parse: ${content}`);
|
|
89
|
+
}
|
|
90
|
+
return json as PackageJson;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* This function is used to get the package manager install command.
|
|
95
|
+
* @param {string} baseDir The base directory to start searching for the package manager
|
|
96
|
+
* @returns {string} The package manager install command
|
|
97
|
+
*/
|
|
98
|
+
export function getPackageManagerInstallCommand(baseDir: string = process.cwd()) {
|
|
99
|
+
if (fs.existsSync(path.resolve(baseDir, 'pnpm-lock.yaml'))) return 'pnpm i';
|
|
100
|
+
if (fs.existsSync(path.resolve(baseDir, 'yarn.lock'))) return 'yarn';
|
|
101
|
+
if (fs.existsSync(path.resolve(baseDir, 'package-lock.json'))) return 'npm i';
|
|
102
|
+
baseDir = path.resolve(baseDir, '..');
|
|
103
|
+
if (baseDir === '/') {
|
|
104
|
+
throw logAndCreateError('Package manager could not detected.');
|
|
105
|
+
}
|
|
106
|
+
return getPackageManagerInstallCommand(baseDir);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export const isTagKebabCaseRegExp = /^kol-[a-z]+(-[a-z]+)*$/;
|
|
110
|
+
export const isPropertyKebabCaseRegExp = /^(data-removed-)?_[a-z]+(-[a-z]+)*$/;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Converts a kebab case string to a capital case string.
|
|
114
|
+
* @param {string} str The kebab case string
|
|
115
|
+
* @returns {string} The capital case string
|
|
116
|
+
*/
|
|
117
|
+
export function kebabToCapitalCase(str: string) {
|
|
118
|
+
return str
|
|
119
|
+
.split('-') // Split on hyphen
|
|
120
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) // Capitalize each word
|
|
121
|
+
.join(''); // Join without space
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Converts a kebab case string to a camel case string.
|
|
126
|
+
* @param {string} str The kebab case string
|
|
127
|
+
* @returns {string} The camel case string
|
|
128
|
+
*/
|
|
129
|
+
export function kebabToCamelCase(str: string) {
|
|
130
|
+
return str
|
|
131
|
+
.split('-') // Split on hyphen
|
|
132
|
+
.map((word, index) => (index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())) // Capitalize each word
|
|
133
|
+
.join(''); // Join without space
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const MODIFIED_FILES = new Set<string>();
|
|
137
|
+
|
|
138
|
+
let REMOVE_MODE: RemoveMode = 'prefix';
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Sets the remove mode.
|
|
142
|
+
* @param {RemoveMode} mode The remove mode
|
|
143
|
+
*/
|
|
144
|
+
export function setRemoveMode(mode: RemoveMode): void {
|
|
145
|
+
REMOVE_MODE = mode;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Gets the remove mode.
|
|
150
|
+
* @returns {RemoveMode} The remove mode
|
|
151
|
+
*/
|
|
152
|
+
export function getRemoveMode(): RemoveMode {
|
|
153
|
+
return REMOVE_MODE;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const getContentOfProjectPkgJson = (): string => {
|
|
157
|
+
try {
|
|
158
|
+
return readPackageString(path.resolve(process.cwd()));
|
|
159
|
+
} catch (err) {
|
|
160
|
+
throw logAndCreateError('Could not read content of project "package.json"!');
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
export const getVersionOfPublicUiComponents = (): string => {
|
|
164
|
+
try {
|
|
165
|
+
return readPackageJson(path.resolve(process.cwd(), 'node_modules/@public-ui/components')).version;
|
|
166
|
+
} catch (err) {
|
|
167
|
+
throw logAndCreateError(
|
|
168
|
+
'Could not get version of installed "@public-ui/components" package!',
|
|
169
|
+
'Check that you are in the root directory of your project and that the package "@public-ui/components" is installed.',
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
export const getVersionOfPublicUiKoliBriCli = (): string => {
|
|
174
|
+
try {
|
|
175
|
+
return readPackageJson(path.resolve(__dirname, '..', '..', '..')).version;
|
|
176
|
+
} catch (err) {
|
|
177
|
+
throw logAndCreateError(
|
|
178
|
+
'Could not get version of global installed "@public-ui/kolibri-cli" package!',
|
|
179
|
+
'Install the package with: npm i -g @public-ui/kolibri-cli',
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
};
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const FILE_EXTENSIONS = ['html', 'js', 'json', 'jsx', 'ts', 'tsx', 'vue'] as const;
|
|
2
|
+
export type FileExtension = (typeof FILE_EXTENSIONS)[number];
|
|
3
|
+
|
|
4
|
+
export const COMPONENT_FILE_EXTENSIONS: FileExtension[] = ['jsx', 'tsx', 'vue'];
|
|
5
|
+
export const CUSTOM_ELEMENT_FILE_EXTENSIONS: FileExtension[] = ['html', 'jsx', 'tsx', 'vue'];
|
|
6
|
+
export const MARKUP_EXTENSIONS: FileExtension[] = COMPONENT_FILE_EXTENSIONS.concat(CUSTOM_ELEMENT_FILE_EXTENSIONS);
|
|
7
|
+
|
|
8
|
+
export type PackageJson = {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
scripts?: { [key: string]: string };
|
|
12
|
+
dependencies?: { [key: string]: string };
|
|
13
|
+
devDependencies?: { [key: string]: string };
|
|
14
|
+
peerDependencies?: { [key: string]: string };
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type Configuration = {
|
|
18
|
+
migrate?: {
|
|
19
|
+
tasks: {
|
|
20
|
+
[identifier: string]: boolean;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
package/dist/index.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
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
|
-
process.env.KOLIBRI_CWD = process.cwd();
|
|
9
|
-
const tempDir = process.env.RUNNER_TEMP || process.env.TMPDIR;
|
|
10
|
-
if (!process.env.THEME_MODULE) {
|
|
11
|
-
throw new Error('Environment variable THEME_MODULE not specified.');
|
|
12
|
-
}
|
|
13
|
-
if (!tempDir) {
|
|
14
|
-
throw new Error('Neither environment variable RUNNER_TEMP or TMPDIR specified.');
|
|
15
|
-
}
|
|
16
|
-
process.env.THEME_MODULE = path.join(process.cwd(), process.env.THEME_MODULE);
|
|
17
|
-
const visualsTestModulePath = fileURLToPath(new URL('..', import.meta.url));
|
|
18
|
-
const binaryPath = fileURLToPath(new URL('../node_modules/.bin', import.meta.url));
|
|
19
|
-
const buildPath = path.join(tempDir, `kolibri-visual-testing-build-${crypto.randomUUID()}`);
|
|
20
|
-
process.env.KOLIBRI_VISUAL_TESTS_BUILD_PATH = buildPath;
|
|
21
|
-
console.log('Building React Sample App...');
|
|
22
|
-
child_process.execFileSync(path.join(binaryPath, 'kolibri-sample-react-test-build'), [buildPath], {
|
|
23
|
-
encoding: 'utf-8',
|
|
24
|
-
});
|
|
25
|
-
console.log(`React Sample App build finished. Directory:`, buildPath);
|
|
26
|
-
void (async () => {
|
|
27
|
-
process.env.KOLIBRI_VISUAL_TEST_PORT = String(await portfinder.getPortPromise());
|
|
28
|
-
const playwright = child_process.spawn(path.join(binaryPath, 'playwright'), ['test', ...process.argv.slice(2)], {
|
|
29
|
-
cwd: visualsTestModulePath,
|
|
30
|
-
});
|
|
31
|
-
playwright.stdout.on('data', (data) => {
|
|
32
|
-
console.log('Playwright: ' + data.toString());
|
|
33
|
-
});
|
|
34
|
-
playwright.stderr.on('data', (data) => {
|
|
35
|
-
console.log('Playwright stderr: ' + data.toString());
|
|
36
|
-
});
|
|
37
|
-
playwright.on('exit', (code) => {
|
|
38
|
-
console.log(`Playwright test finished with exit code ${code}.`);
|
|
39
|
-
console.log('Cleaning up build folder...');
|
|
40
|
-
fs.rmSync(buildPath, { recursive: true, force: true });
|
|
41
|
-
process.exit(code !== null && code !== void 0 ? code : 1);
|
|
42
|
-
});
|
|
43
|
-
})();
|
package/kolibri-visual-test.sh
DELETED
package/playwright.config.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
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
|
-
});
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { test, expect, TestInfo } from '@playwright/test';
|
|
2
|
-
// @ts-ignore
|
|
3
|
-
import { routes } from '@public-ui/sample-react/src/routes-test.ts';
|
|
4
|
-
|
|
5
|
-
// https://github.com/microsoft/playwright/issues/7575#issuecomment-1288164474
|
|
6
|
-
export const configureSnapshotPath =
|
|
7
|
-
(options?: {}) =>
|
|
8
|
-
({}: any, testInfo: TestInfo): any => {
|
|
9
|
-
const originalSnapshotPath = testInfo.snapshotPath;
|
|
10
|
-
testInfo.snapshotPath = (snapshotName) => {
|
|
11
|
-
const result = originalSnapshotPath
|
|
12
|
-
.apply(testInfo, [snapshotName])
|
|
13
|
-
|
|
14
|
-
// Remove browser name from snapshot name
|
|
15
|
-
// .replace('-chromium', '')
|
|
16
|
-
// .replace('-firefox', '')
|
|
17
|
-
|
|
18
|
-
// Remove os name from snapshot name
|
|
19
|
-
.replace('-darwin', '')
|
|
20
|
-
.replace('-linux', '')
|
|
21
|
-
.replace('-windows', '')
|
|
22
|
-
|
|
23
|
-
// Remove test counter from snapshot name
|
|
24
|
-
.replace('-1-', '-');
|
|
25
|
-
return result;
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
test.beforeEach(configureSnapshotPath());
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @todo stabilize and re-enable test
|
|
33
|
-
*/
|
|
34
|
-
const blocklist = ['/heading/paragraph'];
|
|
35
|
-
|
|
36
|
-
routes
|
|
37
|
-
.filter((route) => !blocklist.includes(route))
|
|
38
|
-
.forEach((route) => {
|
|
39
|
-
test(`snapshot for ${route}`, async ({ page }) => {
|
|
40
|
-
await page.goto(`/#${route}?hideMenus`, { waitUntil: 'networkidle' });
|
|
41
|
-
await expect(page).toHaveScreenshot({
|
|
42
|
-
fullPage: true,
|
|
43
|
-
maxDiffPixelRatio: 0.03,
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"allowSyntheticDefaultImports": true,
|
|
4
|
-
"allowUnreachableCode": false,
|
|
5
|
-
"declaration": false,
|
|
6
|
-
"experimentalDecorators": true,
|
|
7
|
-
"lib": ["ES2017"],
|
|
8
|
-
"moduleResolution": "nodenext",
|
|
9
|
-
"module": "nodenext",
|
|
10
|
-
"target": "ES2017",
|
|
11
|
-
"noUnusedLocals": true,
|
|
12
|
-
"noUnusedParameters": true,
|
|
13
|
-
"forceConsistentCasingInFileNames": true,
|
|
14
|
-
"importHelpers": true,
|
|
15
|
-
"removeComments": true,
|
|
16
|
-
"types": ["node"],
|
|
17
|
-
"typeRoots": ["node_modules/@types"],
|
|
18
|
-
"strict": true,
|
|
19
|
-
"skipLibCheck": true
|
|
20
|
-
},
|
|
21
|
-
"include": ["src"]
|
|
22
|
-
}
|