185 lines
6.4 KiB
JavaScript
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();
|
|
}
|