WIP: Tempus e2e tests

This commit is contained in:
Ivymaster
2026-05-27 10:29:13 +02:00
parent af3d96abc7
commit d948251736
9 changed files with 803 additions and 328 deletions
@@ -208,7 +208,7 @@ class Kalender extends FHCAPI_Controller
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess('Erfolgreich');
$this->terminateWithSuccess(getData($result));
}
public function getRaumvorschlag()
+1 -1
View File
@@ -630,7 +630,7 @@ class KalenderLib
if (isError($result)) return $result;
}
return success('Erfolgreich');
return success($result);
}
public function updateZeit($kalender_id, $start_date, $end_date)
+6 -2
View File
@@ -6,8 +6,12 @@ module.exports = defineConfig({
e2e: {
baseUrl: process.env.BASE_URL || "http://localhost:8080",
defaultCommandTimeout: 40000,
pageLoadTimeout: 20000,
defaultCommandTimeout: 20000,
pageLoadTimeout: 10000,
retries: {
runMode: 2, // when running via CLI / CI
openMode: 2 // when running in interactive mode
}
},
env: {
adminusername: process.env.USER_NAME || "2",
@@ -1,148 +0,0 @@
import { tempusPage } from "../../../support/pages/tempus.po";
context("Base tempus tests", () => {
beforeEach(() => {
cy.login();
cy.intercept({ method: "GET", url: "**/StgTree" }).as("fetchCourseTree");
cy.intercept({ method: "GET", url: /\/tempus\/Kalender\/getPlan(?:\?|$)/ }).as("fetchPlanData");
cy.intercept({ method: "GET", url: /\/tempus\/Kalender\/getPlanLecturer(?:\?|$)/ }).as("fetchLecturerPlanData");
cy.intercept({ method: "GET", url: /\/tempus\/Kalender\/getPlanStudent(?:\?|$)/ }).as("fetchStudentPlanData");
cy.intercept({ method: "GET", url: "**/tempus/Kalender/getHistory**" }).as("fetchEventHistory");
cy.intercept({ method: "GET", url: "**/tempus/coursepicker/getByStg**" }).as("fetchCoursePickerCourses");
tempusPage.visit();
cy.wait("@fetchCourseTree").its("response.statusCode").should("eq", 200);
cy.wait("@fetchPlanData").its("response.statusCode").should("eq", 200);
});
it("can access Tempus page with valid credentials", () => {
tempusPage.getTempusOverview().should("be.visible");
});
it ("shows all expected page elements", () => {
tempusPage.getTempusOverview().should("be.visible");
tempusPage.getSidebarMenu().should("exist");
tempusPage.getSlideInCoursesMenu().should("exist");
tempusPage.getCalendarSection().should("be.visible");
tempusPage.getPreviewRoleOptionsHolder().should("be.visible");
});
it("can open courses menu", () => {
tempusPage.getSlideInCoursesMenu().should("exist").should("be.hidden");
tempusPage.openCoursesMenu();
tempusPage.getCourseTreeRows().should("have.length.greaterThan", 0);
});
it("can select one course and show preview of its events", () => {
tempusPage.getSlideInCoursesMenu().should("exist");
tempusPage.getCourseTreeRows().should("have.length.greaterThan", 0);
tempusPage.getCoursePicker().should("exist");
tempusPage.getCoursePickerRows().should("have.length", 0);
tempusPage.selectFirstCourse();
cy.wait("@fetchCoursePickerCourses").its("response.statusCode").should("eq", 200);
tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
});
it("can search for a course event in the course picker", () => {
const searchTerm = "PHY1 SO";
tempusPage.selectFirstCourse();
cy.wait("@fetchCoursePickerCourses").its("response.statusCode").should("eq", 200);
tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
tempusPage.getCoursePickerSearchInput().type(searchTerm);
tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
tempusPage.getCoursePickerRows().first().should("contain.text", searchTerm);
});
it("can drag and drop one course event into the calendar", () => {
tempusPage.getCalendarSection().should("exist");
tempusPage.selectFirstCourse();
cy.wait("@fetchCoursePickerCourses").its("response.statusCode").should("eq", 200);
tempusPage.getCoursePickerRows().first().drag(tempusPage.selectors.calendarSection);
tempusPage.getCalendarEvents().should("have.length", 1);
});
it("shows the same number of calendar events for all role previews", () => {
const rolePreviews = [
{ label: "Planer", fetchAlias: "@fetchPlanData" },
{ label: "Lektor", fetchAlias: "@fetchLecturerPlanData" },
{ label: "Student", fetchAlias: "@fetchStudentPlanData" },
];
const eventCounts = {};
cy.wrap(rolePreviews).each((rolePreview) => {
tempusPage.selectPreviewRole(rolePreview.label);
cy.wait(rolePreview.fetchAlias).its("response.statusCode").should("eq", 200);
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarEvents().then(($events) => {
eventCounts[rolePreview.label] = $events.length;
});
}).then(() => {
const expectedCount = eventCounts[rolePreviews[0].label];
Object.entries(eventCounts).forEach(([role, count]) => {
expect(count, `${role} calendar event count`).to.eq(expectedCount);
});
});
});
it("shows event details modal when clicking a calendar event", () => {
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
tempusPage.getCalendarEvents().first().click();
tempusPage.getCalendarEventModal().should("be.visible");
});
it("shows event context menu when right clicking a calendar event", () => {
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
tempusPage.getCalendarEvents().first().rightclick();
tempusPage.getEventContextMenu().should("be.visible");
});
it("shows history modal when selecting History from event context menu", () => {
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
tempusPage.getCalendarEvents().first().rightclick();
tempusPage.getEventContextMenuOption("History").click();
cy.wait("@fetchEventHistory").its("response.statusCode").should("eq", 200);
tempusPage.getHistoryModal().should("be.visible");
});
it("shows reservation modal when dropping reservation handle on calendar", () => {
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarSection().should("be.visible");
tempusPage.getReservationDragHandle().drag(tempusPage.selectors.calendarSection);
tempusPage.getReservationModal().should("be.visible");
});
it("can drop event from calendar into parking slot", () => {
tempusPage.getEventParkingSlot().should("exist");
tempusPage.getParkedEvents().should("have.length", 0);
tempusPage.getCalendarEvents().first().drag(tempusPage.selectors.parkingSlot);
tempusPage.getParkedEvents().should("have.length", 1);
});
});
@@ -0,0 +1,710 @@
import { tempusPage } from "../../../../support/pages/tempus.po";
const PLANER = "Planer";
const LEKTOR = "Lektor";
const STUDENT = "Student";
const SYNC = "Sync";
const roleFetchAliases = {
[PLANER]: "@fetchPlanData",
[LEKTOR]: "@fetchLecturerPlanData",
[STUDENT]: "@fetchStudentPlanData",
};
const waitForOk = (alias) =>
cy.wait(alias).its("response.statusCode").should("eq", 200);
const syncAndReloadPlanner = () => {
tempusPage.selectPreviewRole(SYNC); // ensure all events are loaded
waitForOk("@syncCalendar");
waitForOk("@fetchPlanData");
tempusPage.waitForCalendarToFinishLoading();
};
const selectRoleAndWait = (role) => {
tempusPage.selectPreviewRole(role);
waitForOk(roleFetchAliases[role]);
tempusPage.waitForCalendarToFinishLoading();
};
const formatIsoDateTimeForKalenderApi = (isoDateTime) =>
isoDateTime.slice(0, 16).replace("T", " ");
let eventRestoreOnFailure = null;
context("Base tempus tests", () => {
beforeEach(() => {
cy.login();
cy.intercept({ method: "GET", url: "**/StgTree" }).as("fetchCourseTree");
cy.intercept({
method: "GET",
url: /\/tempus\/Kalender\/getPlan(?:\?|$)/,
}).as("fetchPlanData");
cy.intercept({
method: "GET",
url: /\/tempus\/Kalender\/getPlanLecturer(?:\?|$)/,
}).as("fetchLecturerPlanData");
cy.intercept({
method: "GET",
url: /\/tempus\/Kalender\/getPlanStudent(?:\?|$)/,
}).as("fetchStudentPlanData");
cy.intercept({ method: "GET", url: "**/tempus/Kalender/getHistory**" }).as(
"fetchEventHistory",
);
cy.intercept({
method: "GET",
url: "**/tempus/coursepicker/getByStg**",
}).as("fetchCoursePickerCourses");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/addKalenderEvent**",
}).as("addCalendarEvent");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/updateKalenderEvent**",
}).as("updateCalendarEvent");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/sync**",
}).as("syncCalendar");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/syncToLecturer**",
}).as("syncCalendarToLecturer");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/syncToStudent**",
}).as("syncCalendarToStudent");
cy.intercept({
method: "POST",
url: "**/tempus/Kalender/deleteEntry**",
}).as("deleteCalendarEvent");
tempusPage.visit();
waitForOk("@fetchCourseTree");
waitForOk("@fetchPlanData");
});
afterEach(function () {
const eventRestore = eventRestoreOnFailure;
eventRestoreOnFailure = null;
if (this.currentTest.state !== "failed" || !eventRestore) {
return;
}
return tempusPage
.restoreKalenderEventTime(
eventRestore.kalenderId,
eventRestore.startTime,
eventRestore.endTime,
{ failOnStatusCode: false },
)
.its("status")
.should("eq", 200);
});
// it("can access Tempus page with valid credentials", () => {
// tempusPage.getTempusOverview().should("be.visible");
// });
// it("shows all expected page elements", () => {
// tempusPage.getTempusOverview().should("be.visible");
// tempusPage.getSidebarMenu().should("exist");
// tempusPage.getSlideInCoursesMenu().should("exist");
// tempusPage.getCalendarSection().should("be.visible");
// tempusPage.getPreviewRoleOptionsHolder().should("be.visible");
// });
// it("can open courses menu", () => {
// tempusPage.getSlideInCoursesMenu().should("exist").should("be.hidden");
// tempusPage.openCoursesMenu();
// tempusPage.getCourseTreeRows().should("have.length.greaterThan", 0);
// });
// it("can select one course and show preview of its events", () => {
// tempusPage.getSlideInCoursesMenu().should("exist");
// tempusPage.getCourseTreeRows().should("have.length.greaterThan", 0);
// tempusPage.getCoursePicker().should("exist");
// tempusPage.getCoursePickerRows().should("have.length", 0);
// tempusPage.selectFirstCourse();
// waitForOk("@fetchCoursePickerCourses");
// tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
// });
// it("can search for a course event in the course picker", () => {
// tempusPage.selectFirstCourse();
// waitForOk("@fetchCoursePickerCourses");
// tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
// tempusPage
// .getCoursePickerRows()
// .last()
// .find("div:first span:first")
// .invoke("text")
// .as("randomCourseText");
// cy.get("@randomCourseText").then((randomCourseText) => {
// tempusPage.getCoursePickerSearchInput().type(randomCourseText);
// tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
// tempusPage
// .getCoursePickerRows()
// .first()
// .should("contain.text", randomCourseText);
// });
// });
// it("can drag and drop one course event into the calendar", () => {
// tempusPage.getCalendarSection().should("exist");
// tempusPage.waitForCalendarToFinishLoading();
// tempusPage.selectFirstCourse();
// waitForOk("@fetchCoursePickerCourses");
// tempusPage.getCalendarEvents().then(($events) => {
// cy.wrap($events.length).as("initialEventCount");
// });
// tempusPage.getCoursePickerRows().should("have.length.greaterThan", 0);
// tempusPage.dropCourseOnCalendarPart(0, 10);
// waitForOk("@addCalendarEvent");
// waitForOk("@fetchPlanData");
// tempusPage.waitForCalendarToFinishLoading();
// cy.get("@initialEventCount").then((initialEventCount) => {
// tempusPage
// .getCalendarEvents()
// .should("have.length", initialEventCount + 1);
// });
// });
// it("shows the same number of calendar events for all role previews", () => {
// const rolePreviews = [
// { label: PLANER, fetchAlias: roleFetchAliases[PLANER] },
// { label: LEKTOR, fetchAlias: roleFetchAliases[LEKTOR] },
// { label: STUDENT, fetchAlias: roleFetchAliases[STUDENT] },
// ];
// const eventCounts = {};
// syncAndReloadPlanner();
// cy.wrap(rolePreviews)
// .each((rolePreview) => {
// selectRoleAndWait(rolePreview.label);
// tempusPage.getCalendarEvents().then(($events) => {
// eventCounts[rolePreview.label] = $events.length;
// });
// })
// .then(() => {
// const expectedCount = eventCounts[rolePreviews[0].label];
// Object.entries(eventCounts).forEach(([role, count]) => {
// expect(count, `${role} calendar event count`).to.eq(expectedCount);
// });
// });
// });
// it("shows event details modal when clicking a calendar event", () => {
// tempusPage.waitForCalendarToFinishLoading();
// tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
// tempusPage.getCalendarEvents().first().click();
// tempusPage.getCalendarEventModal().should("be.visible");
// });
// it("shows event context menu when right clicking a calendar event", () => {
// tempusPage.waitForCalendarToFinishLoading();
// tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
// tempusPage.getCalendarEvents().first().rightclick();
// tempusPage.getEventContextMenu().should("be.visible");
// });
// it("shows history modal when selecting History from event context menu", () => {
// tempusPage.waitForCalendarToFinishLoading();
// tempusPage.getCalendarEvents().should("have.length.greaterThan", 0);
// tempusPage.getCalendarEvents().first().rightclick();
// tempusPage.getEventContextMenuOption("History").click();
// waitForOk("@fetchEventHistory");
// tempusPage.getHistoryModal().should("be.visible");
// });
// it.skip("shows reservation modal when dropping reservation handle on calendar", () => {
// tempusPage.waitForCalendarToFinishLoading();
// tempusPage.getCalendarBaseGrid().should("be.visible");
// cy.wait(1000); // wait for potential animations
// tempusPage
// .getReservationDragHandle()
// .drag(
// tempusPage.selectors.calendarBaseGrid + " .part-body:nth-of-type(18)",
// {
// waitForAnimations: false,
// animationDistanceThreshold: 0,
// },
// );
// cy.wait(3000); // wait for potential animations
// tempusPage.getReservationModal().should("be.visible");
// });
// it("can drop event from calendar into parking slot", () => {
// tempusPage.getEventParkingSlot().should("exist");
// tempusPage.getParkedEvents().should("have.length", 0);
// tempusPage
// .getCalendarEvents()
// .first()
// .drag(tempusPage.selectors.parkingSlot);
// tempusPage.getParkedEvents().should("have.length", 1);
// });
it("on planner event change shows unchanged event on other roles", () => {
syncAndReloadPlanner();
cy.get(".fhc-calendar-base-grid > div")
.last()
.invoke(
"css",
"overflow",
"hidden",
);
cy.wait(500); // ensure overflow change is applied before dragging, otherwise the drag can fail due to the calendar scrolling
tempusPage
.getCalendarEventsByTimeRange("08:00:00", "08:45:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
const eventData = JSON.parse(eventJSON);
const originalStartTime = formatIsoDateTimeForKalenderApi(
eventData.orig.isostart,
);
const originalEndTime = formatIsoDateTimeForKalenderApi(
eventData.orig.isoend,
);
let eventId = eventData?.id;
expect(eventId).to.exist;
tempusPage.dropEventOnCalendarPart(eventId, 2);
cy.wait("@updateCalendarEvent").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
const updatedEventId =
interception.response.body.data.retval.kalender_id;
eventRestoreOnFailure = {
kalenderId: updatedEventId,
startTime: originalStartTime,
endTime: originalEndTime,
};
cy.wrap(updatedEventId).as("updatedEventId");
});
waitForOk("@fetchPlanData");
cy.get("@updatedEventId").then((updatedEventId) => {
tempusPage.getEventGridRow(updatedEventId).then((gridRowStyle) => {
selectRoleAndWait(LEKTOR);
tempusPage.getEventGridRow(eventId).then((lecturerGridRow) => {
expect(lecturerGridRow).to.not.eq(gridRowStyle);
});
selectRoleAndWait(STUDENT);
tempusPage.getEventGridRow(eventId).then((studentGridRow) => {
expect(studentGridRow).to.not.eq(gridRowStyle);
});
});
});
});
cy.get(".fhc-calendar-base-grid > div:last-child()").invoke(
"css",
"overflow",
"auto",
);
});
it("sync after planner preview event change loads event in same way on all previews", () => {
syncAndReloadPlanner();
tempusPage
.getCalendarEventsByTimeRange("08:00:00", "08:45:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
const eventData = JSON.parse(eventJSON);
const originalStartTime = formatIsoDateTimeForKalenderApi(
eventData.orig.isostart,
);
const originalEndTime = formatIsoDateTimeForKalenderApi(
eventData.orig.isoend,
);
let eventId = eventData?.id;
expect(eventId).to.exist;
tempusPage.dropEventOnCalendarPart(eventId, 3, {
scrollIntoView: true,
});
cy.wait("@updateCalendarEvent").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
const updatedEventId =
interception.response.body.data.retval.kalender_id;
eventRestoreOnFailure = {
kalenderId: updatedEventId,
startTime: originalStartTime,
endTime: originalEndTime,
};
cy.wrap(updatedEventId).as("updatedEventId");
});
waitForOk("@fetchPlanData");
syncAndReloadPlanner();
cy.get("@updatedEventId").then((updatedEventId) => {
tempusPage.getEventGridRow(updatedEventId).then((gridRowStyle) => {
selectRoleAndWait(LEKTOR);
tempusPage
.getEventGridRow(updatedEventId)
.then((lecturerGridRow) => {
expect(lecturerGridRow).to.eq(gridRowStyle);
});
selectRoleAndWait(STUDENT);
tempusPage
.getEventGridRow(updatedEventId)
.then((studentGridRow) => {
expect(studentGridRow).to.eq(gridRowStyle);
});
});
});
});
});
it("live unlock after planner preview event change loads event in same way on planner and lektor, but not on student preview", () => {
syncAndReloadPlanner();
tempusPage
.getCalendarEventsByTimeRange("08:00:00", "08:45:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
let eventId = JSON.parse(eventJSON)?.id;
expect(eventId).to.exist;
tempusPage.dropEventOnCalendarPart(eventId, 4, {
scrollIntoView: true,
});
cy.wait("@updateCalendarEvent")
.its("response.body.data.retval.kalender_id")
.as("updatedEventId");
waitForOk("@fetchPlanData");
tempusPage.waitForCalendarToFinishLoading();
cy.get("@updatedEventId").then((updatedEventId) => {
tempusPage
.getCalendarEventById(updatedEventId)
.should("exist")
.rightclick();
tempusPage.getEventContextMenuOption("Freischalten für Live").click(); // TODO: Check wether live is for studnet
waitForOk("@syncCalendarToStudent");
tempusPage.getEventGridRow(updatedEventId).then((gridRowStyle) => {
selectRoleAndWait(LEKTOR);
tempusPage
.getEventGridRow(updatedEventId)
.then((lecturerGridRow) => {
expect(lecturerGridRow).to.eq(gridRowStyle);
});
selectRoleAndWait(STUDENT);
tempusPage.getEventGridRow(eventId).then((studentGridRow) => {
expect(studentGridRow).to.not.eq(gridRowStyle);
});
});
});
});
});
it("event change on lector preview is prohibited", () => {
syncAndReloadPlanner();
selectRoleAndWait(LEKTOR);
tempusPage
.getCalendarEventsByTimeRange("08:00:00", "08:45:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
let eventId = JSON.parse(eventJSON)?.id;
expect(eventId).to.exist;
tempusPage.dropEventOnCalendarPart(eventId, 15);
cy.get("@updateCalendarEvent").should("not.exist");
tempusPage.getEventGridRow(eventId).then((gridRowStyle) => {
selectRoleAndWait(LEKTOR);
tempusPage.getEventGridRow(eventId).then((lecturerGridRow) => {
expect(lecturerGridRow).to.eq(gridRowStyle);
});
selectRoleAndWait(STUDENT);
tempusPage.getEventGridRow(eventId).then((studentGridRow) => {
expect(studentGridRow).to.eq(gridRowStyle);
});
});
});
});
it("event change on student preview is prohibited", () => {
syncAndReloadPlanner();
selectRoleAndWait(STUDENT);
tempusPage
.getCalendarEventsByTimeRange("08:00:00", "08:45:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
let eventId = JSON.parse(eventJSON)?.id;
expect(eventId).to.exist;
tempusPage.dropEventOnCalendarPart(eventId, 15);
cy.get("@updateCalendarEvent").should("not.exist");
tempusPage.getEventGridRow(eventId).then((gridRowStyle) => {
selectRoleAndWait(LEKTOR);
tempusPage.getEventGridRow(eventId).then((lecturerGridRow) => {
expect(lecturerGridRow).to.eq(gridRowStyle);
});
selectRoleAndWait(STUDENT);
tempusPage.getEventGridRow(eventId).then((studentGridRow) => {
expect(studentGridRow).to.eq(gridRowStyle);
});
});
});
});
it("event deletion on planner preview preservers event on planner, but shows it as unsynced on lektor and student preview", () => {
syncAndReloadPlanner();
tempusPage
.getCalendarEvents()
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
let eventId = JSON.parse(eventJSON)?.id;
expect(eventId).to.exist;
tempusPage
.getCalendarEventById(eventId)
.should("be.visible")
.rightclick();
tempusPage.getEventContextMenuOption("Delete").click();
cy.wait("@deleteCalendarEvent");
waitForOk("@fetchPlanData");
tempusPage.waitForCalendarToFinishLoading();
tempusPage.getCalendarEventById(eventId).should("be.visible");
selectRoleAndWait(LEKTOR);
tempusPage.getCalendarEventById(eventId).should("not.exist");
selectRoleAndWait(STUDENT);
tempusPage.getCalendarEventById(eventId).should("not.exist");
});
});
it("syncing event deletion on planner preview removes event from other previews", () => {
syncAndReloadPlanner();
tempusPage
.getCalendarEvents()
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
expect(eventJSON).to.exist;
let eventId = JSON.parse(eventJSON)?.id;
expect(eventId).to.exist;
tempusPage
.getCalendarEventById(eventId)
.should("be.visible")
.rightclick();
tempusPage.getEventContextMenuOption("Delete").click();
cy.wait("@deleteCalendarEvent");
waitForOk("@fetchPlanData");
syncAndReloadPlanner();
tempusPage.getCalendarEventById(eventId).should("not.exist");
selectRoleAndWait(LEKTOR);
tempusPage.getCalendarEventById(eventId).should("not.exist");
selectRoleAndWait(STUDENT);
tempusPage.getCalendarEventById(eventId).should("not.exist");
});
});
it("can bottom resize an event on planner preview", () => {
tempusPage.getCalendarSection().should("exist");
tempusPage.waitForCalendarToFinishLoading();
tempusPage
.getCalendarEventsByStartTime("08:00:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
cy.wrap(JSON.parse(eventJSON)).its("id").as("eventId");
cy.wrap(JSON.parse(eventJSON).orig)
.its("beginn")
.as("originalEventStart");
cy.wrap(JSON.parse(eventJSON).orig).its("ende").as("originalEventEnd");
});
cy.get("@eventId").then((eventId) => {
tempusPage
.getCalendarEventById(eventId)
.find(".fhc-resize-bar--bottom")
.first()
.realHover()
.realMouseDown("center", {
button: "left",
})
.realMouseMove(0, 120)
.realMouseUp();
cy.wait("@updateCalendarEvent").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
const updatedEventId =
interception.response.body.data.retval.kalender_id;
cy.wrap(updatedEventId).as("updatedEventId");
});
waitForOk("@fetchPlanData");
cy.get("@updatedEventId").then((updatedEventId) => {
tempusPage
.getCalendarEventById(updatedEventId)
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
let newEventStart = JSON.parse(eventJSON)?.orig?.beginn;
let newEventEnd = JSON.parse(eventJSON)?.orig?.ende;
cy.get("@originalEventStart").then((originalEventStart) => {
expect(newEventStart).to.eq(originalEventStart);
});
cy.get("@originalEventEnd").then((originalEventEnd) => {
expect(newEventEnd).to.not.eq(originalEventEnd);
});
});
});
});
});
it("can top resize an event on planner preview", () => {
tempusPage.getCalendarSection().should("exist");
tempusPage.waitForCalendarToFinishLoading();
tempusPage
.getCalendarEventsByStartTime("09:40:00")
.first()
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
cy.wrap(JSON.parse(eventJSON)).its("id").as("eventId");
cy.wrap(JSON.parse(eventJSON).orig)
.its("beginn")
.as("originalEventStart");
cy.wrap(JSON.parse(eventJSON).orig).its("ende").as("originalEventEnd");
});
cy.get("@eventId").then((eventId) => {
tempusPage
.getCalendarEventById(eventId)
.find(".fhc-resize-bar--top")
.first()
.realHover()
.realMouseDown("center", {
button: "left",
})
.realMouseMove(0, -40)
.realMouseUp();
cy.wait("@updateCalendarEvent").then((interception) => {
expect(interception.response.statusCode).to.eq(200);
const updatedEventId =
interception.response.body.data.retval.kalender_id;
cy.wrap(updatedEventId).as("updatedEventId");
});
waitForOk("@fetchPlanData");
cy.get("@updatedEventId").then((updatedEventId) => {
tempusPage
.getCalendarEventById(updatedEventId)
.invoke("attr", "data-fhc-draggable-value")
.then((eventJSON) => {
let newEventStart = JSON.parse(eventJSON)?.orig?.beginn;
let newEventEnd = JSON.parse(eventJSON)?.orig?.ende;
cy.get("@originalEventStart").then((originalEventStart) => {
expect(newEventStart).to.not.eq(originalEventStart);
});
cy.get("@originalEventEnd").then((originalEventEnd) => {
expect(newEventEnd).to.eq(originalEventEnd);
});
});
});
});
});
// check live issue -- done
// check delete -- DONE
// resize - dones
// sve al bez stunden raster
// course picker search
// raumauswal
// btn click to current semester
// filter za raum und fuer person
// filter ode u sidebar
});
@@ -25,6 +25,7 @@
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
require("@4tw/cypress-drag-drop");
require("cypress-real-events")
Cypress.Commands.add("login", () => {
const { adminusername, adminpassword, loginAsUser } = Cypress.env();
@@ -1,6 +1,7 @@
class TempusPage {
selectors = {
calendarSection: "div[data-cy='tempus'] .fhc-calendar-base",
calendarBaseGrid: "div[data-cy='tempus'] .fhc-calendar-base-grid",
parkingSlot: "div[data-cy='tempus'] #parkingslot",
};
@@ -14,6 +15,7 @@ class TempusPage {
getSlideInCoursesMenu = () => cy.get("div[data-cy='verbandMenu']");
getSidebarMenu = () => this.getTempusOverview().find("#sidebarMenu");
getCalendarSection = () => this.getTempusOverview().find(".fhc-calendar-base");
getCalendarBaseGrid = () => this.getCalendarSection().find(".fhc-calendar-base-grid");
getCoursePicker = () => this.getTempusOverview().find(".course-picker");
getPreviewRoleOptionsHolder = () => this.getTempusOverview().find("[data-cy='previewRoleOptionsHolder']");
getAllCoursesSliderBtn = () => this.getSidebarMenu().find("button[title='Verband']").first();
@@ -21,6 +23,76 @@ class TempusPage {
getCoursePickerRows = () => this.getCoursePicker().find(".course-picker-row");
getCoursePickerSearchInput = () => this.getCoursePicker().find("input");
getCalendarEvents = () => this.getCalendarSection().find(".fhc-calendar-base-grid-line-event");
getCalendarEventById = (id) => this.getCalendarEvents().filter(`div[data-id="event-${id}"]`);
getCalendarPartDropTarget = (partIndex) =>
`${this.selectors.calendarBaseGrid} .part-body:nth-of-type(${partIndex})`;
dropEventOnCalendarPart = (eventId, partIndex, options = {}) => {
const { scrollIntoView = false, ...dragOptions } = options;
const event = this.getCalendarEventById(eventId);
const eventToDrag = scrollIntoView ? event.scrollIntoView() : event;
return eventToDrag.should("be.visible").focus().drag(
this.getCalendarPartDropTarget(partIndex),
{
waitForAnimations: false,
animationDistanceThreshold: 0,
scrollBehavior: false,
...dragOptions,
},
);
};
dropCourseOnCalendarPart = (courseIndex, partIndex, options = {}) => {
const { scrollIntoView = false, ...dragOptions } = options;
const course = this.getCoursePickerRows().eq(courseIndex);
const courseToDrag = scrollIntoView ? course.scrollIntoView() : course;
return courseToDrag.should("be.visible").drag(
this.getCalendarPartDropTarget(partIndex),
{
waitForAnimations: false,
animationDistanceThreshold: 0,
...dragOptions,
},
);
};
updateKalenderEvent = (kalenderId, updatedInfos, options = {}) =>
cy.request({
method: "POST",
url: "/index.ci.php/api/frontend/v1/tempus/Kalender/updateKalenderEvent",
body: {
kalender_id: kalenderId,
updatedInfos,
},
...options,
});
restoreKalenderEventTime = (kalenderId, startTime, endTime, options = {}) =>
this.updateKalenderEvent(
kalenderId,
{
start_time: startTime,
end_time: endTime,
},
options,
);
getEventGridRowFromStyle = (style) =>
/grid-row:\s*([^;]+)/.exec(style)?.[1]?.trim();
getEventGridRow = (id) =>
this.getCalendarEventById(id)
.invoke("attr", "style")
.then((style) => this.getEventGridRowFromStyle(style));
getCalendarEventsByStartTime = (startTime) => this.getCalendarEvents().filter((index, event) => {
const eventData = JSON.parse(event.getAttribute("data-fhc-draggable-value"));
return eventData?.orig?.beginn === startTime;
});
getCalendarEventsByEndTime = (endTime) => this.getCalendarEvents().filter((index, event) => {
const eventData = JSON.parse(event.getAttribute("data-fhc-draggable-value"));
return eventData?.orig?.ende === endTime;
});
getCalendarEventsByTimeRange = (startTime, endTime) => this.getCalendarEvents().filter((index, event) => {
const eventData = JSON.parse(event.getAttribute("data-fhc-draggable-value"));
return eventData?.orig?.beginn === startTime && eventData?.orig?.ende === endTime;
});
getCalendarLoadingEvents = () => this.getCalendarSection().find(".placeholder-glow");
getCalendarEventModal = () => this.getCalendarSection().find(".bootstrap-modal.show");
getEventContextMenu = () => cy.get("[data-cy='eventContextMenu']");
+11 -176
View File
File diff suppressed because it is too large Load Diff
+1
View File
@@ -4,6 +4,7 @@
"cypress": "^15.11.0"
},
"dependencies": {
"cypress-real-events": "^1.15.0",
"dotenv": "^17.4.2"
}
}