diff --git a/e2e-tests/cypress/tests/cypress/e2e/User.Authentication/the_user_is_logged_in_with_username_overview_page_is_displayed_with_the_username _{string}.ts b/e2e-tests/cypress/tests/cypress/e2e/User.Authentication/the_user_is_logged_in_with_username_overview_page_is_displayed_with_the_username _{string}.ts deleted file mode 100644 index d37236335..000000000 --- a/e2e-tests/cypress/tests/cypress/e2e/User.Authentication/the_user_is_logged_in_with_username_overview_page_is_displayed_with_the_username _{string}.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Then } from "@badeball/cypress-cucumber-preprocessor"; -import { OverviewPage } from "../models/OverviewPage"; - -Then("the user is logged in with username {string}", (username: string) => { - const overviewPage = new OverviewPage(); - cy.url().should('include', '/overview') - cy.get(overviewPage.navbarNameSelector).should('contain', username); -}); - - diff --git a/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword.feature b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword.feature new file mode 100644 index 000000000..ceee131fb --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword.feature @@ -0,0 +1,27 @@ +Feature: User profile - change password + As a user + I want the option to change my password on my profile page. + + Background: + # TODO for these pre-conditions utilize seeding or API check, if user exists in test system + # Given the following "users" are in the database: + # | email | password | name | + # | bibi@bloxberg.de | Aa12345_ | Bibi Bloxberg | | + + # TODO instead of credentials use the name of an user object (see seeds in backend) + Given the user is logged in as "bibi@bloxberg.de" "Aa12345_" + + Scenario: Change password successfully + Given the browser navigates to page "/profile" + And the user opens the change password menu + When the user fills the password form with: + | Old password | Aa12345_ | + | New password | 12345Aa_ | + | Repeat new password | 12345Aa_ | + And the user submits the password form + And the user is presented a "success" message + And the user logs out + Then the user submits the credentials "bibi@bloxberg.de" "Aa12345_" + And the user cannot login + But the user submits the credentials "bibi@bloxberg.de" "12345Aa_" + And the user is logged in with username "Bibi Bloxberg" diff --git a/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_fills_the_password_form_with.ts b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_fills_the_password_form_with.ts new file mode 100644 index 000000000..c1c1084fd --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_fills_the_password_form_with.ts @@ -0,0 +1,11 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; +import { ProfilePage } from "../models/ProfilePage"; + +When("the user fills the password form with:", table => { + table = table.rowsHash(); + const profilePage = new ProfilePage(); + profilePage.enterOldPassword(table["Old password"]); + profilePage.enterNewPassword(table["New password"]); + profilePage.enterRepeatPassword(table["Repeat new password"]); + cy.get(profilePage.submitNewPasswordBtn).should('be.enabled'); +}); \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_is_presented_a_{string}_message.ts b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_is_presented_a_{string}_message.ts new file mode 100644 index 000000000..79b63e499 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_is_presented_a_{string}_message.ts @@ -0,0 +1,8 @@ +import { When } from "@badeball/cypress-cucumber-preprocessor"; +import { Toasts } from "../models/Toasts"; + +When("the user is presented a {string} message", (type: string) => { + const toast = new Toasts(); + cy.get(toast.toastTitle).should('contain.text', 'Success'); + cy.get(toast.toastMessage).should('contain.text', 'Your password has been changed.'); +}); \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_opens_the_change_password_menu.ts b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_opens_the_change_password_menu.ts new file mode 100644 index 000000000..78e6cdfe0 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_opens_the_change_password_menu.ts @@ -0,0 +1,9 @@ +import { And } from "@badeball/cypress-cucumber-preprocessor"; +import { ProfilePage } from "../models/ProfilePage"; + +And("the user opens the change password menu", () => { + const profilePage = new ProfilePage(); + cy.get(profilePage.openChangePassword).click(); + cy.get(profilePage.newPasswordRepeatInput).should('be.visible'); + cy.get(profilePage.submitNewPasswordBtn).should('be.disabled'); +}); \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_submits_the_password_form.ts b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_submits_the_password_form.ts new file mode 100644 index 000000000..7730f04fc --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/UserProfile.ChangePassword/the_user_submits_the_password_form.ts @@ -0,0 +1,7 @@ +import { And } from "@badeball/cypress-cucumber-preprocessor"; +import { ProfilePage } from "../models/ProfilePage"; + +And("the user submits the password form", () => { + const profilePage = new ProfilePage(); + profilePage.submitPasswordForm(); +}); \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/e2e/models/ProfilePage.ts b/e2e-tests/cypress/tests/cypress/e2e/models/ProfilePage.ts new file mode 100644 index 000000000..f7a243a40 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/models/ProfilePage.ts @@ -0,0 +1,35 @@ +/// + +export class ProfilePage { + // selectors + openChangePassword = '[data-test=open-password-change-form]'; + oldPasswordInput = '#password-input-field'; + newPasswordInput = '#Neues-Passwort-input-field'; + newPasswordRepeatInput = '#Neues-Passwort-wiederholen-input-field'; + submitNewPasswordBtn = '[data-test=submit-new-password-btn]'; + + goto() { + cy.visit('/profile'); + return this; + } + + enterOldPassword(password: string) { + cy.get(this.oldPasswordInput).clear().type(password); + return this; + } + + enterNewPassword(password: string) { + cy.get(this.newPasswordInput).clear().type(password); + return this; + } + + enterRepeatPassword(password: string) { + cy.get(this.newPasswordRepeatInput).clear().type(password); + return this; + } + + submitPasswordForm() { + cy.get(this.submitNewPasswordBtn).click(); + return this; + } +} diff --git a/e2e-tests/cypress/tests/cypress/e2e/models/SideNavMenu.ts b/e2e-tests/cypress/tests/cypress/e2e/models/SideNavMenu.ts new file mode 100644 index 000000000..6770fe6ff --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/models/SideNavMenu.ts @@ -0,0 +1,17 @@ +/// + +export class SideNavMenu { + // selectors + profileMenu = '[data-test=profile-menu]'; + logoutMenu = '[data-test=logout-menu]'; + + openUserProfile() { + cy.get(this.profileMenu).click(); + return this; + } + + logout() { + cy.get(this.logoutMenu).click(); + return this; + } + } \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/e2e/models/Toasts.ts b/e2e-tests/cypress/tests/cypress/e2e/models/Toasts.ts new file mode 100644 index 000000000..86fed8933 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/e2e/models/Toasts.ts @@ -0,0 +1,7 @@ +/// + +export class Toasts { + // selectors + toastTitle = '.gdd-toaster-title'; + toastMessage = '.gdd-toaster-body'; +} \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_cannot_login.ts b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_cannot_login.ts new file mode 100644 index 000000000..9f7607565 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_cannot_login.ts @@ -0,0 +1,8 @@ +import { Then } from "@badeball/cypress-cucumber-preprocessor"; +import { Toasts } from "../../e2e/models/Toasts"; + +Then("the user cannot login", () => { + const toast = new Toasts(); + cy.get(toast.toastTitle).should('contain.text', 'Fehler!'); // 'Error!' + cy.get(toast.toastMessage).should('contain.text', 'Kein Benutzer mit diesen Anmeldedaten.'); // 'No user with this credentials.' +}); diff --git a/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_is_logged_in_as_{string}_{string}.ts b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_is_logged_in_as_{string}_{string}.ts new file mode 100644 index 000000000..e8692da38 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_is_logged_in_as_{string}_{string}.ts @@ -0,0 +1,5 @@ +import { Given } from "@badeball/cypress-cucumber-preprocessor"; + +Given("the user is logged in as {string} {string}", (email: string, password: string) => { + cy.login(email, password); +}); \ No newline at end of file diff --git a/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_logs_out.ts b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_logs_out.ts new file mode 100644 index 000000000..2822fce78 --- /dev/null +++ b/e2e-tests/cypress/tests/cypress/support/step_definitions/the_user_logs_out.ts @@ -0,0 +1,7 @@ +import { Then } from "@badeball/cypress-cucumber-preprocessor"; +import { SideNavMenu } from "../../e2e/models/SideNavMenu"; + +Then("the user logs out", () => { + const sideNavMenu = new SideNavMenu; + sideNavMenu.logout(); +}); \ No newline at end of file diff --git a/frontend/src/components/Inputs/InputPasswordConfirmation.vue b/frontend/src/components/Inputs/InputPasswordConfirmation.vue index 8154984ef..3209018c3 100644 --- a/frontend/src/components/Inputs/InputPasswordConfirmation.vue +++ b/frontend/src/components/Inputs/InputPasswordConfirmation.vue @@ -12,6 +12,7 @@ atLeastOneSpecialCharater: true, noWhitespaceCharacters: true, }" + id="new-password-input-field" :label="register ? $t('form.password') : $t('form.password_new')" :showAllErrors="true" :immediate="true" diff --git a/frontend/src/components/Menu/Sidebar.vue b/frontend/src/components/Menu/Sidebar.vue index 4b38851b2..f6abb6fbc 100644 --- a/frontend/src/components/Menu/Sidebar.vue +++ b/frontend/src/components/Menu/Sidebar.vue @@ -24,7 +24,7 @@ {{ $t('navigation.community') }} - + {{ $t('navigation.profile') }} @@ -48,7 +48,7 @@ {{ $t('navigation.admin_area') }} - + {{ $t('navigation.logout') }} diff --git a/frontend/src/components/UserSettings/UserPassword.vue b/frontend/src/components/UserSettings/UserPassword.vue index 0ba1576e8..2f571d400 100644 --- a/frontend/src/components/UserSettings/UserPassword.vue +++ b/frontend/src/components/UserSettings/UserPassword.vue @@ -6,6 +6,7 @@ {{ $t('settings.password.change-password') }} @@ -36,6 +37,7 @@ :variant="disabled ? 'light' : 'success'" class="mt-4" :disabled="disabled" + data-test="submit-new-password-btn" > {{ $t('form.save') }}