Files
KanbanGit/tests/Fixtures/ui-components.mjs
T
Twyco 2e2ddd5b74
CI/CD / Publish immutable image (push) Canceled after 0s
CI/CD / test_and_check_app (push) Canceled after 6s
CI/CD / Publish immutable image (pull_request) Canceled after 0s
CI/CD / test_and_check_app (pull_request) Canceled after 6s
feat(KAN-18): redesign foundational UI components
2026-09-11 14:13:49 +02:00

185 lines
6.4 KiB
JavaScript

import assert from 'node:assert/strict';
import { fileURLToPath } from 'node:url';
import vue from '@vitejs/plugin-vue';
import { createServer } from 'vite';
import { createSSRApp, h } from 'vue';
import { renderToString } from 'vue/server-renderer';
const server = await createServer({
configFile: false,
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('../../resources/js', import.meta.url)),
},
},
server: { middlewareMode: true, hmr: false, watch: null },
appType: 'custom',
});
try {
const { createLocalization } = await server.ssrLoadModule(
'/resources/js/lib/localization.ts',
);
const { en } = await server.ssrLoadModule('/resources/js/locales/en.ts');
const { default: Button } = await server.ssrLoadModule(
'/resources/js/components/ui/button/Button.vue',
);
const { buttonVariants } = await server.ssrLoadModule(
'/resources/js/components/ui/button/index.ts',
);
const { default: Input } = await server.ssrLoadModule(
'/resources/js/components/ui/input/Input.vue',
);
const { default: Select } = await server.ssrLoadModule(
'/resources/js/components/ui/select/Select.vue',
);
const { default: SelectTrigger } = await server.ssrLoadModule(
'/resources/js/components/ui/select/SelectTrigger.vue',
);
const { default: SelectValue } = await server.ssrLoadModule(
'/resources/js/components/ui/select/SelectValue.vue',
);
const { default: Checkbox } = await server.ssrLoadModule(
'/resources/js/components/ui/checkbox/Checkbox.vue',
);
const { default: Badge } = await server.ssrLoadModule(
'/resources/js/components/ui/badge/Badge.vue',
);
const { badgeVariants } = await server.ssrLoadModule(
'/resources/js/components/ui/badge/index.ts',
);
const { default: Avatar } = await server.ssrLoadModule(
'/resources/js/components/ui/avatar/Avatar.vue',
);
const { default: AvatarFallback } = await server.ssrLoadModule(
'/resources/js/components/ui/avatar/AvatarFallback.vue',
);
const { default: UserAvatar } = await server.ssrLoadModule(
'/resources/js/components/ui/avatar/UserAvatar.vue',
);
const { avatarVariants } = await server.ssrLoadModule(
'/resources/js/components/ui/avatar/index.ts',
);
const german = createLocalization(
{ locale: 'de' },
{ de: { ...en, 'common.loading': 'Wird geladen…' } },
);
const render = (component, props = {}, slots = {}) =>
renderToString(
createSSRApp({ render: () => h(component, props, slots) }).use(
german,
),
);
const loadingButton = await render(
Button,
{ loading: true },
{ default: () => 'Save' },
);
assert.match(loadingButton, /<button/);
assert.match(loadingButton, /disabled/);
assert.match(loadingButton, /aria-disabled="true"/);
assert.match(loadingButton, /aria-busy="true"/);
assert.match(loadingButton, /data-loading/);
assert.match(loadingButton, /role="status"/);
assert.match(loadingButton, /aria-label="Wird geladen…"/);
assert.match(loadingButton, />Save</);
assert.match(buttonVariants(), /min-h-control/);
assert.match(buttonVariants(), /bg-brand/);
assert.match(buttonVariants({ variant: 'outline' }), /bg-card/);
const invalidInput = await render(Input, {
disabled: true,
invalid: true,
name: 'title',
});
assert.match(invalidInput, /<input/);
assert.match(invalidInput, /name="title"/);
assert.match(invalidInput, /disabled/);
assert.match(invalidInput, /aria-invalid="true"/);
assert.match(invalidInput, /data-invalid/);
assert.match(invalidInput, /min-h-control/);
const select = await render(
Select,
{ disabled: true },
{
default: () =>
h(
SelectTrigger,
{ invalid: true },
{
default: () =>
h(SelectValue, { placeholder: 'Choose' }),
},
),
},
);
assert.match(select, /role="combobox"/);
assert.match(select, /disabled/);
assert.match(select, /aria-invalid="true"/);
assert.match(select, /data-invalid/);
assert.match(select, /min-h-control/);
const checkbox = await render(Checkbox, {
disabled: true,
invalid: true,
});
assert.match(checkbox, /role="checkbox"/);
assert.match(checkbox, /aria-checked="false"/);
assert.match(checkbox, /disabled/);
assert.match(checkbox, /aria-invalid="true"/);
assert.match(checkbox, /data-invalid/);
const successBadge = await render(
Badge,
{ variant: 'success' },
{ default: () => 'Done' },
);
assert.match(successBadge, /bg-success/);
assert.match(successBadge, />Done</);
assert.doesNotMatch(successBadge, /variant="success"/);
assert.match(badgeVariants({ variant: 'success' }), /bg-success/);
assert.match(badgeVariants({ variant: 'warning' }), /bg-warning/);
assert.match(badgeVariants({ variant: 'info' }), /bg-info/);
const avatar = await render(
Avatar,
{ size: 'xl', shape: 'square' },
{ default: () => h(AvatarFallback, {}, () => 'NS') },
);
assert.match(avatar, /data-size="xl"/);
assert.match(avatar, /data-shape="square"/);
assert.match(avatar, /size-16/);
assert.match(avatar, /rounded-sm/);
assert.match(avatar, />NS</);
assert.match(avatarVariants({ size: 'sm' }), /size-6/);
const userAvatar = await render(UserAvatar, {
rounded: true,
size: 'lg',
user: {
id: 1,
name: 'Nico Schröder',
email: 'nico@example.test',
avatar: null,
avatar_color: null,
avatar_is_generated: false,
email_verified_at: null,
must_change_password_on_next_login: false,
created_at: '2026-09-09T00:00:00Z',
updated_at: '2026-09-09T00:00:00Z',
},
});
assert.match(userAvatar, /data-size="lg"/);
assert.match(userAvatar, /data-shape="circle"/);
assert.match(userAvatar, /aria-label="Nico Schröder"/);
assert.match(userAvatar, />NS</);
console.log('UI component behavior checks passed.');
} finally {
await server.close();
}