diff --git a/cypress/e2e/course/addCtlToolToCourse.feature b/cypress/e2e/course/addCtlToolToCourse.feature new file mode 100644 index 00000000..56ef562a --- /dev/null +++ b/cypress/e2e/course/addCtlToolToCourse.feature @@ -0,0 +1,24 @@ +@release +Feature: Course - To add a ctl tool to a course + + As a teacher I want to add a new ctl tool to my course. + + @stable_test + Scenario: Student cant see the button to add a tool + Given I am logged in as a 'student2_nbc' at 'nbc' + When I go to rooms overview + When I go to room 'German' + When I click on the tools tab + Then I cant see the button to add a tool + + @stable_test + Scenario: Teacher adds a tool to a course + Given I am logged in as a 'teacher1_nbc' at 'nbc' + When I go to rooms overview + When I go to room 'German' + When I click on the tools tab + Then I can see the button to add a tool + When I click on the button to add a tool + Then I can see the tool configuration page title + When I click on the tool configuration selection + Then I can enter 'Test' as tool name in the selection diff --git a/cypress/e2e/course/createEditAndDeleteCourse.feature b/cypress/e2e/course/createEditAndDeleteCourse.feature index 9aa8a746..6678600b 100644 --- a/cypress/e2e/course/createEditAndDeleteCourse.feature +++ b/cypress/e2e/course/createEditAndDeleteCourse.feature @@ -49,3 +49,79 @@ Feature: Course - To add and delete a course by the teacher Then I see the modal to confirm the deletion When I click on the button delete on the modal to confirm the course deletion Then I do not see the course 'Cypress Testkurs Edit' on the room overview page + + @stable_test + Scenario: as a pre-condition teacher deletes undeleted tests + Given I am logged in as a 'teacher1_nbc' at 'nbc' + When I go to rooms overview + When I delete all courses named 'Cypress Test Creation and Deletion' + Then I do not see the course 'Cypress Test Creation and Deletion' on the room overview page + When I delete all courses named 'Cypress Testkurs Edit' + Then I do not see the course 'Cypress Testkurs Edit' on the room overview page + + @stable_test + Scenario: Create, edit and delete a course with groups of type class in nbc + Given I am logged in as a 'teacher1_nbc' at 'nbc' + When I go to rooms overview + Then I see room search box on the room overview page + When I click on FAB to create a new room + Then I see section one area on the course create page + When I enter the course title 'Cypress Test Creation and Deletion' + When I select room colour as red + Then I see teacher 'Karl Herzog' is selected by default + Then I see substitute teacher selection box + Then I see date pickers to start and end the course as per school year + Then I see button to create a course time table container + When I click on button Next Steps after entering the room detail in section one + Then I see section two area on the course create page + When I click on button Next Steps after selecting room participant details + Then I see the section three area as the finish page + When I click on button To Course Overview on the finish page + Then I see the course 'Cypress Test Creation and Deletion' on the room overview page + + # Editing the course + When I go to room 'Cypress Test Creation and Deletion' + When I open course edit page + Then I can see course edit page + When I edit the title of the room to 'Cypress Testkurs Edit' + When I edit the room description to 'cy edit this is test description' + + # Add groups to course + When I click on the selection box to add a new group with ' Cypress-Test-Group1 | moin.schule ' + When I click on the selection box to add a new group with ' Cypress-Test-Group2 | moin.schule ' + When I click on save changes after editing the course details + Then I see the course 'Cypress Testkurs Edit' on the room overview page + When I open course edit page + Then I see ' Cypress-Test-Group1 | moin.schule ' in the class selection box + Then I see 'Kraft, Herbert' in the student selection box + + # Remove one group from course + When I click on the remove icon of group ' Cypress-Test-Group2 | moin.schule ' + When I click on save changes after editing the course details + Then I see the course 'Cypress Testkurs Edit' on the room overview page + When I open course edit page + Then I see ' Cypress-Test-Group1 | moin.schule ' in the class selection box + Then I do not see ' Cypress-Test-Group2 | moin.schule ' in the group selection box + Then I see 'Kraft, Herbert' in the student selection box + Then I do not see 'Strobl, Amelia' in the student selection box + + # Remove second group from course + When I click on the remove icon of group ' Cypress-Test-Group1 | moin.schule ' + When I click on save changes after editing the course details + Then I see the course 'Cypress Testkurs Edit' on the room overview page + When I open course edit page + Then I do not see ' Cypress-Test-Group1 | moin.schule ' in the group selection box + Then I do not see ' Cypress-Test-Group2 | moin.schule ' in the group selection box + Then I do not see 'Strobl, Amelia' in the student selection box + Then I do not see 'Kraft, Herbert' in the student selection box + When I click on save changes after editing the course details + Then I see the course 'Cypress Testkurs Edit' on the room overview page + + + # Deleting the course/room created in this feature test + When I open course edit page + When I click on the button delete course + Then I see the modal to confirm the deletion + When I click on the button delete on the modal to confirm the course deletion + Then I do not see the course 'Cypress Testkurs Edit' on the room overview page + diff --git a/cypress/e2e/account/changeLanguage.feature b/cypress/e2e/dashboard/changeLanguage.feature similarity index 100% rename from cypress/e2e/account/changeLanguage.feature rename to cypress/e2e/dashboard/changeLanguage.feature diff --git a/cypress/e2e/group/groupMembers.feature b/cypress/e2e/group/groupMembers.feature new file mode 100644 index 00000000..6f7a5ff8 --- /dev/null +++ b/cypress/e2e/group/groupMembers.feature @@ -0,0 +1,20 @@ +@release +Feature: Group - To show members in a group + + As a teacher I want to see the members in a group + + @stable_test + Scenario: As a teacher I can manage a group of type class from external systems + Given I am logged in as a 'teacher1_nbc' at 'nbc' + When I go to administration page + And I go to new class administration page + Then I see the new class administration page + And I can see the group 'Cypress-Test-Group' with source 'moin.schule' + And the group 'Cypress-Test-Group' has a manage button + When I click the manage group button + Then I can see the manage group page + And I can see the manage group page title + And I can see the group member table + And I can see the 'Lehrkraft' with name 'Herzog' + And I can see the infobox + And I can see the infotext diff --git a/cypress/e2e/group/showGroupsAndClassesInTable.feature b/cypress/e2e/group/showGroupsAndClassesInTable.feature new file mode 100644 index 00000000..faca0496 --- /dev/null +++ b/cypress/e2e/group/showGroupsAndClassesInTable.feature @@ -0,0 +1,83 @@ +@release +Feature: Group - To show groups and classes in one table with respective functionality + + As a teacher I want to see all groups and classes belonging to my school. + + @stable_test + Scenario: As a pre-condition teacher adds a class to school + Given I am logged in as a 'teacher1_nbc' at 'nbc' + When I go to administration page + And I go to class administration + And I click on add class + And I click on the confirm button + And I confirm managing the class + Then I see the new class administration page + + @stable_test + Scenario: As a teacher i can see all classes and groups of my school on the new class administration page. + Given I see the new class administration page + Then I can see the page title + And I can see the group 'Cypress-Test-Group' with source 'moin.schule' + And I can see the class '1' without source + And the group 'Cypress-Test-Group' has a manage button + And the class '1' has 4 enabled action items + + @stable_test + Scenario: As a teacher i can manage my classes + Given I see the new class administration page + When I click the manage button + Then I can see the manage classes page + When I click the cancel manage class button + Then I can see the cancel modal + When I click the confirmation button on the cancel modal + Then I see the new class administration page + When I click the manage button + And I confirm managing the class + Then I see the new class administration page + + @stable_test + Scenario: As a teacher i can edit my classes + Given I see the new class administration page + When I click the edit button + Then I can see the edit classes page + When I click the cancel edit class button + Then I can see the cancel modal + When I click the confirmation button on the cancel modal + Then I see the new class administration page + When I click the edit button + When I click in the name suffix text element + Then I can click on the save changes button + And I see the new class administration page + + @stable_test + Scenario: As a teacher i can upgrade my upgradable classes + Given I see the new class administration page + When I click the create successor button + Then I can see the create successor page + When I click the cancel create successor button + Then I can see the cancel modal + When I click the confirmation button on the cancel modal + Then I see the new class administration page + When I click the create successor button + And I confirm creating the successor + And I confirm managing the class + Then I see the new class administration page + And the create successor button of the original class is disabled + + @stable_test + Scenario: As a teacher i can delete my classes + Given I see the new class administration page + When I click the delete button + Then I can see the delete modal + When I click the cancel button on the delete modal + Then I see the new class administration page + When I click the delete button + And I click the confirmation button on the delete modal + Then I see the new class administration page + + @stable_test + Scenario: As a post-condition teacher deletes the successor class and logs out + Given I see the new class administration page + When I click the delete button + And I click the confirmation button on the delete modal + Then I see the new class administration page diff --git a/cypress/e2e/topics/accessH5PEditor.feature b/cypress/e2e/topics/accessH5PEditor.feature new file mode 100644 index 00000000..19ac2cdc --- /dev/null +++ b/cypress/e2e/topics/accessH5PEditor.feature @@ -0,0 +1,16 @@ +@release +Feature: To access the H5P editor as a teacher. + +As a teacher, I want to be able to access the H5P Editor for a topic in my course to create learning content + +@stable_test +Scenario: Access H5P Editor + Given I am logged in as a 'teacher1_dbc' at 'default' + When I go to rooms overview + When I go to room 'Course with subject and tasks' + When I click on topic 'Statistic' on course page + When I click on the button Edit on topic page + When I click on the Add Content H5P button + Then I can click on the Create H5P button + + diff --git a/cypress/support/custom_commands/login.js b/cypress/support/custom_commands/login.js index 1f0cc7ca..3fab6d79 100644 --- a/cypress/support/custom_commands/login.js +++ b/cypress/support/custom_commands/login.js @@ -57,6 +57,14 @@ Cypress.Commands.add('login', (username, environment) => { userEmail = 'ADMIN_1_BRB_EMAIL' userPassword = 'ADMIN_1_BRB_PASSWORD' break + case 'teacher1_nbc': + userEmail = 'TEACHER_1_NBC_EMAIL' + userPassword = 'TEACHER_1_NBC_PASSWORD' + break + case 'student2_nbc': + userEmail = 'STUDENT_2_NBC_EMAIL' + userPassword = 'STUDENT_2_NBC_PASSWORD' + break case 'admin1_nbc': userEmail = 'ADMIN_1_NBC_EMAIL' userPassword = 'ADMIN_1_NBC_PASSWORD' diff --git a/cypress/support/pages/account/pageAccount.js b/cypress/support/pages/account/pageAccount.js index fc6eb839..9aab1ff7 100644 --- a/cypress/support/pages/account/pageAccount.js +++ b/cypress/support/pages/account/pageAccount.js @@ -5,25 +5,6 @@ class Account { static #settingsButton = '[data-testid="settings"]' static #email = '[data-testid="user_email"]' static #emailReadOnly = '[data-testid="user_email_readonly"]' - static #languageMenu = '#language-menu' - static #selectedLanguage = '#selected-language' - static #listOfAllLanguages = '#available-languages' - static #germanLanguage = '[data-testid="available-language-de"]' - static #spanishLanguage = '[data-testid="available-language-es"]' - static #ukrainianLanguage = '[data-testid="available-language-uk"]' - static #englishLanguage = '[data-testid="available-language-en"]' - static #pageTitle = '#page-title' - - static #testAssertionData = { - german: 'Deutsch', - spanish: 'Español', - ukrainian: 'Yкраїнська', - english: 'English', - overviewInGerman: 'Übersicht', - overviewInSpanish: 'Panel', - overviewInUkrainian: 'Панель керування', - overviewInEnglish: 'Dashboard' - } navigateToAccountSettingsSection () { cy.get(Account.#initialsButton).click() @@ -40,105 +21,5 @@ class Account { cy.get(Account.#emailReadOnly).should('have.attr', 'readonly') } } - - assertNameInitialsIsVisible () { - cy.get(Account.#initialsButton).should('be.visible') - } - - clickInitialsOfName () { - cy.get(Account.#initialsButton) - .should('be.visible') - .then($btn => { - if ($btn.is(':disabled')) { - cy.log('Button exists and is disabled!') - return - } else { - cy.log('Button exists and is enabled!') - cy.wrap($btn).click() - } - }) - } - - clickLanguagesDropDownMenu () { - cy.get(Account.#languageMenu) - .should('be.visible') - .click() - .then(() => { - cy.get(Account.#selectedLanguage).should('be.visible') - cy.get(Account.#listOfAllLanguages).find('li').each($element => { - cy.get($element).should('have.prop', 'value') - cy.get($element).should('be.visible') - }) - }) - } - - changeLanguage (language) { - if (language === 'german') { - return this.selectLanguage( - Account.#germanLanguage, - Account.#testAssertionData.german - ) - } - - if (language === 'spanish') { - return this.selectLanguage( - Account.#spanishLanguage, - Account.#testAssertionData.spanish - ) - } - - if (language === 'ukrainian') { - return this.selectLanguage( - Account.#ukrainianLanguage, - Account.#testAssertionData.ukrainian - ) - } - - return this.selectLanguage( - Account.#englishLanguage, - Account.#testAssertionData.english - ) - } - - selectLanguage (sel, language) { - return cy.contains(sel, language) - .should('be.visible') - .click() - .wait(['@alerts_api']) - } - - assertLanguageUpdate (updatedText) { - cy.wait(300) - .get(Account.#pageTitle) - .invoke('text') - .should('eq', updatedText) - cy.get(Account.#pageTitle) - .invoke('attr', 'data-testid') - .should('eq', updatedText) - } - - verifyLanguageChanged (language) { - if (language === 'german') { - return this.assertLanguageUpdate( - Account.#testAssertionData.overviewInGerman - ) - } - - if (language === 'spanish') { - return this.assertLanguageUpdate( - Account.#testAssertionData.overviewInSpanish - ) - } - - if (language === 'ukrainian') { - return this.assertLanguageUpdate( - Account.#testAssertionData.overviewInUkrainian - ) - } - - return this.assertLanguageUpdate( - Account.#testAssertionData.overviewInEnglish - ) - } } export default Account diff --git a/cypress/support/pages/admin/pageAdministration.js b/cypress/support/pages/admin/pageAdministration.js index addbe8a1..ffe9cca8 100644 --- a/cypress/support/pages/admin/pageAdministration.js +++ b/cypress/support/pages/admin/pageAdministration.js @@ -29,6 +29,7 @@ class Management { static #teacherAdministrationNavigationButton = '[data-testid="Lehrkräfte"]' static #courseAdministrationNavigationButton = '[data-testid="Kurse"]' static #classAdministrationNavigationButton = '[data-testid="Klassen"]' + static #newClassAdministrationNavigationButton = '[data-testid="administrate_classes_new"]' static #teamAdministrationNavigationButton = '[data-testid="Teams"]' static #schoolAdministrationNavigationButton = '[data-testid="Schule"]' static #studentTeamCheckbox = '[data-testid="student_team_checkbox"]' @@ -124,6 +125,11 @@ class Management { cy.url().should('include', '/administration/classes') } + navigateToNewClassAdministration() { + cy.get(Management.#newClassAdministrationNavigationButton).click() + cy.url().should('include', '/administration/groups/classes') + } + navigateToTeamAdministration() { cy.get(Management.#teamAdministrationNavigationButton).eq(1).click() cy.url().should('include', '/administration/teams') diff --git a/cypress/support/pages/course/pageCourses.js b/cypress/support/pages/course/pageCourses.js index 93f12191..9954b1d0 100644 --- a/cypress/support/pages/course/pageCourses.js +++ b/cypress/support/pages/course/pageCourses.js @@ -15,7 +15,7 @@ class Courses { static #mainContent = '[id="main-content"]' static #createCourse = '[data-testid="add-course-button"]' static #createContent = '[data-testid="add-content-button"]' - static #toolsTab = '[data-testid="tools"]' + static #ltiToolsTab = '[data-testid="tools"]' static #toolsList = '[data-testid="course_tool_list_add_tool"]' static #courseOverviewNavigationButton = '[data-testid="Course-Overview"]' static #addNewToolButton = '[data-testid="add_new_tool"]' @@ -63,6 +63,12 @@ class Courses { static #learningContentTab = '[data-testid="learnContent-tab"]' static #courseDetailPageTitle = '[data-testid="courses-course-title"]' + static #toolsTab = '[data-testid="tools-tab"]' + static #addToolButton = '[data-testid="add-tool-button"]' + static #toolConfigurationSelect = '[data-testid="configuration-select"]' + static #contextExternalToolConfiguratorPageTitle = '[data-testid="context-external-tool-configurator-title"]' + static #groupSelection = '[id="classId_chosen"]' + static #chosenStudents= '[id="studentsId_chosen"] > .chosen-choices' seeSectionOneAreaOnCourseCreatePage () { cy.get(Courses.#sectionOneAreaOnCourseCreationPage).should('exist') } @@ -154,14 +160,42 @@ class Courses { cy.get(Courses.#courseDetailPageTitle).should('contain.text', courseName) } - navigateToTools () { - cy.get(Courses.#toolsTab).click() + navigateToLtiTools () { + cy.get(Courses.#ltiToolsTab).click() } - addNewTool () { + clickOnAddNewLtiToolButton () { cy.get(Courses.#addNewToolButton).click() } + navigateToToolsTab () { + cy.get(Courses.#toolsTab).click() + } + + clickOnAddNewToolFAB () { + cy.get(Courses.#addToolButton).click() + } + + seeAddNewToolFAB () { + cy.get(Courses.#addToolButton).should('exist') + } + + seeNotAddNewToolFAB () { + cy.get(Courses.#addToolButton).should('not.exist') + } + + seeContextExternalToolConfiguratorPageTitle () { + cy.get(Courses.#contextExternalToolConfiguratorPageTitle).should('exist') + } + + clickOnToolConfigurationSelect () { + cy.get(Courses.#toolConfigurationSelect).click() + } + + enterAnToolNameInToolConfigurationSelect (toolName) { + cy.get(Courses.#toolConfigurationSelect).type(toolName) + } + courseIsVisibleOnOverviewPage (courseName) { cy.contains(courseName).should('be.visible').and('contain.text', courseName) } @@ -452,5 +486,31 @@ class Courses { } }) } + + checkIfGroupIsVisible (groupName) { + cy.get(Courses.#groupSelection).find('.chosen-choices').contains(groupName).should('be.visible'); + } + checkIfGroupIsNotVisible (groupName) { + cy.get(Courses.#groupSelection).find('.chosen-choices').contains(groupName).should('not.exist'); + + + } + + checkIfStudentIsVisible (studentName) { + cy.get(Courses.#chosenStudents).find('.search-choice').children('span').should('contain', studentName); + } + + checkIfStudentIsNotVisible (studentName) { + cy.get(Courses.#chosenStudents).should('not.contain', studentName); + } + + addGroup (groupName) { + cy.get(Courses.#groupSelection).find('.chosen-choices').click(); + cy.get(Courses.#groupSelection).find('.chosen-results').contains(groupName).click(); + } + + removeGroup (groupName) { + cy.get(Courses.#groupSelection).find('.chosen-choices').contains(groupName).siblings('a').click(); + } } export default Courses diff --git a/cypress/support/pages/dashboard/pageDashboard.js b/cypress/support/pages/dashboard/pageDashboard.js index 41aec8b3..8115c18c 100644 --- a/cypress/support/pages/dashboard/pageDashboard.js +++ b/cypress/support/pages/dashboard/pageDashboard.js @@ -2,6 +2,27 @@ class Dashboard { + static #initialsButton = '[data-testid="initials"]' + static #languageMenu = '#language-menu' + static #selectedLanguage = '#selected-language' + static #listOfAllLanguages = '#available-languages' + static #germanLanguage = '[data-testid="available-language-de"]' + static #spanishLanguage = '[data-testid="available-language-es"]' + static #ukrainianLanguage = '[data-testid="available-language-uk"]' + static #englishLanguage = '[data-testid="available-language-en"]' + static #getPageTitle = '#page-title' + + static #testAssertionData = { + german: 'Deutsch', + spanish: 'Español', + ukrainian: 'Yкраїнська', + english: 'English', + overviewInGerman: 'Übersicht', + overviewInSpanish: 'Panel', + overviewInUkrainian: 'Панель керування', + overviewInEnglish: 'Dashboard' + } + static #welcomeMessage = '[data-testid="welcome-section"]' static #dashboardTasksTitle = '[data-testid="dashboard-tasks-title"]' static #dashboardTaskCourseName = '[data-testid="task-course-name"]' @@ -11,6 +32,106 @@ class Dashboard { static #newsSection = '[data-testid="news-section"]' static #titleOnDashboardPage = '[id="page-title"]' + assertNameInitialsIsVisible () { + cy.get(Dashboard.#initialsButton).should('be.visible') + } + + clickInitialsOfName () { + cy.get(Dashboard.#initialsButton) + .should('be.visible') + .then($btn => { + if ($btn.is(':disabled')) { + cy.log('Button exists and is disabled!') + return + } else { + cy.log('Button exists and is enabled!') + cy.wrap($btn).click() + } + }) + } + + clickLanguagesDropDownMenu () { + cy.get(Dashboard.#languageMenu) + .should('be.visible') + .click() + .then(() => { + cy.get(Dashboard.#selectedLanguage).should('be.visible') + cy.get(Dashboard.#listOfAllLanguages).find('li').each($element => { + cy.get($element).should('have.prop', 'value') + cy.get($element).should('be.visible') + }) + }) + } + + changeLanguage (language) { + if (language === 'german') { + return this.selectLanguage( + Dashboard.#germanLanguage, + Dashboard.#testAssertionData.german + ) + } + + if (language === 'spanish') { + return this.selectLanguage( + Dashboard.#spanishLanguage, + Dashboard.#testAssertionData.spanish + ) + } + + if (language === 'ukrainian') { + return this.selectLanguage( + Dashboard.#ukrainianLanguage, + Dashboard.#testAssertionData.ukrainian + ) + } + + return this.selectLanguage( + Dashboard.#englishLanguage, + Dashboard.#testAssertionData.english + ) + } + + selectLanguage (sel, language) { + return cy.contains(sel, language) + .should('be.visible') + .click() + .wait(['@alerts_api']) + } + + assertLanguageUpdate (updatedText) { + cy.wait(300) + .get(Dashboard.#getPageTitle) + .invoke('text') + .should('eq', updatedText) + cy.get(Dashboard.#getPageTitle) + .invoke('attr', 'data-testid') + .should('eq', updatedText) + } + + verifyLanguageChanged (language) { + if (language === 'german') { + return this.assertLanguageUpdate( + Dashboard.#testAssertionData.overviewInGerman + ) + } + + if (language === 'spanish') { + return this.assertLanguageUpdate( + Dashboard.#testAssertionData.overviewInSpanish + ) + } + + if (language === 'ukrainian') { + return this.assertLanguageUpdate( + Dashboard.#testAssertionData.overviewInUkrainian + ) + } + + return this.assertLanguageUpdate( + Dashboard.#testAssertionData.overviewInEnglish + ) + } + arriveOnDashboard() { cy.visit('/dashboard') cy.url() diff --git a/cypress/support/pages/group/pageGroups.js b/cypress/support/pages/group/pageGroups.js new file mode 100644 index 00000000..4e5ca272 --- /dev/null +++ b/cypress/support/pages/group/pageGroups.js @@ -0,0 +1,196 @@ +'use strict' + +class Groups { + static #createClass = '[data-testid="createClass"]'; + static #confirmClassCreate = '[data-testid="confirmClassCreate"]'; + static #manageConfirm = '[data-testid="manage-confirm"]'; + static #classTitleNew = '[data-testid="admin-class-title"]'; + static #classTableNew = '[data-testid="admin-class-table"]'; + static #manageClassButton = '[data-testid="legacy-class-table-manage-btn"]'; + static #cancelModal = '[data-testid="modal_content"]'; + static #editClassButton = '[data-testid="class-table-edit-btn"]'; + static #createSuccessorButton = '[data-testid="class-table-successor-btn"]'; + static #deleteClassButton = '[data-testid="class-table-delete-btn"]'; + static #deleteDialog = '.v-dialog--active'; + static #deleteDialogCancel = '[data-testid="dialog-cancel"]'; + static #deleteDialogConfirm = '[data-testid="dialog-confirm"]'; + static #adminGroupTitle = '[data-testid="admin-class-title"]'; + static #groupMemberTable = '[data-testid="class-members-table"]'; + static #classMemberInfoBox = '[data-testid="class-members-info-box"]'; + static #classMemberInfoBoxText = '[data-testid="class-members-info-box-text"]'; + static #manageGroupButton = '[data-testid="class-table-members-manage-btn"]'; + + clickCreateClass() { + cy.get(Groups.#createClass) + .click(); + } + + clickConfirmCreateClass() { + cy.get(Groups.#confirmClassCreate) + .click(); + } + + clickConfirmManageClass() { + cy.get(Groups.#manageConfirm) + .click(); + } + + clickCancelButton() { + cy.get('.btn-cancel') + .click(); + } + + clickManageClassButton() { + cy.get(Groups.#manageClassButton) + .first().click(); + } + + clickConfirmButton() { + cy.get('.historyback') + .click(); + } + + clickEditClassButton() { + cy.get(Groups.#editClassButton) + .first().click(); + } + + clickNameSuffixField() { + cy.get('[name=classsuffix]') + .click(); + } + + clickCreateSuccessorButton() { + cy.get(Groups.#createSuccessorButton) + .first().click(); + } + + clickSaveChangesButton() { + cy.get('.btn-primary') + .eq(0) + .should('not.be.disabled') + .click(); + } + + clickConfirmSuccessor() { + cy.get('.btn-primary') + .eq(0) + .click(); + } + + clickDeleteButton() { + cy.get(Groups.#deleteClassButton) + .first().click(); + } + + clickCancelDeleteDialogButton() { + cy.get(Groups.#deleteDialogCancel) + .click(); + } + + clickConfirmDeleteDialogButton() { + cy.get(Groups.#deleteDialogConfirm) + .click(); + } + + isNewClassAdministrationPage() { + cy.url().should('include', '/administration/groups/classes'); + } + + isManageClassPage() { + cy.url().should('include', '/administration/classes'); + cy.url().should('include', '/manage'); + } + + isEditClassPage() { + cy.url().should('include', '/administration/classes'); + cy.url().should('include', '/edit'); + } + + isCancelModal() { + cy.get(Groups.#cancelModal).should('exist'); + } + + isCreateSuccessorPage() { + cy.url().should('include', '/administration/classes'); + cy.url().should('include', '/createSuccessor'); + } + + seeNewClassPageTitle() { + cy.get(Groups.#classTitleNew).should('exist'); + } + + isSuccessorButtonDisabled() { + cy.get(Groups.#createSuccessorButton) + .first().should('have.class', 'v-btn--disabled'); + } + + isDeleteDialog() { + cy.get(Groups.#deleteDialog) + .should('be.visible'); + } + + newClassTableContainsClass(className, sourceName) { + const classNameData = cy.get(Groups.#classTableNew).find('td').contains(className); + + classNameData.should('be.visible'); + classNameData.siblings('td').eq(0).should(($td) => { + expect($td.text().trim()).to.equal(sourceName); + }); + } + + groupsHaveAManageButton(groupName) { + const classNameData = cy.get(Groups.#classTableNew).find('td').contains(groupName); + + classNameData.siblings('td').eq(2).find('a[data-testid="class-table-members-manage-btn"]') + .should('exist'); + } + + classesHave4ActiveActionItems(className) { + const classNameData = cy.get(Groups.#classTableNew).find('td').contains(className); + + const buttons = classNameData.siblings('td').eq(2).find('a, button'); + + buttons.should('have.length', 4); + buttons.each(($btn) => { + cy.wrap($btn).should('not.be.disabled'); + }) + } + + seeManageGroupPage(){ + cy.url().should('include', '/administration/groups/classes/'); + } + + seeManageGroupPageTitle() { + cy.get(Groups.#adminGroupTitle).should('be.visible') + } + + seeGroupMemberTable() { + cy.get(Groups.#groupMemberTable).should('be.visible') + } + + seeGroupMemberTableContainsMember(role, lastName){ + const groupMemberData = cy.get(Groups.#groupMemberTable).find('td').contains(lastName); + + groupMemberData.should('be.visible'); + groupMemberData.siblings('td').eq(1).should(($td) => { + expect($td.text().trim()).to.equal(role); + }); + } + + seeClassMemberInfoBox() { + cy.get(Groups.#classMemberInfoBox).should('be.visible') + } + + seeClassMemberInfoBoxText() { + cy.get(Groups.#classMemberInfoBoxText).should('be.visible') + } + + clickManageGroupButton(){ + cy.get(Groups.#manageGroupButton) + .first().click(); + } + +} + +export default Groups diff --git a/cypress/support/pages/topics/pageTopics.js b/cypress/support/pages/topics/pageTopics.js index 6b4130b2..e42b7f7a 100644 --- a/cypress/support/pages/topics/pageTopics.js +++ b/cypress/support/pages/topics/pageTopics.js @@ -11,6 +11,8 @@ class Topics { static #addLearningMaterialBtn = '[data-testid="topic-addcontent-material-btn"]' static #addEtherpadBtn = '[data-testid="topic-addcontent-etherpad-btn"]' static #addTaskBtn = '[data-testid="topic-addcontent-task-btn"]' + static #addContentH5pBtn = '[data-testid="topic-addcontent-h5p-btn"]' + static #createH5pBtn = '[data-testid="topic-h5p-create-btn"]' // class is used for cardHeader and cardBlock because the elements are too generic and depend on position of the element, so using data-testid would need much more logic (also in the feature file) and code than using class. static #cardHeader = '[class="card-header"]' static #cardBlock = '[class="card-block"]' @@ -71,11 +73,23 @@ class Topics { cy.get(Topics.#addTaskBtn).click() } + clickOnAddContentH5PToTopic() { + cy.get(Topics.#addContentH5pBtn).click() + } + + seeCreateH5PInTopic() { + cy.get(Topics.#createH5pBtn) + .should('exist') + .click() + } + clickOnSubmitChangesInTopicBtn() { cy.get(Topics.#submitChangesInTopicBtn) .click() } + + seeFormElementText(textElementPosition) { if(textElementPosition === '0'){ cy.get(Topics.#textElementPos0).should('exist') diff --git a/cypress/support/step_definition/course/createEditAndDeleteCourseSteps.spec.js b/cypress/support/step_definition/course/createEditAndDeleteCourseSteps.spec.js index b258d525..da5dbae7 100644 --- a/cypress/support/step_definition/course/createEditAndDeleteCourseSteps.spec.js +++ b/cypress/support/step_definition/course/createEditAndDeleteCourseSteps.spec.js @@ -85,4 +85,28 @@ Then ('I see the modal to confirm the deletion',() =>{ When ('I click on the button delete on the modal to confirm the course deletion',() =>{ courses.confirmCourseDeletionOnModal() -}) \ No newline at end of file +}) + +Then ('I see {string} in the class selection box',(groupName) => { + courses.checkIfGroupIsVisible(groupName); +}) + +Then ('I see {string} in the student selection box',(studentName) => { + courses.checkIfStudentIsVisible(studentName); +}) + +When('I click on the selection box to add a new group with {string}',(groupName) =>{ + courses.addGroup(groupName); +}) + +When('I click on the remove icon of group {string}',(groupName) =>{ + courses.removeGroup(groupName); +}) + +Then('I do not see {string} in the group selection box',(groupName) =>{ + courses.checkIfGroupIsNotVisible(groupName); +}) + +Then('I do not see {string} in the student selection box',(studentName) =>{ + courses.checkIfStudentIsNotVisible(studentName); +}) diff --git a/cypress/support/step_definition/course/toolCourseSteps.spec.js b/cypress/support/step_definition/course/toolCourseSteps.spec.js new file mode 100644 index 00000000..9ac8a73b --- /dev/null +++ b/cypress/support/step_definition/course/toolCourseSteps.spec.js @@ -0,0 +1,35 @@ +const { When, Then } = require('@badeball/cypress-cucumber-preprocessor') +import Courses from '../../pages/course/pageCourses' + +const courses = new Courses() + +When('I click on the tools tab', () => { + courses.navigateToToolsTab() +}) + +Then('I can see the button to add a tool', () => { + courses.seeAddNewToolFAB() +}) + +Then('I cant see the button to add a tool', () => { + courses.seeNotAddNewToolFAB() +}) + +When('I click on the button to add a tool', () => { + courses.clickOnAddNewToolFAB() +}) + +Then('I can see the tool configuration page title', () => { + courses.seeContextExternalToolConfiguratorPageTitle() +}) + + +When('I click on the tool configuration selection', () => { + courses.clickOnToolConfigurationSelect() +}) + +Then('I can enter {string} as tool name in the selection', toolName => { + courses.enterAnToolNameInToolConfigurationSelect(toolName) +}) + + diff --git a/cypress/support/step_definition/account/changeLanguageSteps.spec.js b/cypress/support/step_definition/dashboard/changeLanguageSteps.spec.js similarity index 55% rename from cypress/support/step_definition/account/changeLanguageSteps.spec.js rename to cypress/support/step_definition/dashboard/changeLanguageSteps.spec.js index ba77f7cf..f11df3ab 100644 --- a/cypress/support/step_definition/account/changeLanguageSteps.spec.js +++ b/cypress/support/step_definition/dashboard/changeLanguageSteps.spec.js @@ -1,24 +1,24 @@ const { When, Then } = require("@badeball/cypress-cucumber-preprocessor") -import Account from '../../pages/account/pageAccount' +import Dashboard from '../../pages/dashboard/pageDashboard' -const account = new Account() +const dashboard = new Dashboard() Then('I can see initials of my name', () => { - account.assertNameInitialsIsVisible() + dashboard.assertNameInitialsIsVisible() }) When('I click on initials of my name', () => { - account.clickInitialsOfName() + dashboard.clickInitialsOfName() }) Then('I click on language drop down menu', () => { - account.clickLanguagesDropDownMenu() + dashboard.clickLanguagesDropDownMenu() }) When('I can change language to {string}', language => { - account.changeLanguage(language) + dashboard.changeLanguage(language) }) Then('I can see title in dashboard is changed to {string}', language => { - account.verifyLanguageChanged(language) + dashboard.verifyLanguageChanged(language) }) diff --git a/cypress/support/step_definition/group/commonGroupSteps.spec.js b/cypress/support/step_definition/group/commonGroupSteps.spec.js new file mode 100644 index 00000000..54e49b31 --- /dev/null +++ b/cypress/support/step_definition/group/commonGroupSteps.spec.js @@ -0,0 +1,51 @@ +const { When, Then } = require('@badeball/cypress-cucumber-preprocessor') +import Groups from '../../pages/group/pageGroups' +import Management from '../../pages/admin/pageAdministration'; + + +const groups = new Groups(); +const management = new Management(); + +When('I go to class administration', () => { + management.navigateToClassAdministration(); +}) + +When('I go to new class administration page', () => { + management.navigateToNewClassAdministration(); +}) + +When('I click on add class', () => { + groups.clickCreateClass(); +}) + +When('I click on the confirm button', () => { + groups.clickConfirmCreateClass(); +}) + +When('I confirm managing the class', () => { + groups.clickConfirmManageClass(); +}) + +Then('I see the new class administration page', () => { + groups.isNewClassAdministrationPage(); +}) + +Then('I can see the page title', () => { + groups.seeNewClassPageTitle(); +}) + +Then('I can see the group {string} with source {string}', (groupName, systemName) => { + groups.newClassTableContainsClass(groupName, systemName); +}) + +Then('I can see the class {string} without source', (className) => { + groups.newClassTableContainsClass(className, ""); +}) + +Then('the group {string} has a manage button', (groupName) => { + groups.groupsHaveAManageButton(groupName); +}) + +Then('the class {string} has 4 enabled action items', (className) => { + groups.classesHave4ActiveActionItems(className); +}) diff --git a/cypress/support/step_definition/group/manageGroups.spec.js b/cypress/support/step_definition/group/manageGroups.spec.js new file mode 100644 index 00000000..9dfd79fe --- /dev/null +++ b/cypress/support/step_definition/group/manageGroups.spec.js @@ -0,0 +1,32 @@ +import Groups from "../../pages/group/pageGroups"; +import {Then, When} from "@badeball/cypress-cucumber-preprocessor"; + +const groups = new Groups(); + +When('I click the manage group button', () => { + groups.clickManageGroupButton(); +}) + +Then('I can see the manage group page', () => { + groups.seeManageGroupPage(); +}) + +Then('I can see the manage group page title', () => { + groups.seeManageGroupPageTitle() +}) + +Then('I can see the group member table', () => { + groups.seeGroupMemberTable() +}) + +Then('I can see the {string} with name {string}', (role, lastName) => { + groups.seeGroupMemberTableContainsMember(role, lastName) +}) + +Then('I can see the infobox', () => { + groups.seeClassMemberInfoBox() +}) + +Then('I can see the infotext', () => { + groups.seeClassMemberInfoBoxText() +}) diff --git a/cypress/support/step_definition/group/showGroupsAndClassesInTableSteps.spec.js b/cypress/support/step_definition/group/showGroupsAndClassesInTableSteps.spec.js new file mode 100644 index 00000000..30e29a22 --- /dev/null +++ b/cypress/support/step_definition/group/showGroupsAndClassesInTableSteps.spec.js @@ -0,0 +1,79 @@ +const { When, Then } = require('@badeball/cypress-cucumber-preprocessor') +import Groups from '../../pages/group/pageGroups'; + +const groups = new Groups() + +When('I click the manage button', () => { + groups.clickManageClassButton(); +}) + +Then('I can see the manage classes page', () => { + groups.isManageClassPage(); +}) + +When('I click the cancel manage class button', () => { + groups.clickCancelButton(); +}) + +Then('I can see the cancel modal', () => { + groups.isCancelModal(); +}) + +When('I click the confirmation button on the cancel modal', () => { + groups.clickConfirmButton(); +}) + +When('I click the edit button', () => { + groups.clickEditClassButton(); +}) + +Then('I can see the edit classes page', () => { + groups.isEditClassPage(); +}) + +When('I click the cancel edit class button', () => { + groups.clickCancelButton(); +}) + +When('I click in the name suffix text element', () => { + groups.clickNameSuffixField(); +}) + +Then('I can click on the save changes button', () => { + groups.clickSaveChangesButton(); +}) + +When('I click the create successor button', () => { + groups.clickCreateSuccessorButton(); +}) + +Then('I can see the create successor page', () => { + groups.isCreateSuccessorPage(); +}) + +When('I click the cancel create successor button', () => { + groups.clickCancelButton(); +}) + +When('I confirm creating the successor', () => { + groups.clickConfirmSuccessor(); +}) +Then('the create successor button of the original class is disabled', () => { + groups.isSuccessorButtonDisabled(); +}) + +When('I click the delete button', () => { + groups.clickDeleteButton(); +}) + +Then('I can see the delete modal', () => { + groups.isDeleteDialog(); +}) + +When('I click the cancel button on the delete modal', () => { + groups.clickCancelDeleteDialogButton(); +}) + +When('I click the confirmation button on the delete modal', () => { + groups.clickConfirmDeleteDialogButton(); +}) diff --git a/cypress/support/step_definition/topics/accessH5PEditor.spec.js b/cypress/support/step_definition/topics/accessH5PEditor.spec.js new file mode 100644 index 00000000..110cf070 --- /dev/null +++ b/cypress/support/step_definition/topics/accessH5PEditor.spec.js @@ -0,0 +1,18 @@ +const { When, Then } = require("@badeball/cypress-cucumber-preprocessor") +import Topics from '../../pages/topics/pageTopics' + +const topics = new Topics() + +When('I click on the button Edit on topic page', () => { + topics.clickOnButtonEditInTopicPage() +}) + +When('I click on the Add Content H5P button', () =>{ + topics.clickOnAddContentH5PToTopic(); +}) + +Then('I can click on the Create H5P button', ()=>{ + topics.seeCreateH5PInTopic(); +}) + + diff --git a/package-lock.json b/package-lock.json index 8437ae89..760c9cbb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,13 +86,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.15.tgz", - "integrity": "sha512-Zu9oWARBqeVOW0dZOjXc3JObrzuqothQ3y/n1kUtrjCoCPLkXUwMvOo/F/TCfoHMbWIFlWwpZtkZVb9ga4U2pA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "peer": true, "dependencies": { - "@babel/types": "^7.22.15", + "@babel/types": "^7.23.0", "@jridgewell/gen-mapping": "^0.3.2", "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" @@ -214,14 +214,14 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "peer": true, "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" @@ -458,9 +458,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.22.16", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.16.tgz", - "integrity": "sha512-+gPfKv8UWeKKeJTUxe59+OobVcrYHETCsORl61EmSkmgymguYk/X5bp7GuUIXaFsc6y++v8ZxPsLSSuujqDphA==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -1735,20 +1735,20 @@ } }, "node_modules/@babel/traverse": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.20.tgz", - "integrity": "sha512-eU260mPZbU7mZ0N+X10pxXhQFMGTeLb9eFS0mxehS8HZp9o1uSnFeWQuG1UPrlxgA7QoUzFhOnilHDp0AXCyHw==", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", "dev": true, "peer": true, "dependencies": { "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.22.15", + "@babel/generator": "^7.23.0", "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.22.5", + "@babel/helper-function-name": "^7.23.0", "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.16", - "@babel/types": "^7.22.19", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -1757,14 +1757,14 @@ } }, "node_modules/@babel/types": { - "version": "7.22.19", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.19.tgz", - "integrity": "sha512-P7LAw/LbojPzkgp5oznjE6tQEIWbp4PkkfrZDINTro9zgBRtI324/EYsiSI7lhPbpIQ+DCeR2NNmMWANGGfZsg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "peer": true, "dependencies": { "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.19", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": {