diff options
| author | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2023-06-16 06:19:48 +0000 |
|---|---|---|
| committer | Marcus Eibrink-Lunzenauer <lunzenauer@elan-ev.de> | 2023-06-16 06:19:48 +0000 |
| commit | 91bd2c3e86f5fdaa5740ca536909ccd12f44b10e (patch) | |
| tree | 9646026525934c02521b26b4de66f816c54b202b /tests | |
| parent | 94abf115a32671423c2ea0a8e37c83cecf1ff6e6 (diff) | |
Add playwright tests, refs #2635
Merge request studip/studip!1790
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/e2e/a11y.spec.ts | 43 | ||||
| -rw-r--r-- | tests/e2e/auth.setup.ts | 42 | ||||
| -rw-r--r-- | tests/e2e/credentials.ts | 22 | ||||
| -rw-r--r-- | tests/e2e/login.spec.ts | 62 | ||||
| -rw-r--r-- | tests/e2e/logout.spec.ts | 15 | ||||
| -rw-r--r-- | tests/e2e/plugin-administration.spec.js | 22 | ||||
| -rw-r--r-- | tests/e2e/user-courseware.spec.js | 26 |
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(); + }); +}); |
