aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/e2e/a11y.spec.ts43
-rw-r--r--tests/e2e/auth.setup.ts42
-rw-r--r--tests/e2e/credentials.ts22
-rw-r--r--tests/e2e/login.spec.ts62
-rw-r--r--tests/e2e/logout.spec.ts15
-rw-r--r--tests/e2e/plugin-administration.spec.js22
-rw-r--r--tests/e2e/user-courseware.spec.js26
7 files changed, 232 insertions, 0 deletions
diff --git a/tests/e2e/a11y.spec.ts b/tests/e2e/a11y.spec.ts
new file mode 100644
index 0000000..7ff4981
--- /dev/null
+++ b/tests/e2e/a11y.spec.ts
@@ -0,0 +1,43 @@
+import { test, expect } from '@playwright/test';
+import AxeBuilder from '@axe-core/playwright';
+
+test.describe('Should not have any automatically detectable accessibility issues @a11y', () => {
+ test.describe('while not logged in', () => {
+ const pages = [
+ ['on homepage', 'index.php?cancel_login=1'],
+ ['on login page', 'index.php?again=yes'],
+ ['on password forgotten page', 'dispatch.php/new_password?cancel_login=1'],
+ ];
+
+ pages.forEach(async ([title, url]) =>
+ test(title, async ({ page, baseURL }) => {
+ await page.goto(url);
+ const accessibilityScanResults = await analyze(page);
+ expect(accessibilityScanResults.violations).toEqual([]);
+ })
+ );
+ });
+
+ test.describe('while logged in as author', () => {
+ const autorFile = 'tests/e2e/.auth/autor.json';
+ test.use({ storageState: autorFile });
+
+ const pages = [
+ ['on start page', 'dispatch.php/start'],
+ ['on profile page', 'dispatch.php/profile/index'],
+ ['on my courses page', 'dispatch.php/courses'],
+ ];
+
+ pages.forEach(async ([title, url]) =>
+ test(title, async ({ page, baseURL }) => {
+ await page.goto(url);
+ const accessibilityScanResults = await analyze(page);
+ expect(accessibilityScanResults.violations).toEqual([]);
+ })
+ );
+ });
+});
+
+function analyze(page) {
+ return new AxeBuilder({ page }).analyze();
+}
diff --git a/tests/e2e/auth.setup.ts b/tests/e2e/auth.setup.ts
new file mode 100644
index 0000000..c690f3a
--- /dev/null
+++ b/tests/e2e/auth.setup.ts
@@ -0,0 +1,42 @@
+import { test as setup, expect } from '@playwright/test';
+import { credentials } from './credentials.ts';
+
+const rootFile = 'tests/e2e/.auth/root.json';
+const adminFile = 'tests/e2e/.auth/admin.json';
+const dozentFile = 'tests/e2e/.auth/dozent.json';
+const tutorFile = 'tests/e2e/.auth/tutor.json';
+const autorFile = 'tests/e2e/.auth/autor.json';
+
+setup('authenticate as root', async ({ page }) => {
+ await login(page, credentials.root);
+ await page.context().storageState({ path: rootFile });
+});
+
+setup('authenticate as admin', async ({ page }) => {
+ await login(page, credentials.admin);
+ await page.context().storageState({ path: adminFile });
+});
+
+setup('authenticate as dozent', async ({ page }) => {
+ await login(page, credentials.dozent);
+ await page.context().storageState({ path: dozentFile });
+});
+
+setup('authenticate as tutor', async ({ page }) => {
+ await login(page, credentials.tutor);
+ await page.context().storageState({ path: tutorFile });
+});
+
+setup('authenticate as autor', async ({ page }) => {
+ await login(page, credentials.autor);
+ await page.context().storageState({ path: autorFile });
+});
+
+async function login(page, { username, password }) {
+ await page.goto('index.php?again=yes');
+
+ await page.getByLabel(/Benutzername/i).fill(username);
+ await page.getByLabel(/Passwort/i).fill(password);
+ await page.getByRole('button', { name: 'Anmelden' }).click();
+ await expect(page.locator('#avatar-menu-container')).toBeVisible();
+}
diff --git a/tests/e2e/credentials.ts b/tests/e2e/credentials.ts
new file mode 100644
index 0000000..bfae3cc
--- /dev/null
+++ b/tests/e2e/credentials.ts
@@ -0,0 +1,22 @@
+export const credentials = {
+ root: {
+ username: process.env.PLAYWRIGHT_CREDENTIALS_ROOT_USERNAME ?? 'root@studip',
+ password: process.env.PLAYWRIGHT_CREDENTIALS_ROOT_PASSWORD ?? 'testing',
+ },
+ admin: {
+ username: process.env.PLAYWRIGHT_CREDENTIALS_ADMIN_USERNAME ?? 'test_admin',
+ password: process.env.PLAYWRIGHT_CREDENTIALS_ADMIN_PASSWORD ?? 'testing',
+ },
+ dozent: {
+ username: process.env.PLAYWRIGHT_CREDENTIALS_DOZENT_USERNAME ?? 'test_dozent',
+ password: process.env.PLAYWRIGHT_CREDENTIALS_DOZENT_PASSWORD ?? 'testing',
+ },
+ tutor: {
+ username: process.env.PLAYWRIGHT_CREDENTIALS_TUTOR_USERNAME ?? 'test_tutor',
+ password: process.env.PLAYWRIGHT_CREDENTIALS_TUTOR_PASSWORD ?? 'testing',
+ },
+ autor: {
+ username: process.env.PLAYWRIGHT_CREDENTIALS_AUTOR_USERNAME ?? 'test_autor',
+ password: process.env.PLAYWRIGHT_CREDENTIALS_AUTOR_PASSWORD ?? 'testing',
+ },
+};
diff --git a/tests/e2e/login.spec.ts b/tests/e2e/login.spec.ts
new file mode 100644
index 0000000..95e44a6
--- /dev/null
+++ b/tests/e2e/login.spec.ts
@@ -0,0 +1,62 @@
+import { test, expect } from '@playwright/test';
+import { credentials } from './credentials.ts';
+
+test.describe('Loggin In - HTML Web Form @auth', () => {
+ test.describe('Coming from homepage', () => {
+ test('should take us to the login form @smoke', async ({ page, baseURL }) => {
+ await page.goto('');
+
+ await expect(page.locator('#loginbox')).toBeVisible();
+
+ const loginLink = page.getByRole('link', { name: 'Login für registrierte NutzerInnen' });
+ await expect(loginLink).toBeVisible();
+ await loginLink.click();
+
+ const benutzername = page.getByLabel(/Benutzername/i);
+ await expect(benutzername).toBeVisible();
+ await expect(benutzername).toBeEditable();
+
+ const passwort = page.getByLabel(/Passwort/i);
+ await expect(passwort).toBeVisible();
+ await expect(passwort).toBeEditable();
+ });
+ });
+
+ test.describe('Unauthorized', () => {
+ test('redirects to the login form @smoke', async ({ page }) => {
+ await page.goto('dispatch.php/start');
+
+ await expect(page.getByLabel(/Passwort/)).toBeVisible();
+ await expect(page.locator('#avatar-menu-container')).not.toBeVisible();
+ });
+ });
+
+ test.describe('HTML Form submission', () => {
+ test.beforeEach(async ({ page }) => {
+ await page.goto('index.php?again=yes');
+ });
+
+ test('displays error on invalid login', async ({ page }) => {
+ const benutzername = page.getByLabel(/Benutzername/i);
+ const passwort = page.getByLabel(/Passwort/i);
+ const submit = page.getByRole('button', { name: 'Anmelden' });
+
+ await benutzername.fill('username');
+ await passwort.fill('password');
+ await submit.click();
+ await expect(page.locator('css=.messagebox_error')).toBeVisible();
+ });
+
+ test('redirects to start page', async ({ page, baseURL }) => {
+ const benutzername = page.getByLabel(/Benutzername/i);
+ const passwort = page.getByLabel(/Passwort/i);
+ const submit = page.getByRole('button', { name: 'Anmelden' });
+
+ await benutzername.fill(credentials.autor.username);
+ await passwort.fill(credentials.autor.password);
+ await submit.click();
+ await expect(page.locator('#avatar-menu-container')).toBeVisible();
+ await expect(page).toHaveURL(`${baseURL}dispatch.php/start`);
+ });
+ });
+});
diff --git a/tests/e2e/logout.spec.ts b/tests/e2e/logout.spec.ts
new file mode 100644
index 0000000..bd87e0b
--- /dev/null
+++ b/tests/e2e/logout.spec.ts
@@ -0,0 +1,15 @@
+import { test, expect } from '@playwright/test';
+
+const dozentFile = 'tests/e2e/.auth/dozent.json';
+
+test.describe('Logging Out', () => {
+ test.use({ storageState: dozentFile });
+
+ test('should take us back to the homepage', async ({ page, baseURL }) => {
+ await page.goto(baseURL);
+ await expect(page.locator('#avatar-menu-container')).toBeVisible();
+ await page.getByTitle('Testaccount Dozent').click();
+ await page.getByRole('link', { name: 'Logout' }).click();
+ await expect(page).toHaveURL(/index\.php.*logout=true/);
+ });
+});
diff --git a/tests/e2e/plugin-administration.spec.js b/tests/e2e/plugin-administration.spec.js
new file mode 100644
index 0000000..7a84d68
--- /dev/null
+++ b/tests/e2e/plugin-administration.spec.js
@@ -0,0 +1,22 @@
+import { test, expect } from '@playwright/test';
+
+const rootFile = 'tests/e2e/.auth/root.json';
+
+test.describe('Visiting the plugin administration @root @plugins', () => {
+ test.use({ storageState: rootFile });
+
+ test('should let us deactivate and re-activate plugins', async ({ page }) => {
+ await page.goto('dispatch.php/admin/plugin');
+ const tableRow = await page.getByRole('row', { name: /TerminWidget/i });
+ const input = await tableRow.locator('input[name*=enabled]');
+ const saveButton = await page.getByRole('button', { name: 'Speichern' });
+
+ await input.uncheck();
+ await saveButton.click();
+ await expect(page.getByText('Plugin "TerminWidget" wurde deaktiviert')).toBeVisible();
+
+ await input.check();
+ await saveButton.click();
+ await expect(page.getByText('Plugin "TerminWidget" wurde aktiviert')).toBeVisible();
+ });
+});
diff --git a/tests/e2e/user-courseware.spec.js b/tests/e2e/user-courseware.spec.js
new file mode 100644
index 0000000..5fc220d
--- /dev/null
+++ b/tests/e2e/user-courseware.spec.js
@@ -0,0 +1,26 @@
+import { test, expect } from '@playwright/test';
+
+const autorFile = 'tests/e2e/.auth/autor.json';
+
+test.describe('Visiting my Arbeitsplatz @autor @courseware', () => {
+ test.use({ storageState: autorFile });
+
+ test('should let us create a new Lernmaterial', async ({ page }) => {
+ await page.goto('dispatch.php/start');
+ await page.getByRole('link', { name: /Courseware Erstellen/ }).click();
+ await page.getByRole('button', { name: 'Lernmaterial hinzufügen' }).click();
+ await page.getByLabel('Titel des Lernmaterials*').click();
+ await page.getByLabel('Titel des Lernmaterials*').fill('Ein Titel');
+ await page.getByLabel('Titel des Lernmaterials*').press('Tab');
+ await page.getByLabel('Beschreibung*').fill('Eine Beschreibung');
+ await page.getByRole('tab', { name: 'Erscheinung' }).click();
+ await page
+ .getByRole('combobox', { name: 'Search for option' })
+ .locator('div')
+ .filter({ hasText: 'Blau' })
+ .click();
+ await page.getByRole('button', { name: 'Erstellen' }).click();
+ const lernmaterial = await page.getByRole('link', { name: 'Ein Titel Eine Beschreibung' }).last();
+ await expect(lernmaterial).toBeVisible();
+ });
+});