adds tests

This commit is contained in:
Christian Beutel
2025-01-21 14:37:52 +01:00
parent c40e01d56c
commit 7571f6e9b9
10 changed files with 66 additions and 6 deletions

View File

@@ -33,6 +33,12 @@ export default defineConfig({
/* Configure projects for major browsers */ /* Configure projects for major browsers */
projects: [ projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ }, { name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'teardown', testMatch: /.*\.teardown\.ts/, use:
{
storageState: 'playwright/.auth/user.json',
}
},
// { // {
// name: 'firefox', // name: 'firefox',
@@ -46,6 +52,7 @@ export default defineConfig({
{ {
name: 'chromium', name: 'chromium',
// dependencies: ['setup'],
use: { use: {
...devices['Desktop Chrome'], ...devices['Desktop Chrome'],
storageState: 'playwright/.auth/user.json', storageState: 'playwright/.auth/user.json',

View File

@@ -8,7 +8,8 @@
export let large: boolean = false; export let large: boolean = false;
export let loading: boolean = false; export let loading: boolean = false;
export let disabled: boolean = false; export let disabled: boolean = false;
export let tooltip: string = ""; export let tooltip: string | undefined = undefined;
export let id: string | undefined = undefined
</script> </script>
<button <button
@@ -18,10 +19,11 @@
class:btn-large={large} class:btn-large={large}
class:btn-disabled={disabled || loading} class:btn-disabled={disabled || loading}
disabled={disabled || loading} disabled={disabled || loading}
class:tooltip={tooltip.length > 0} class:tooltip={(tooltip?.length ?? 0) > 0}
data-title={tooltip} data-title={tooltip}
on:click on:click
{type} {type}
{id}
> >
<div class:invisible={loading}> <div class:invisible={loading}>
{#if icon} {#if icon}

View File

@@ -25,7 +25,7 @@
<button class="btn-secondary" on:click={closeModal} <button class="btn-secondary" on:click={closeModal}
>{$_("cancel")}</button >{$_("cancel")}</button
> >
<button class={action === "delete" ? "btn-danger" : "btn-primary"} type="button" on:click={confirm} name="delete" <button id="confirm" class={action === "delete" ? "btn-danger" : "btn-primary"} type="button" on:click={confirm} name="delete"
>{$_(action)}</button >{$_(action)}</button
> >
</div></Modal </div></Modal

View File

@@ -117,6 +117,7 @@
error={$errors.password} error={$errors.password}
></TextField> ></TextField>
<Button <Button
id="submit"
primary={true} primary={true}
extraClasses={"min-w-full"} extraClasses={"min-w-full"}
type="submit" type="submit"

View File

@@ -94,7 +94,7 @@
<h4 class="text-xl text-red-400 font-medium"> <h4 class="text-xl text-red-400 font-medium">
{$_("danger-zone")} {$_("danger-zone")}
</h4> </h4>
<button class="btn-danger" on:click={openConfirmModal} <button id="delete-account" class="btn-danger" on:click={openConfirmModal}
>{$_("delete-account")}</button >{$_("delete-account")}</button
> >
</div> </div>

View File

@@ -2,11 +2,36 @@ import { test as setup } from '@playwright/test';
const authFile = 'playwright/.auth/user.json'; const authFile = 'playwright/.auth/user.json';
setup('authenticate', async ({ page }) => { setup('create user', async ({ page }) => {
await page.goto('/login', { waitUntil: 'networkidle' }); await page.goto('/login', { waitUntil: 'networkidle' });
await page.locator('input[name="username"]').fill('Test'); await page.locator('input[name="username"]').fill('Test');
await page.locator('input[name="password"]').fill('password'); await page.locator('input[name="password"]').fill('password');
const loginPromise = page.waitForResponse('**/api/v1/auth/login')
await page.getByRole('button', { name: 'Login' }).click(); await page.getByRole('button', { name: 'Login' }).click();
const response = await loginPromise;
let responseJson;
try {
responseJson = await response.json();
} catch (e) {
if (e instanceof Error && e.message.includes("No resource with given identifier found")) {
console.log("Already logged in!")
} else {
throw e
}
}
if (responseJson?.message === "Failed to authenticate.") {
await page.goto('/register', { waitUntil: 'networkidle' });
await page.locator('input[name="username"]').fill('Test');
await page.locator('input[name="email"]').fill('test@test.de');
await page.locator('input[name="password"]').fill('password');
await page.locator('#submit').click();
}
// Wait until the page receives the cookies. // Wait until the page receives the cookies.
// //
// Sometimes login flow sets cookies in the process of several redirects. // Sometimes login flow sets cookies in the process of several redirects.

View File

@@ -0,0 +1,9 @@
import { test as teardown } from '@playwright/test';
teardown('delete user', async ({ page }) => {
await page.goto('/settings/account', { waitUntil: 'networkidle' });
await page.locator("#delete-account").click();
await page.locator("#confirm").click();
await page.waitForURL('/');
});

View File

@@ -6,3 +6,10 @@ test('index page does not show error', async ({ page }) => {
await indexPage.goto() await indexPage.goto()
await indexPage.hasNoError() await indexPage.hasNoError()
}); });
test('location search works', async ({ page }) => {
const indexPage = new IndexPage(page);
await indexPage.goto()
await indexPage.search()
});

View File

@@ -13,6 +13,15 @@ export class IndexPage {
await this.page.goto('/'); await this.page.goto('/');
} }
async search() {
await this.page.locator('input[name="q"]').fill('Munich');
await this.page.waitForResponse('**/api/v1/search/multi');
await this.page.locator('.menu-item').first().click();
await this.page.waitForURL('/map?lat=48.13743&lon=11.57549');
}
async hasNoError() { async hasNoError() {
await expect(this.error).toHaveCount(0); await expect(this.error).toHaveCount(0);
} }

View File

@@ -20,7 +20,7 @@ export class ListsPage {
constructor(page: Page) { constructor(page: Page) {
this.page = page; this.page = page;
this.createListButton = page.locator("#create-list-button"); this.createListButton = page.locator("#create-list");
this.listModal = page.locator("#list-modal"); this.listModal = page.locator("#list-modal");
this.listModalAvatar = this.listModal.locator('input[name="avatar"]') this.listModalAvatar = this.listModal.locator('input[name="avatar"]')