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
34 changes: 28 additions & 6 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ jobs:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 10

Expand All @@ -38,10 +38,10 @@ jobs:
matrix:
node: [20, 22, 24, 'lts/*']
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 10

Expand All @@ -61,25 +61,47 @@ jobs:
name: 🔬 Tests
timeout-minutes: 10
runs-on: ubuntu-latest
env:
VITE_BASE_URL: http://localhost:3000
strategy:
matrix:
node: [20, 22, 24, 'lts/*']
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- name: Install pnpm
uses: pnpm/action-setup@v2
uses: pnpm/action-setup@v4
with:
version: 10

- name: Get pnpm store directory
shell: bash
run: |
echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
cache: 'pnpm'

- name: Cache node modules
uses: actions/cache@v4
env:
cache-name: cache-node-modules
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-${{ env.cache-name }}-
${{ runner.os }}-pnpm-store-
${{ runner.os }}-

- name: Install deps
run: pnpm install

- name: Install Playwright Chromium
run: pnpm exec playwright install chromium --with-deps

- name: Run tests
run: SKIP_ENV_VALIDATION=true pnpm run test:ci
6 changes: 3 additions & 3 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ jobs:
- 5432:5432

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4

- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 20

Expand Down Expand Up @@ -73,7 +73,7 @@ jobs:
run: pnpm install

- name: Install Playwright Browsers
run: pnpm playwright install --with-deps
run: pnpm exec playwright install --with-deps

- name: Migrate database
run: pnpm db:push
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { expect, test, vi } from 'vitest';
import { axe } from 'vitest-axe';
import { z } from 'zod';

import { render, screen, setupUser } from '@/tests/utils';
import {
FAILED_CLICK_TIMEOUT_MS,
page,
render,
setupUser,
} from '@/tests/utils';

import { FormField, FormFieldController } from '..';
import { FormMocked } from '../form-test-utils';
Expand All @@ -14,36 +18,6 @@ const zFormSchema = () =>
}),
});

test('should have no a11y violations', async () => {
const mockedSubmit = vi.fn();

HTMLCanvasElement.prototype.getContext = vi.fn();

const { container } = render(
<FormMocked
schema={zFormSchema()}
useFormOptions={{ defaultValues: { lovesBears: false } }}
onSubmit={mockedSubmit}
>
{({ form }) => (
<FormField>
<FormFieldController
type="checkbox"
control={form.control}
name="lovesBears"
>
I love bears
</FormFieldController>
</FormField>
)}
</FormMocked>
);

const results = await axe(container);

expect(results).toHaveNoViolations();
});

test('should select checkbox on button click', async () => {
const user = setupUser();
const mockedSubmit = vi.fn();
Expand All @@ -68,13 +42,14 @@ test('should select checkbox on button click', async () => {
</FormMocked>
);

const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
expect(checkbox).not.toBeChecked();
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });

await expect.element(checkbox).not.toBeChecked();

await user.click(checkbox);
expect(checkbox).toBeChecked();
await expect.element(checkbox).toBeChecked();

await user.click(screen.getByRole('button', { name: 'Submit' }));
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
});

Expand Down Expand Up @@ -102,16 +77,16 @@ test('should select checkbox on label click', async () => {
</FormMocked>
);

const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
const label = screen.getByText('I love bears');
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
const label = page.getByText('I love bears');

expect(checkbox).not.toBeChecked();
await expect.element(checkbox).not.toBeChecked();

// Test clicking the label specifically
await user.click(label);
expect(checkbox).toBeChecked();
await expect.element(checkbox).toBeChecked();

await user.click(screen.getByRole('button', { name: 'Submit' }));
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
});

Expand All @@ -138,10 +113,10 @@ test('default value', async () => {
</FormMocked>
);

const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
expect(checkbox).toBeChecked();
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
await expect.element(checkbox).toBeChecked();

await user.click(screen.getByRole('button', { name: 'Submit' }));
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: true });
});

Expand Down Expand Up @@ -169,12 +144,18 @@ test('disabled', async () => {
</FormMocked>
);

const checkbox = screen.getByRole('checkbox', { name: 'I love bears' });
expect(checkbox).toBeDisabled();
expect(checkbox).not.toBeChecked();

await user.click(checkbox);
expect(checkbox).not.toBeChecked();
await user.click(screen.getByRole('button', { name: 'Submit' }));
const checkbox = page.getByRole('checkbox', { name: 'I love bears' });
await expect.element(checkbox).toBeDisabled();
await expect.element(checkbox).not.toBeChecked();

try {
await user.click(checkbox, {
trial: true,
timeout: FAILED_CLICK_TIMEOUT_MS,
});
} catch {
await expect.element(checkbox).not.toBeChecked();
}
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ lovesBears: undefined });
});
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { expect, test, vi } from 'vitest';
import { z } from 'zod';

import { render, screen, setupUser } from '@/tests/utils';
import {
FAILED_CLICK_TIMEOUT_MS,
page,
render,
setupUser,
} from '@/tests/utils';

import { FormField, FormFieldController, FormFieldLabel } from '..';
import { FormMocked } from '../form-test-utils';
Expand Down Expand Up @@ -29,10 +34,14 @@ test('update value', async () => {
)}
</FormMocked>
);
const input = screen.getByLabelText<HTMLInputElement>('Code');

const input = page.getByLabelText('Code');
await user.click(input);
await user.paste('000000');
await user.click(screen.getByRole('button', { name: 'Submit' }));
// Add the code to the user clipboard
await navigator.clipboard.writeText('000000');

await user.paste();
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
});

Expand Down Expand Up @@ -62,7 +71,7 @@ test('default value', async () => {
)}
</FormMocked>
);
await user.click(screen.getByRole('button', { name: 'Submit' }));
await user.click(page.getByRole('button', { name: 'Submit' }));
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
});

Expand Down Expand Up @@ -90,9 +99,11 @@ test('auto submit', async () => {
)}
</FormMocked>
);
const input = screen.getByLabelText<HTMLInputElement>('Code');
const input = page.getByLabelText('Code');
await user.click(input);
await user.paste('000000');
// Add the code to the user clipboard
await navigator.clipboard.writeText('000000');
await user.paste();
expect(mockedSubmit).toHaveBeenCalledWith({ code: '000000' });
});

Expand Down Expand Up @@ -120,9 +131,17 @@ test('disabled', async () => {
)}
</FormMocked>
);
const input = screen.getByLabelText<HTMLInputElement>('Code');
await user.click(input);
await user.paste('123456');
await user.click(screen.getByRole('button', { name: 'Submit' }));
const input = page.getByLabelText('Code');
try {
await user.click(input, { timeout: FAILED_CLICK_TIMEOUT_MS });
} catch {
// Click expected to fail since input is disabled
}
// Add the code to the user clipboard
await navigator.clipboard.writeText('123456');
await user.paste();

await user.click(page.getByRole('button', { name: 'Submit' }));

expect(mockedSubmit).toHaveBeenCalledWith({ code: undefined });
});
Loading
Loading