From 26217a522b230b6f38ae39e889d9ba8478e5bff7 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Tue, 10 Jun 2025 17:38:15 +0200 Subject: [PATCH 1/5] test for create a user and use it as Kasse for a Konzert --- frontendtests/codecept.conf.ts | 2 + frontendtests/helpers/PageHelper.ts | 15 +++++++ frontendtests/pages/AdminPage.ts | 33 ++++++++++++++ frontendtests/pages/KonzertPage.ts | 58 ++++++++++++++++++++++++- frontendtests/pages/LoginPage.ts | 19 ++++++++ frontendtests/steps.d.ts | 4 ++ frontendtests/tests/06_benutzer_test.ts | 45 +++++++++++++++++++ 7 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 frontendtests/helpers/PageHelper.ts create mode 100644 frontendtests/pages/AdminPage.ts create mode 100644 frontendtests/pages/LoginPage.ts create mode 100644 frontendtests/tests/06_benutzer_test.ts 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..797ddc97 --- /dev/null +++ b/frontendtests/pages/AdminPage.ts @@ -0,0 +1,33 @@ +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.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..7033c742 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(konzertTitle: string) { + 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..a3312a8d --- /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(0.5); +} + +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/06_benutzer_test.ts b/frontendtests/tests/06_benutzer_test.ts new file mode 100644 index 00000000..d585345b --- /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(konzertTitle); + + I.waitForText("Kasse (Verantwortlich)", 2); + I.see(userName); + }, +); From 6919db0e6056dd30eb3122c6b23745e9547e11b4 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Tue, 10 Jun 2025 17:55:03 +0200 Subject: [PATCH 2/5] fix eslint --- frontendtests/pages/KonzertPage.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontendtests/pages/KonzertPage.ts b/frontendtests/pages/KonzertPage.ts index 7033c742..66d6fdee 100644 --- a/frontendtests/pages/KonzertPage.ts +++ b/frontendtests/pages/KonzertPage.ts @@ -37,7 +37,7 @@ export function deleteKonzert(konzertTitle: string) { I.deleteObjectInCollection("veranstaltungenstore", konzertTitle); } -export function openRequiredPeople(konzertTitle: string) { +export function openRequiredPeople() { I.click(".bi-universal-access"); } From 38a3abf961d5f498e5a7213a41ae12be09f9d502 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Tue, 10 Jun 2025 17:59:07 +0200 Subject: [PATCH 3/5] fix test --- frontendtests/tests/06_benutzer_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontendtests/tests/06_benutzer_test.ts b/frontendtests/tests/06_benutzer_test.ts index d585345b..e1453444 100644 --- a/frontendtests/tests/06_benutzer_test.ts +++ b/frontendtests/tests/06_benutzer_test.ts @@ -37,7 +37,7 @@ Scenario( await loginPage.login("admin", "admin"); konzertPage.openKonzertCollapsable(konzertTitle); - konzertPage.openRequiredPeople(konzertTitle); + konzertPage.openRequiredPeople(); I.waitForText("Kasse (Verantwortlich)", 2); I.see(userName); From 328b0d5b991efa3e8675bd04cfda608d009b6666 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Tue, 10 Jun 2025 18:54:17 +0200 Subject: [PATCH 4/5] stabilize tests --- frontendtests/pages/LoginPage.ts | 2 +- frontendtests/tests/02_konzert_anlegen_test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontendtests/pages/LoginPage.ts b/frontendtests/pages/LoginPage.ts index a3312a8d..a51c361a 100644 --- a/frontendtests/pages/LoginPage.ts +++ b/frontendtests/pages/LoginPage.ts @@ -6,7 +6,7 @@ export async function login(userName: string, password: string) { I.fillField("Benutzername", userName); I.fillField("Passwort", password); I.click("Anmelden"); - I.wait(0.5); + I.wait(1); } export async function logout(userName: string) { 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"); }); From f7bba72bed8e0343e46a96b9548401b488432b50 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Tue, 10 Jun 2025 19:30:03 +0200 Subject: [PATCH 5/5] next try to stabilize --- frontendtests/pages/AdminPage.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontendtests/pages/AdminPage.ts b/frontendtests/pages/AdminPage.ts index 797ddc97..1ef8cd2c 100644 --- a/frontendtests/pages/AdminPage.ts +++ b/frontendtests/pages/AdminPage.ts @@ -9,6 +9,7 @@ export function goToAdminBenutzer() { } export function createBenutzer(identifier: string) { + I.waitForText("Neuer Benutzer"); I.click("Neuer Benutzer"); I.fillField("#id", identifier);