Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests branch merge #4

Merged
merged 14 commits into from
May 13, 2022
Merged
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('wrongemail@apppwrite.io');
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', 'wrongemail@apppwrite.io');
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" />