Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
version: 10.18.0

- name: Install dependencies
run: pnpm install
run: pnpm install --frozen-lockfile

- name: Run lint
run: pnpm lint
Expand All @@ -56,7 +56,7 @@ jobs:
with:
version: 10.18.0
- name: Install dependencies
run: pnpm install
run: pnpm install --frozen-lockfile
- name: Run build
run: pnpm build
test:
Expand All @@ -76,7 +76,12 @@ jobs:
with:
version: 10.18.0
- name: Install dependencies
run: pnpm install
run: pnpm install --frozen-lockfile

- name: Install playwright browsers
run: pnpm exec playwright-core install --with-deps

- name: Run tests
run: pnpm test:all
run: |
pnpm test:unit
pnpm test:nuxt
3 changes: 2 additions & 1 deletion app/components/Header/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const colorMode = useColorMode();
height="40"
fit="contain"
background="transparent"
data-testId="logo"
/>
<template #fallback>
<NuxtImg
Expand All @@ -30,7 +31,7 @@ const colorMode = useColorMode();
<h1 class="text-gray-900 dark:text-white text-lg font-bold">Lystra</h1>
</UButton>
<div class="flex items-center gap-1.5">
<UColorModeButton class="cursor-pointer">
<UColorModeButton class="cursor-pointer" data-testId="color-mode-toggle">
<template #fallback>
<UButton loading variant="ghost" color="neutral" />
</template>
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"test:watch": "vitest --watch",
"test:e2e": "vitest --project e2e",
"test:unit": "vitest --project nuxt",
"test:unit": "vitest run --project unit",
"test:nuxt": "vitest run --project nuxt",
"test:all": "vitest run",
"prepare": "husky"
},
Expand Down
1,445 changes: 792 additions & 653 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

70 changes: 70 additions & 0 deletions test/e2e/main.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { createPage, setup } from '@nuxt/test-utils/e2e';
import { describe, expect, it } from 'vitest';

describe('Header Component', async () => {
await setup({
server: true,
port: 3000,
browser: true,
});

it('should render the logo', async () => {
const page = await createPage('/');

const logo = page.getByTestId('logo');
expect(await logo.isVisible()).toBe(true);
expect(await logo.getAttribute('src')).toContain('lystra-logo-light.svg');
expect(await logo.getAttribute('alt')).toBe('Lystra logo');
});

it('should render the header', async () => {
const page = await createPage('/');

const heading = page.getByRole('heading', { name: 'Lystra' });
expect(await heading.isVisible()).toBe(true);
});

it('should render the theme button', async () => {
const page = await createPage('/');

const button = page.getByTestId('color-mode-toggle');
expect(await button.isVisible()).toBe(true);
});

it('should switch the theme on theme button click', async () => {
const page = await createPage('/');

const button = page.getByTestId('color-mode-toggle');
expect(await button.isVisible()).toBe(true);

const logo = page.getByTestId('logo');
const initialSrc = await logo.getAttribute('src');
expect(initialSrc).toContain('lystra-logo-light.svg');

await button.click();

await page.waitForFunction(
() => {
const logoElement = document.querySelector('[data-testId="logo"]');
return logoElement?.getAttribute('src')?.includes('lystra-logo-dark.svg');
},
{ timeout: 5000 }
);

const newSrc = await logo.getAttribute('src');
expect(newSrc).toContain('lystra-logo-dark.svg');

await button.click();

await page.waitForFunction(
() => {
const logoElement = document.querySelector('[data-testId="logo"]');
return logoElement?.getAttribute('src')?.includes('lystra-logo-light.svg');
},
{ timeout: 5000 }
);

const finalSrc = await logo.getAttribute('src');
expect(finalSrc).toContain('lystra-logo-light.svg');
});
});
22 changes: 0 additions & 22 deletions test/nuxt/__snapshots__/app.nuxt.spec.ts.snap

This file was deleted.

56 changes: 56 additions & 0 deletions test/nuxt/__snapshots__/components.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`App > should match snapshot 1`] = `
"<div class="flex flex-col min-h-screen">
<div class="flex justify-between items-center px-4 md:px-8 lg:px-28 py-4"><a href="/" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer">
<!--v-if--><img width="40" height="40" alt="Lystra logo" data-nuxt-img="" srcset="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg 1x, /_ipx/b_transparent&amp;fit_contain&amp;s_80x80/lystra-logo-light.svg 2x" data-testid="logo" src="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg">
<h1 class="text-gray-900 dark:text-white text-lg font-bold">Lystra</h1>
<!--v-if-->
</a>
<div class="flex items-center gap-1.5"><button type="button" aria-label="Switch to dark mode" data-testid="color-mode-toggle" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer"><span class="iconify i-lucide:sun shrink-0 size-5" aria-hidden="true"></span>
<!--v-if-->
<!--v-if-->
</button>
<signed-out-stub></signed-out-stub>
<signed-in-stub></signed-in-stub>
</div>
</div>
<div></div>
</div>
<!--teleport start-->
<!--teleport end-->"
`;

exports[`DefaultLayout > should match snapshot 1`] = `
"<div class="flex flex-col min-h-screen">
<div class="flex justify-between items-center px-4 md:px-8 lg:px-28 py-4"><a href="/" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer">
<!--v-if--><img width="40" height="40" alt="Lystra logo" data-nuxt-img="" srcset="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg 1x, /_ipx/b_transparent&amp;fit_contain&amp;s_80x80/lystra-logo-light.svg 2x" data-testid="logo" src="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg">
<h1 class="text-gray-900 dark:text-white text-lg font-bold">Lystra</h1>
<!--v-if-->
</a>
<div class="flex items-center gap-1.5"><button type="button" aria-label="Switch to dark mode" data-testid="color-mode-toggle" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer"><span class="iconify i-lucide:sun shrink-0 size-5" aria-hidden="true"></span>
<!--v-if-->
<!--v-if-->
</button>
<signed-out-stub></signed-out-stub>
<signed-in-stub></signed-in-stub>
</div>
</div>
</div>"
`;

exports[`Header > should match snapshot 1`] = `
"<div class="flex justify-between items-center px-4 md:px-8 lg:px-28 py-4"><a href="/" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer">
<!--v-if--><img width="40" height="40" alt="Lystra logo" data-nuxt-img="" srcset="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg 1x, /_ipx/b_transparent&amp;fit_contain&amp;s_80x80/lystra-logo-light.svg 2x" data-testid="logo" src="/_ipx/b_transparent&amp;fit_contain&amp;s_40x40/lystra-logo-light.svg">
<h1 class="text-gray-900 dark:text-white text-lg font-bold">Lystra</h1>
<!--v-if-->
</a>
<div class="flex items-center gap-1.5"><button type="button" aria-label="Switch to dark mode" data-testid="color-mode-toggle" class="rounded-md font-medium inline-flex items-center disabled:cursor-not-allowed aria-disabled:cursor-not-allowed disabled:opacity-75 aria-disabled:opacity-75 transition-colors text-sm gap-1.5 text-default hover:bg-elevated active:bg-elevated focus:outline-none focus-visible:bg-elevated hover:disabled:bg-transparent dark:hover:disabled:bg-transparent hover:aria-disabled:bg-transparent dark:hover:aria-disabled:bg-transparent p-1.5 cursor-pointer"><span class="iconify i-lucide:sun shrink-0 size-5" aria-hidden="true"></span>
<!--v-if-->
<!--v-if-->
</button>
<signed-out-stub></signed-out-stub>
<signed-in-stub></signed-in-stub>
</div>
</div>"
`;
35 changes: 0 additions & 35 deletions test/nuxt/app.nuxt.spec.ts

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,73 @@
import { mountSuspended } from '@nuxt/test-utils/runtime';
import Header from '../../../app/components/Header/index.vue';
import App from '../../app/app.vue';
import Header from '../../app/components/Header/index.vue';
import DefaultLayout from '../../app/layouts/default.vue';
import { describe, expect, it, vi } from 'vitest';

describe('App', () => {
it('should match snapshot', async () => {
const wrapper = await mountSuspended(App, {
global: {
stubs: {
SignInButton: true,
SignedOut: true,
UserButton: true,
SignedIn: true,
},
},
});
expect(wrapper.html()).toMatchSnapshot();
});

it('should render properly', async () => {
const wrapper = await mountSuspended(App, {
global: {
stubs: {
SignInButton: true,
SignedOut: true,
UserButton: true,
SignedIn: true,
},
},
});
expect(wrapper.exists()).toBe(true);
});

// TODO: Add more tests as needed
});

describe('DefaultLayout', () => {
it('should match snapshot', async () => {
const wrapper = await mountSuspended(DefaultLayout, {
global: {
stubs: {
SignInButton: true,
SignedOut: true,
UserButton: true,
SignedIn: true,
},
},
});
expect(wrapper.html()).toMatchSnapshot();
});

it('should render properly', async () => {
const wrapper = await mountSuspended(DefaultLayout, {
global: {
stubs: {
SignInButton: true,
SignedOut: true,
UserButton: true,
SignedIn: true,
},
},
});
expect(wrapper.exists()).toBe(true);
});

// TODO: Add more tests as needed
});

describe('Header', () => {
it('should match snapshot', async () => {
const wrapper = await mountSuspended(Header, {
Expand Down Expand Up @@ -44,9 +110,7 @@ describe('Header', () => {
});
const logo = wrapper.find('img');
expect(logo.exists()).toBe(true);
expect(logo.attributes('src')).toBe(
'/_ipx/b_transparent&fit_contain&s_40x40/lystra-logo-light.svg'
);
expect(logo.attributes('src')).toContain('lystra-logo-light.svg');
expect(logo.attributes('alt')).toBe('Lystra logo');
expect(logo.attributes('width')).toBe('40');
expect(logo.attributes('height')).toBe('40');
Expand Down Expand Up @@ -120,7 +184,7 @@ describe('Header', () => {
useColorMode: () => colorMode,
}));

const HeaderWithMock = (await import('../../../app/components/Header/index.vue')).default;
const HeaderWithMock = (await import('../../app/components/Header/index.vue')).default;
const wrapper = await mountSuspended(HeaderWithMock, {
global: {
stubs: {
Expand Down
17 changes: 0 additions & 17 deletions test/nuxt/components/__snapshots__/Header.nuxt.spec.ts.snap

This file was deleted.

19 changes: 0 additions & 19 deletions test/nuxt/layouts/__snapshots__/default.nuxt.spec.ts.snap

This file was deleted.

Loading