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
4 changes: 0 additions & 4 deletions src/lib/components/copy.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@

const copy = async () => {
try {
if (navigator.clipboard === undefined) {
//TODO: add fallback to old methods
throw new Error('Clipboard API only available to SSL');
}
await navigator.clipboard.writeText(value);
addNotification({
message: 'Copied to clipboard.',
Expand Down
2 changes: 1 addition & 1 deletion src/lib/elements/forms/inputSelect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<FormItem>
<label class="label" for={id}>{label}</label>
<div class="select">
<select bind:value {required} {disabled}>
<select bind:value {id} {required} {disabled}>
{#each options as option}
<option value={option.value} selected={option.value === value}>
{option.label}
Expand Down
51 changes: 50 additions & 1 deletion tests/e2e/login.spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,58 @@
import { expect, test } from '@playwright/test';

test('login page has inputs', async ({ page }) => {
/*TODO: Things to test in login:
- presence of forgot password link
- validation message on wrong input
- correct response and redirect after login
- logout works
- back button does not log out user
- forward button does not log in user after logout
- limit to total number of login attempts
-
*/

test('login page has inputs and button', async ({ page }) => {
await page.goto('/login');
const mail = page.locator('id=email');
const pass = page.locator('id=password');
const button = page.locator('button:has-text("Login")');
expect(await mail.isVisible());
expect(await pass.isVisible());
expect(await button.isVisible());
});

test('login page has a working sign up link', async ({ page }) => {
await page.goto('/login');
const signup = page.locator('a[href="/register"]');
expect(await signup.isVisible());
await signup.click();
await page.waitForNavigation();
expect(page.url()).toContain('/register');
expect(await page.locator('Register').isVisible());
});

test('login page inputs are navigable by keyboard', async ({ page }) => {
await page.goto('/login');
const mail = page.locator('id=email');
await mail.focus();
await page.keyboard.type('[email protected]');
await page.keyboard.press('Tab');
await page.keyboard.type('password');
await page.keyboard.press('Tab');
await page.keyboard.press('Enter');
expect(await page.locator('.toaster-item').isVisible());
expect(await page.locator('text=Invalid credentials').isVisible());
});

test('login page shows error & response is 401 with wrong inputs', async ({ page }) => {
await page.goto('/login');

await page.fill('id=email', '[email protected]');
await page.fill('id=password', 'wrongpassword');
await page.click('button:has-text("Login")');
page.on('response', (response) => {
expect(response.status()).toBe(401);
});
expect(await page.locator('.toaster-item').isVisible());
expect(await page.locator('text=Invalid credentials').isVisible());
});
31 changes: 31 additions & 0 deletions tests/unit/components/copy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import '@testing-library/jest-dom';
import { render, fireEvent } from '@testing-library/svelte';
import { Copy } from '../../../src/lib/components';

const value = 'This is a test';

test('shows copy component', () => {
const { getByRole } = render(Copy, { value });
const input = document.querySelector('input');
const button = getByRole('button');

expect(input).toBeInTheDocument();
expect(button).toBeInTheDocument();
expect(input).toHaveAttribute('type', 'text');
expect(input).toBeDisabled();
});

test('copy to clipboard function called on click', async () => {
const { getByRole } = render(Copy, { value });

Object.assign(window.navigator, {
clipboard: {
writeText: jest.fn().mockImplementation(() => Promise.resolve())
}
});

const button = getByRole('button');
await fireEvent.click(button);

expect(window.navigator.clipboard.writeText).toHaveBeenCalledWith('This is a test');
});
44 changes: 44 additions & 0 deletions tests/unit/components/dropList.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import '@testing-library/jest-dom';
import { render, fireEvent } from '@testing-library/svelte';
import { DropList } from '../../../src/lib/components';

const data = {
show: true,
position: 'top',
horizontal: 'right'
};

test('shows drop list component', () => {
render(DropList, { ...data });
const wrapper = document.querySelector('div');
const dropList = document.querySelector('ul');

expect(wrapper).toBeInTheDocument();
expect(dropList).toBeInTheDocument();
});

test('hide drop list on body click', async () => {
render(DropList, { ...data });
const body = document.querySelector('body');
const dropList = document.querySelector('ul');

await fireEvent.click(body);
expect(dropList).not.toBeInTheDocument();
});

test('hide drop list on wrapper click', async () => {
render(DropList, { ...data });
const wrapper = document.querySelector('div');
const dropList = document.querySelector('ul');

await fireEvent.click(wrapper);
expect(dropList).not.toBeInTheDocument();
});

test('drop list visible on list click', async () => {
render(DropList, { ...data });
const dropList = document.querySelector('ul');

await fireEvent.click(dropList);
expect(dropList).toBeInTheDocument();
});
65 changes: 65 additions & 0 deletions tests/unit/elements/inputCheckbox.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import '@testing-library/jest-dom';
import { render, fireEvent } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { InputCheckbox } from '../../../src/lib/elements/forms';

test('shows checkbox input', () => {
const { getByText, getByLabelText } = render(InputCheckbox, { id: 'input', label: 'checkbox' });
const checkbox = getByLabelText('checkbox');

expect(getByText('checkbox')).toBeInTheDocument();
expect(checkbox).toBeInTheDocument();
});

test('shows checkbox input - required', () => {
const { getByLabelText } = render(InputCheckbox, {
id: 'input',
label: 'checkbox',
required: true
});

expect(getByLabelText('checkbox')).toBeRequired();
});

test('shows checkbox input - disabled', () => {
const { getByLabelText } = render(InputCheckbox, {
id: 'input',
label: 'checkbox',
disabled: true
});

expect(getByLabelText('checkbox')).toBeDisabled();
});

test('state', async () => {
const { component, getByLabelText } = render(InputCheckbox, { id: 'input', label: 'checkbox' });
const checkbox = getByLabelText('checkbox');

expect(component.value).toEqual(false);
await userEvent.click(checkbox);
expect(component.value).toEqual(true);
});

test('state', async () => {
const { getByLabelText, component } = render(InputCheckbox, { id: 'input', label: 'checkbox' });
const checkbox = getByLabelText('checkbox');

expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);

await fireEvent.click(checkbox);
expect(checkbox).toBeChecked();
expect(component.value).toStrictEqual(true);

await fireEvent.click(checkbox);
expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);

component.value = true;
expect(checkbox).toBeChecked();
expect(component.value).toStrictEqual(true);

component.value = false;
expect(checkbox).not.toBeChecked();
expect(component.value).toStrictEqual(false);
});
53 changes: 53 additions & 0 deletions tests/unit/elements/inputRadio.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import '@testing-library/jest-dom';
import { render, fireEvent } from '@testing-library/svelte';
import { InputRadio } from '../../../src/lib/elements/forms';
import radioGroup from './radioGroup.test.svelte';

const data = {
id: 'radio',
label: 'radio',
group: 'radio',
value: 'radio',
name: 'radio'
};

test('shows label', () => {
const { getByText } = render(InputRadio, { ...data });

expect(getByText('radio')).toBeInTheDocument();
});

test('shows boolean input - required', () => {
const { getByRole } = render(InputRadio, { ...data, required: true });

expect(getByRole('radio')).toBeRequired();
});

test('shows boolean input - disabled', () => {
const { getByRole } = render(InputRadio, { ...data, disabled: true });

expect(getByRole('radio')).toBeDisabled();
});

test('state', async () => {
const { getByLabelText } = render(radioGroup);

const one = getByLabelText('one');
const two = getByLabelText('two');
const three = getByLabelText('three');

await fireEvent.click(one);
expect(one).toBeChecked();
expect(two).not.toBeChecked();
expect(three).not.toBeChecked();

await fireEvent.click(two);
expect(one).not.toBeChecked();
expect(two).toBeChecked();
expect(three).not.toBeChecked();

await fireEvent.click(three);
expect(one).not.toBeChecked();
expect(two).not.toBeChecked();
expect(three).toBeChecked();
});
75 changes: 75 additions & 0 deletions tests/unit/elements/inputSelect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import '@testing-library/jest-dom';
import { render } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import { InputSelect } from '../../../src/lib/elements/forms';

const options = [
{ value: '', label: 'None' },
{ value: '1', label: 'One' },
{ value: '2', label: 'Two' },
{ value: '3', label: 'Three' }
];

test('shows select input', () => {
const { getByText, getByLabelText } = render(InputSelect, {
id: 'select',
label: 'select',
options
});
const select = getByLabelText('select');

expect(getByText('select')).toBeInTheDocument();
expect(select).toBeInTheDocument();
});

test('shows options', () => {
const { getByText } = render(InputSelect, {
id: 'select',
label: 'select',
options
});

options.forEach((option) => {
expect(getByText(option.label)).toBeInTheDocument();
});
});

test('shows select input - required', () => {
const { getByLabelText } = render(InputSelect, {
id: 'select',
label: 'select',
options,
required: true
});

expect(getByLabelText('select')).toBeRequired();
});

test('shows select input - disabled', () => {
const { getByLabelText } = render(InputSelect, {
id: 'select',
label: 'select',
options,
disabled: true
});

expect(getByLabelText('select')).toBeDisabled();
});

test('state', async () => {
const { component, getByLabelText } = render(InputSelect, {
id: 'select',
label: 'select',
options,
value: ''
});
const select = getByLabelText('select');

expect(component.value).toEqual('');

await userEvent.selectOptions(select, '1');
expect(component.value).toEqual(options[1].value);

await userEvent.selectOptions(select, '2');
expect(component.value).toEqual(options[2].value);
});
7 changes: 7 additions & 0 deletions tests/unit/elements/radioGroup.test.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
import { InputRadio } from '../../../src/lib/elements/forms';
</script>

<InputRadio label="one" id="one" group="radio" value="1" name="radio" />
<InputRadio label="two" id="two" group="radio" value="2" name="radio" />
<InputRadio label="three" id="three" group="radio" value="3" name="radio" />