diff --git a/frontendtests/codecept.conf.ts b/frontendtests/codecept.conf.ts index 7bcc44f3..2b9e9a74 100644 --- a/frontendtests/codecept.conf.ts +++ b/frontendtests/codecept.conf.ts @@ -70,6 +70,8 @@ export const config: CodeceptJS.MainConfig = { ortePage: "./pages/OrtePage", konzertPage: "./pages/KonzertPage", konzertGaestePage: "./pages/KonzertGaestePage", + adminPage: "./pages/AdminPage", + loginPage: "./pages/LoginPage", }, bootstrap: async () => { new SqliteHelper(config).createData("userstore", "admin"); diff --git a/frontendtests/helpers/PageHelper.ts b/frontendtests/helpers/PageHelper.ts new file mode 100644 index 00000000..319ec1c6 --- /dev/null +++ b/frontendtests/helpers/PageHelper.ts @@ -0,0 +1,15 @@ +const { I } = inject(); + +export const fillDropdown = (labelText: string, optionToSelect: string) => { + const formItem = locate(".ant-form-item").withDescendant( + locate("label").withText(labelText), + ); + I.click(formItem.find(".ant-select-selector")); + + I.fillField( + formItem.find(".ant-select-selection-search-input"), + optionToSelect, + ); + + I.click(locate(".ant-select-item-option-content").withText(optionToSelect)); +}; diff --git a/frontendtests/pages/AdminPage.ts b/frontendtests/pages/AdminPage.ts new file mode 100644 index 00000000..1ef8cd2c --- /dev/null +++ b/frontendtests/pages/AdminPage.ts @@ -0,0 +1,34 @@ +import { fillDropdown } from "../helpers/PageHelper"; + +const { I } = inject(); + +export function goToAdminBenutzer() { + I.amOnPage("/vue/users"); + + I.waitForText("Übersicht über die User"); +} + +export function createBenutzer(identifier: string) { + I.waitForText("Neuer Benutzer"); + I.click("Neuer Benutzer"); + + I.fillField("#id", identifier); + I.fillField("#password", identifier); + + I.fillField("#name", "Testuser " + identifier); + I.fillField("#email", "Testuser_" + identifier + "@google.com"); + + // TODO funktioniert noch nicht + I.click("Kasse"); + + I.fillField("#tel", "01797591061"); + + fillDropdown("T-Shirt", "M"); + fillDropdown("Rechte", "abendkasse"); + + I.click("Kassenfreigabe"); + + I.click("OK"); + + I.waitForText("Speichern erfolgreich"); +} diff --git a/frontendtests/pages/KonzertPage.ts b/frontendtests/pages/KonzertPage.ts index 6116a9d9..66d6fdee 100644 --- a/frontendtests/pages/KonzertPage.ts +++ b/frontendtests/pages/KonzertPage.ts @@ -14,12 +14,68 @@ export function goToEditKonzert(konzertTitle: string) { I.amOnPage("/vue/veranstaltungen"); I.waitForText(konzertTitle); - I.click(locate("span.ant-collapse-header-text").withText(konzertTitle)); + this.openKonzertCollapsable(konzertTitle); I.click(".bi-keyboard"); I.waitForText("Allgemein"); } +export function openKonzertCollapsable(konzertTitle: string) { + I.click(locate("span.ant-collapse-header-text").withText(konzertTitle)); +} + +export function setConfirmed(konzertTitle: string) { + this.goToEditKonzert(konzertTitle); + + I.click("Ist bestätigt"); + + I.click("Speichern"); + I.waitForText("Speichern erfolgreich"); +} + export function deleteKonzert(konzertTitle: string) { I.deleteObjectInCollection("veranstaltungenstore", konzertTitle); } + +export function openRequiredPeople() { + I.click(".bi-universal-access"); +} + +export function addRequiredKassePeople(konzertTitle: string) { + I.amOnPage("/vue/veranstaltungen"); + I.waitForText(konzertTitle); + + this.openKonzertCollapsable(konzertTitle); + + this.openRequiredPeople(konzertTitle); + + setRequiredPeople("Kasse (Verantwortlich)"); + setRequiredPeople("Kasse (Unterstützung)"); + + I.click("Speichern"); + I.waitForText("Speichern erfolgreich"); +} + +export function assignCurrentUserToRole( + konzertTitle: string, + role: string, + userName: string, +) { + this.openKonzertCollapsable(konzertTitle); + + const formItem = locate(".ant-list-item").withDescendant( + locate(".ant-list-item-meta-title").withText(role), + ); + I.click(formItem.find(".bi-plus-circle-fill")); + + I.waitForText(userName, 1, formItem); +} + +function setRequiredPeople(identifier: string) { + I.waitForText(identifier); + + const formItem = locate(".ant-form-item").withDescendant( + locate("label").withText(identifier), + ); + I.click(formItem.find(".ant-checkbox")); +} diff --git a/frontendtests/pages/LoginPage.ts b/frontendtests/pages/LoginPage.ts new file mode 100644 index 00000000..a51c361a --- /dev/null +++ b/frontendtests/pages/LoginPage.ts @@ -0,0 +1,19 @@ +const { I } = inject(); + +export async function login(userName: string, password: string) { + I.amOnPage("/"); + I.waitForText("Benutzername"); + I.fillField("Benutzername", userName); + I.fillField("Passwort", password); + I.click("Anmelden"); + I.wait(1); +} + +export async function logout(userName: string) { + I.click(locate(".ant-menu-submenu-title").withText(userName)); + + I.waitForText("Abmelden"); + I.click("Abmelden"); + + I.waitForText("Benutzername"); +} diff --git a/frontendtests/steps.d.ts b/frontendtests/steps.d.ts index b80b33fe..892a7c8d 100644 --- a/frontendtests/steps.d.ts +++ b/frontendtests/steps.d.ts @@ -3,6 +3,8 @@ type filters = typeof import("./helpers/filters"); type ortePage = typeof import("./pages/OrtePage"); type konzertPage = typeof import("./pages/KonzertPage"); type konzertGaestePage = typeof import("./pages/KonzertGaestePage"); +type adminPage = typeof import("./pages/AdminPage"); +type loginPage = typeof import("./pages/LoginPage"); type SqliteHelper = import("./helpers/SqliteHelper"); type ChaiWrapper = import("codeceptjs-chai"); @@ -15,6 +17,8 @@ declare namespace CodeceptJS { ortePage: ortePage; konzertPage: konzertPage; konzertGaestePage: konzertGaestePage; + adminPage: adminPage; + loginPage: loginPage; } interface Methods extends Playwright, SqliteHelper, ChaiWrapper {} interface I extends WithTranslation {} diff --git a/frontendtests/tests/02_konzert_anlegen_test.ts b/frontendtests/tests/02_konzert_anlegen_test.ts index 33257315..bc65c10c 100644 --- a/frontendtests/tests/02_konzert_anlegen_test.ts +++ b/frontendtests/tests/02_konzert_anlegen_test.ts @@ -51,6 +51,6 @@ Scenario("Erzeuge neues Konzert", async ({ I }) => { I.assertDeepEqual(res.endDate, "2020-03-20T19:00:00.000Z"); I.amOnPage("/vue/veranstaltungen"); - I.waitForText("Konzert #1"); + I.waitForText("Konzert #1", 2); I.see("Konzert #1"); }); diff --git a/frontendtests/tests/06_benutzer_test.ts b/frontendtests/tests/06_benutzer_test.ts new file mode 100644 index 00000000..e1453444 --- /dev/null +++ b/frontendtests/tests/06_benutzer_test.ts @@ -0,0 +1,45 @@ +Feature("Admin Benutzer"); + +Before(({ login }) => { + login("admin"); +}); + +Scenario( + "Erstelle Team Benutzer und weise ihn als Kasse (Verantwortlich) zu", + async ({ I, konzertPage, loginPage, adminPage }) => { + const konzertTitle = "TeamUserKasseKonzert1"; + konzertPage.createExampleKonzert(konzertTitle); + + konzertPage.addRequiredKassePeople(konzertTitle); + + konzertPage.setConfirmed(konzertTitle); + + adminPage.goToAdminBenutzer(); + + const randomInt = Math.floor(Math.random() * 9000) + 1000; + const userName = `AbendkasseHelfer_${randomInt}`; + adminPage.createBenutzer(userName); + + await loginPage.logout("admin"); + + await loginPage.login(userName, userName); + I.click("Danke"); + + I.waitForText(konzertTitle, 2); + konzertPage.assignCurrentUserToRole( + konzertTitle, + "Kasse (Verantwortlich)", + userName, + ); + + await loginPage.logout(userName); + + await loginPage.login("admin", "admin"); + + konzertPage.openKonzertCollapsable(konzertTitle); + konzertPage.openRequiredPeople(); + + I.waitForText("Kasse (Verantwortlich)", 2); + I.see(userName); + }, +);