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') }}