From 62b08aba918964967a24df58dba789f5dc311dd5 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Wed, 21 May 2025 23:38:54 +0200 Subject: [PATCH 1/3] test to change, copy and delete guest list entries --- frontendtests/pages/KonzertGaestePage.ts | 30 ++++++++++++- frontendtests/tests/05_konzert_gaeste_test.ts | 44 ++++++++++++++++++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/frontendtests/pages/KonzertGaestePage.ts b/frontendtests/pages/KonzertGaestePage.ts index fad8271f..a7f08364 100644 --- a/frontendtests/pages/KonzertGaestePage.ts +++ b/frontendtests/pages/KonzertGaestePage.ts @@ -32,11 +32,28 @@ export async function setAlreadyIn(row: number, value: number) { I.click('[data-testid="alreadyIn' + row + '"]'); I.fillField("#alreadyIn", value); - // I.wait(5); + I.pressKey("Tab"); + + I.click(buttons.speichern); +} + +export async function changeGuestName(row: number, value: string) { + I.click('[data-testid="name' + row + '"]'); + I.fillField("#name", value); I.pressKey("Tab"); - // I.wait(5); + I.click(buttons.speichern); +} + +export async function copyGuest(row: number) { + I.click('[data-row-key="row' + row + '"] .bi-files'); + + I.click(buttons.speichern); +} + +export async function deleteRow(row: number) { + I.click('[data-row-key="row' + row + '"] .bi-trash'); I.click(buttons.speichern); } @@ -61,3 +78,12 @@ export async function verifyGuestInStore( key: "row" + index, }); } + +export async function verifyGuestStoreEmpty(konzertTitle: string) { + const res = await I.loadObjectInCollection( + "veranstaltungenstore", + konzertTitle, + ); + + I.assertEmpty(res.gaesteliste); +} diff --git a/frontendtests/tests/05_konzert_gaeste_test.ts b/frontendtests/tests/05_konzert_gaeste_test.ts index 1b868f42..25ac7811 100644 --- a/frontendtests/tests/05_konzert_gaeste_test.ts +++ b/frontendtests/tests/05_konzert_gaeste_test.ts @@ -7,10 +7,10 @@ Before(({ login }) => { Scenario( "Erstelle Gast in Gästeliste und setze alreadyIn", async ({ konzertPage, konzertGaestePage }) => { - const konzertTitle = "GaesteBeispiel"; + const konzertTitle = "GaesteCreate"; await konzertPage.createExampleKonzert(konzertTitle); - await konzertPage.goToEditKonzert(konzertTitle); + await konzertGaestePage.goToGaestePage(); const guest = { @@ -32,3 +32,43 @@ Scenario( }); }, ); + +Scenario( + "Erstelle Gast danach kopieren und löschen", + async ({ konzertPage, konzertGaestePage }) => { + const konzertTitle = "GaesteCopyDelete"; + await konzertPage.createExampleKonzert(konzertTitle); + await konzertPage.goToEditKonzert(konzertTitle); + + await konzertGaestePage.goToGaestePage(); + + const guest = { + name: "Stefan Rinderle", + comment: "Kommt später", + number: 2, + alreadyIn: 0, + }; + + await konzertGaestePage.addGaesteListe(guest); + await konzertGaestePage.verifyGuestInStore(konzertTitle, guest); + + await konzertGaestePage.copyGuest(0); + + const expectedChangedName = "Mario Rinderle"; + await konzertGaestePage.changeGuestName(1, expectedChangedName); + + const changedGuest = { + ...guest, + name: expectedChangedName, + }; + await konzertGaestePage.verifyGuestInStore(konzertTitle, changedGuest, 1); + + await konzertGaestePage.deleteRow(0); + + await konzertGaestePage.verifyGuestInStore(konzertTitle, changedGuest, 0); + + await konzertGaestePage.deleteRow(0); + + await konzertGaestePage.verifyGuestStoreEmpty(konzertTitle); + }, +); From 798f81f125d8780f28990ae3bd9d1fae7bec9c31 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Thu, 22 May 2025 12:28:56 +0200 Subject: [PATCH 2/3] test for reservations --- frontendtests/pages/KonzertGaestePage.ts | 136 ++++++++++++++++-- frontendtests/tests/05_konzert_gaeste_test.ts | 83 ++++++++++- 2 files changed, 202 insertions(+), 17 deletions(-) diff --git a/frontendtests/pages/KonzertGaestePage.ts b/frontendtests/pages/KonzertGaestePage.ts index a7f08364..4de97c47 100644 --- a/frontendtests/pages/KonzertGaestePage.ts +++ b/frontendtests/pages/KonzertGaestePage.ts @@ -1,14 +1,21 @@ const { I } = inject(); +const guestTabIdentifier = "Gästeliste"; +const reservationTabIdentifier = "Reservierungen"; + const buttons = { - addInTable: '(//button[@data-testid="add-in-table"])', speichern: "Speichern", + addInTable: locate("button").withAttr({ "data-testid": "add-in-table" }), }; +async function executeActionInTab(tabIdentifier: string, action: () => void) { + await within(locate(".ant-collapse-item").withText(tabIdentifier), action); +} + export async function goToGaestePage() { I.click(locate('div[role="tab"]').withText("Gäste am Abend")); - I.waitForText("Gästeliste"); + I.waitForText(guestTabIdentifier); } export async function addGaesteListe(guest: { @@ -17,7 +24,32 @@ export async function addGaesteListe(guest: { number: number; alreadyIn: number; }) { - I.click(buttons.addInTable); + await executeActionInTab(guestTabIdentifier, () => { + I.click(buttons.addInTable); + }); + + fillGuestDataInRow(guest); +} + +export async function addReservation(guest: { + name: string; + comment: string; + number: number; + alreadyIn: number; +}) { + await executeActionInTab(reservationTabIdentifier, () => { + I.click(buttons.addInTable); + }); + + fillGuestDataInRow(guest); +} + +function fillGuestDataInRow(guest: { + name: string; + comment: string; + number: number; + alreadyIn: number; +}) { I.click('[data-testid="name0"]'); I.fillField("#name", guest.name); I.pressKey("Tab"); @@ -28,17 +60,45 @@ export async function addGaesteListe(guest: { I.click(buttons.speichern); } -export async function setAlreadyIn(row: number, value: number) { - I.click('[data-testid="alreadyIn' + row + '"]'); +export async function setGuestAlreadyIn(row: number, value: number) { + await executeActionInTab(guestTabIdentifier, () => { + I.click('[data-testid="alreadyIn' + row + '"]'); + }); + I.fillField("#alreadyIn", value); + I.pressKey("Tab"); + + I.click(buttons.speichern); +} + +export async function setReservationAlreadyIn(row: number, value: number) { + await executeActionInTab(reservationTabIdentifier, () => { + I.click('[data-testid="alreadyIn' + row + '"]'); + }); + I.fillField("#alreadyIn", value); I.pressKey("Tab"); I.click(buttons.speichern); } export async function changeGuestName(row: number, value: string) { - I.click('[data-testid="name' + row + '"]'); + await executeActionInTab(guestTabIdentifier, () => { + I.click('[data-testid="name' + row + '"]'); + }); + + changeName(value); +} + +export async function changeReservationName(row: number, value: string) { + await executeActionInTab(reservationTabIdentifier, () => { + I.click('[data-testid="name' + row + '"]'); + }); + + changeName(value); +} + +function changeName(value: string) { I.fillField("#name", value); I.pressKey("Tab"); @@ -47,13 +107,33 @@ export async function changeGuestName(row: number, value: string) { } export async function copyGuest(row: number) { - I.click('[data-row-key="row' + row + '"] .bi-files'); + await executeActionInTab(guestTabIdentifier, () => { + I.click('[data-row-key="row' + row + '"] .bi-files'); + }); + + I.click(buttons.speichern); +} + +export async function copyReservation(row: number) { + await executeActionInTab(reservationTabIdentifier, () => { + I.click('[data-row-key="row' + row + '"] .bi-files'); + }); + + I.click(buttons.speichern); +} + +export async function deleteGuestRow(row: number) { + await executeActionInTab(guestTabIdentifier, () => { + I.click('[data-row-key="row' + row + '"] .bi-trash'); + }); I.click(buttons.speichern); } -export async function deleteRow(row: number) { - I.click('[data-row-key="row' + row + '"] .bi-trash'); +export async function deleteReservationRow(row: number) { + await executeActionInTab(reservationTabIdentifier, () => { + I.click('[data-row-key="row' + row + '"] .bi-trash'); + }); I.click(buttons.speichern); } @@ -68,7 +148,7 @@ export async function verifyGuestInStore( }, index: number = 0, ) { - const res = await I.loadObjectInCollection("veranstaltungenstore", title); + const res = await loadKonzertStoreData(title); I.assertDeepEqual(res.gaesteliste[index], { name: guest.name, @@ -79,11 +159,39 @@ export async function verifyGuestInStore( }); } +export async function verifyReservationInStore( + title: string, + guest: { + name: string; + comment: string; + number: number; + alreadyIn: number; + }, + index: number = 0, +) { + const res = await loadKonzertStoreData(title); + + I.assertDeepEqual(res.reservierungen[index], { + name: guest.name, + comment: guest.comment, + number: guest.number, + alreadyIn: guest.alreadyIn, + key: "row" + index, + }); +} + export async function verifyGuestStoreEmpty(konzertTitle: string) { - const res = await I.loadObjectInCollection( - "veranstaltungenstore", - konzertTitle, - ); + const res = await loadKonzertStoreData(konzertTitle); I.assertEmpty(res.gaesteliste); } + +export async function verifyReservationStoreEmpty(konzertTitle: string) { + const res = await loadKonzertStoreData(konzertTitle); + + I.assertEmpty(res.reservierungen); +} + +async function loadKonzertStoreData(konzertTitle: string) { + return await I.loadObjectInCollection("veranstaltungenstore", konzertTitle); +} diff --git a/frontendtests/tests/05_konzert_gaeste_test.ts b/frontendtests/tests/05_konzert_gaeste_test.ts index 25ac7811..c766f6be 100644 --- a/frontendtests/tests/05_konzert_gaeste_test.ts +++ b/frontendtests/tests/05_konzert_gaeste_test.ts @@ -24,7 +24,7 @@ Scenario( await konzertGaestePage.verifyGuestInStore(konzertTitle, guest); - await konzertGaestePage.setAlreadyIn(0, 1); + await konzertGaestePage.setGuestAlreadyIn(0, 1); await konzertGaestePage.verifyGuestInStore(konzertTitle, { ...guest, @@ -63,12 +63,89 @@ Scenario( }; await konzertGaestePage.verifyGuestInStore(konzertTitle, changedGuest, 1); - await konzertGaestePage.deleteRow(0); + await konzertGaestePage.deleteGuestRow(0); await konzertGaestePage.verifyGuestInStore(konzertTitle, changedGuest, 0); - await konzertGaestePage.deleteRow(0); + await konzertGaestePage.deleteGuestRow(0); await konzertGaestePage.verifyGuestStoreEmpty(konzertTitle); }, ); + +Scenario( + "Erstelle Reservierung und setze alreadyIn", + async ({ konzertPage, konzertGaestePage }) => { + const konzertTitle = "ReservationCreate"; + await konzertPage.createExampleKonzert(konzertTitle); + await konzertPage.goToEditKonzert(konzertTitle); + + await konzertGaestePage.goToGaestePage(); + + const guest = { + name: "Stefan Rinderle", + comment: "Freund von Schlagzeuger", + number: 12, + alreadyIn: 0, + }; + + await konzertGaestePage.addReservation(guest); + + await konzertGaestePage.verifyReservationInStore(konzertTitle, guest); + + await konzertGaestePage.setReservationAlreadyIn(0, 10); + + await konzertGaestePage.verifyReservationInStore(konzertTitle, { + ...guest, + alreadyIn: 10, + }); + }, +); + +Scenario( + "Erstelle Reservierung danach kopieren und löschen", + async ({ konzertPage, konzertGaestePage }) => { + const konzertTitle = "ReservationCopyDelete"; + await konzertPage.createExampleKonzert(konzertTitle); + await konzertPage.goToEditKonzert(konzertTitle); + + await konzertGaestePage.goToGaestePage(); + + const guest = { + name: "Stefan Rinderle", + comment: "Kommt später", + number: 2, + alreadyIn: 0, + }; + + await konzertGaestePage.addReservation(guest); + await konzertGaestePage.verifyReservationInStore(konzertTitle, guest); + + await konzertGaestePage.copyReservation(0); + + const expectedChangedName = "Mario Rinderle"; + await konzertGaestePage.changeReservationName(1, expectedChangedName); + + const changedGuest = { + ...guest, + name: expectedChangedName, + }; + await konzertGaestePage.verifyReservationInStore( + konzertTitle, + changedGuest, + 1, + ); + + await konzertGaestePage.deleteReservationRow(0); + + await konzertGaestePage.verifyReservationInStore( + konzertTitle, + changedGuest, + 0, + ); + + await konzertGaestePage.deleteReservationRow(0); + + await konzertGaestePage.verifyReservationStoreEmpty(konzertTitle); + }, +); From bceea158d0befa9ead0d98e8ee2f7b7f75569610 Mon Sep 17 00:00:00 2001 From: Stefan Rinderle Date: Thu, 22 May 2025 16:53:11 +0200 Subject: [PATCH 3/3] delete konzert after test --- frontendtests/pages/KonzertGaestePage.ts | 2 +- frontendtests/pages/KonzertPage.ts | 8 +++-- frontendtests/tests/05_konzert_gaeste_test.ts | 32 ++++++++++++------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/frontendtests/pages/KonzertGaestePage.ts b/frontendtests/pages/KonzertGaestePage.ts index 4de97c47..9a3b8935 100644 --- a/frontendtests/pages/KonzertGaestePage.ts +++ b/frontendtests/pages/KonzertGaestePage.ts @@ -12,7 +12,7 @@ async function executeActionInTab(tabIdentifier: string, action: () => void) { await within(locate(".ant-collapse-item").withText(tabIdentifier), action); } -export async function goToGaestePage() { +export function goToGaestePage() { I.click(locate('div[role="tab"]').withText("Gäste am Abend")); I.waitForText(guestTabIdentifier); diff --git a/frontendtests/pages/KonzertPage.ts b/frontendtests/pages/KonzertPage.ts index 2c952def..6116a9d9 100644 --- a/frontendtests/pages/KonzertPage.ts +++ b/frontendtests/pages/KonzertPage.ts @@ -1,6 +1,6 @@ const { I } = inject(); -export async function createExampleKonzert(title: string) { +export function createExampleKonzert(title: string) { I.createData("optionenstore", "optionen"); I.createData("optionenstore", "orte"); @@ -10,7 +10,7 @@ export async function createExampleKonzert(title: string) { I.createDataWithReplacer("veranstaltungenstore", "Replacervorlage", replacer); } -export async function goToEditKonzert(konzertTitle: string) { +export function goToEditKonzert(konzertTitle: string) { I.amOnPage("/vue/veranstaltungen"); I.waitForText(konzertTitle); @@ -19,3 +19,7 @@ export async function goToEditKonzert(konzertTitle: string) { I.click(".bi-keyboard"); I.waitForText("Allgemein"); } + +export function deleteKonzert(konzertTitle: string) { + I.deleteObjectInCollection("veranstaltungenstore", konzertTitle); +} diff --git a/frontendtests/tests/05_konzert_gaeste_test.ts b/frontendtests/tests/05_konzert_gaeste_test.ts index c766f6be..049523c2 100644 --- a/frontendtests/tests/05_konzert_gaeste_test.ts +++ b/frontendtests/tests/05_konzert_gaeste_test.ts @@ -8,10 +8,10 @@ Scenario( "Erstelle Gast in Gästeliste und setze alreadyIn", async ({ konzertPage, konzertGaestePage }) => { const konzertTitle = "GaesteCreate"; - await konzertPage.createExampleKonzert(konzertTitle); - await konzertPage.goToEditKonzert(konzertTitle); + konzertPage.createExampleKonzert(konzertTitle); + konzertPage.goToEditKonzert(konzertTitle); - await konzertGaestePage.goToGaestePage(); + konzertGaestePage.goToGaestePage(); const guest = { name: "Stefan Rinderle", @@ -30,6 +30,8 @@ Scenario( ...guest, alreadyIn: 1, }); + + konzertPage.deleteKonzert(konzertTitle); }, ); @@ -37,10 +39,10 @@ Scenario( "Erstelle Gast danach kopieren und löschen", async ({ konzertPage, konzertGaestePage }) => { const konzertTitle = "GaesteCopyDelete"; - await konzertPage.createExampleKonzert(konzertTitle); - await konzertPage.goToEditKonzert(konzertTitle); + konzertPage.createExampleKonzert(konzertTitle); + konzertPage.goToEditKonzert(konzertTitle); - await konzertGaestePage.goToGaestePage(); + konzertGaestePage.goToGaestePage(); const guest = { name: "Stefan Rinderle", @@ -70,6 +72,8 @@ Scenario( await konzertGaestePage.deleteGuestRow(0); await konzertGaestePage.verifyGuestStoreEmpty(konzertTitle); + + konzertPage.deleteKonzert(konzertTitle); }, ); @@ -77,10 +81,10 @@ Scenario( "Erstelle Reservierung und setze alreadyIn", async ({ konzertPage, konzertGaestePage }) => { const konzertTitle = "ReservationCreate"; - await konzertPage.createExampleKonzert(konzertTitle); - await konzertPage.goToEditKonzert(konzertTitle); + konzertPage.createExampleKonzert(konzertTitle); + konzertPage.goToEditKonzert(konzertTitle); - await konzertGaestePage.goToGaestePage(); + konzertGaestePage.goToGaestePage(); const guest = { name: "Stefan Rinderle", @@ -99,6 +103,8 @@ Scenario( ...guest, alreadyIn: 10, }); + + konzertPage.deleteKonzert(konzertTitle); }, ); @@ -106,10 +112,10 @@ Scenario( "Erstelle Reservierung danach kopieren und löschen", async ({ konzertPage, konzertGaestePage }) => { const konzertTitle = "ReservationCopyDelete"; - await konzertPage.createExampleKonzert(konzertTitle); - await konzertPage.goToEditKonzert(konzertTitle); + konzertPage.createExampleKonzert(konzertTitle); + konzertPage.goToEditKonzert(konzertTitle); - await konzertGaestePage.goToGaestePage(); + konzertGaestePage.goToGaestePage(); const guest = { name: "Stefan Rinderle", @@ -147,5 +153,7 @@ Scenario( await konzertGaestePage.deleteReservationRow(0); await konzertGaestePage.verifyReservationStoreEmpty(konzertTitle); + + konzertPage.deleteKonzert(konzertTitle); }, );