mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-05 22:38:48 +00:00
Cypress test for the profile settings page (#3083)
* Added cypress test for profile settings page * Updated common selectors * Updated common text * Added functions for random names * Added data-cy attributes for components * Added verification for the input value * Added password field validation * Added common utils file * Added wait * Updated login error toast
This commit is contained in:
parent
cacce68713
commit
cb678190d7
10 changed files with 267 additions and 30 deletions
|
|
@ -1,15 +1,18 @@
|
||||||
export const commonSelectors={
|
export const commonSelectors={
|
||||||
toastMessage: ".go318386747",
|
toastMessage: ".go318386747",
|
||||||
appCard: "[data-cy=app-card]",
|
appCard: "[data-cy=app-card]",
|
||||||
editButton: "[data-cy=edit-button]",
|
editButton: "[data-cy=edit-button]",
|
||||||
searchField:"[data-cy=widget-search-box]",
|
searchField:"[data-cy=widget-search-box]",
|
||||||
firstWidget:"[data-cy=widget-list]:eq(0)",
|
firstWidget:"[data-cy=widget-list]:eq(0)",
|
||||||
canvas:"[data-cy=real-canvas]",
|
canvas:"[data-cy=real-canvas]",
|
||||||
appCardOptions: "[data-cy=app-card-menu-icon]",
|
appCardOptions: "[data-cy=app-card-menu-icon]",
|
||||||
deleteApp: "[data-cy=card-options] :nth-child(5)>span",
|
deleteApp: "[data-cy=card-options] :nth-child(5)>span",
|
||||||
confirmButton: "[data-cy=confirm-yes-button]",
|
confirmButton: "[data-cy=confirm-yes-button]",
|
||||||
autoSave: "[data-cy=autosave-indicator]",
|
autoSave: "[data-cy=autosave-indicator]",
|
||||||
skipButton: ".driver-close-btn",
|
skipButton: ".driver-close-btn",
|
||||||
skipInstallationModal: "[data-cy=skip-button]",
|
skipInstallationModal: "[data-cy=skip-button]",
|
||||||
homePageLogo: "[data-cy=home-page-logo]"
|
homePageLogo: "[data-cy=home-page-logo]",
|
||||||
|
emailField: "[data-cy=email-text-field]",
|
||||||
|
passwordField: "[data-cy=password-text-field]",
|
||||||
|
signInButton: "[data-cy=login-button]",
|
||||||
}
|
}
|
||||||
22
cypress/constants/selectors/profile.js
Normal file
22
cypress/constants/selectors/profile.js
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
export const profileSelector={
|
||||||
|
profileDropdown: "[data-cy=dropdown-menu]",
|
||||||
|
profileLink: "[data-cy=profile-link]",
|
||||||
|
logoutLink: "[data-cy=logout-link]",
|
||||||
|
profileElements:{
|
||||||
|
pageTitle: "[data-cy=page-title]",
|
||||||
|
profileCard: "[data-cy=card-title-profile]",
|
||||||
|
firstNameLabel: "[data-cy=first-name-label]",
|
||||||
|
lastNameLabel: "[data-cy=last-name-label]",
|
||||||
|
emailLabel: "[data-cy=email-label]",
|
||||||
|
passwordCard: "[data-cy=card-title-change-password]",
|
||||||
|
currentPasswordLabel: "[data-cy=current-password-label]",
|
||||||
|
newPasswordLabel: "[data-cy=new-password-label]",
|
||||||
|
},
|
||||||
|
firstNameInput: "[data-cy=first-name-input]",
|
||||||
|
lastNameInput: "[data-cy=last-name-input]",
|
||||||
|
emailInput: "[data-cy=email-input]",
|
||||||
|
updateButton: "[data-cy=update-button]",
|
||||||
|
changePasswordButton: "[data-cy=change-password-button]",
|
||||||
|
currentPasswordField: "[data-cy=current-password-input]",
|
||||||
|
newPasswordField: "[data-cy=new-password-input]",
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
export const path={
|
export const path={
|
||||||
loginPath:"/login",
|
loginPath: "/login",
|
||||||
|
profilePath: "/settings"
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commonText={
|
export const commonText={
|
||||||
autoSave:"All changes are saved"
|
autoSave: "All changes are saved",
|
||||||
|
email: "dev@tooljet.io",
|
||||||
|
password: "password"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
23
cypress/constants/texts/profile.js
Normal file
23
cypress/constants/texts/profile.js
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
export const profileText={
|
||||||
|
profileElements:{
|
||||||
|
pageTitle: "Profile Settings",
|
||||||
|
profileCard: "Profile",
|
||||||
|
firstNameLabel: "First name ",
|
||||||
|
lastNameLabel: "Last name",
|
||||||
|
emailLabel: "Email ",
|
||||||
|
passwordCard: "Change password",
|
||||||
|
currentPasswordLabel: "Current password",
|
||||||
|
newPasswordLabel: "New password",
|
||||||
|
},
|
||||||
|
firstName: "The",
|
||||||
|
lastName: "Developer",
|
||||||
|
updateButton: "Update",
|
||||||
|
email: "dev@tooljet.io",
|
||||||
|
nameSuccessToast: "Details updated!",
|
||||||
|
nameErrorToast: "Name can't be empty!",
|
||||||
|
newPassword: "newpassword",
|
||||||
|
changePasswordButton: "Change password",
|
||||||
|
passwordErrorToast: "Please verify that you have entered the correct password",
|
||||||
|
passwordSuccessToast: "Password updated successfully",
|
||||||
|
loginErrorToast:"Invalid email or password",
|
||||||
|
}
|
||||||
|
|
@ -2,12 +2,18 @@ import faker from 'faker'
|
||||||
export let fake ={};
|
export let fake ={};
|
||||||
|
|
||||||
function email(){
|
function email(){
|
||||||
return (`${faker.name.findName()}@example.com`)
|
return (`${faker.name.findName()}@example.com`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function password(){
|
function password(){
|
||||||
return(faker.internet.password())
|
return(faker.internet.password());
|
||||||
|
}
|
||||||
|
function firstName(){
|
||||||
|
return (faker.name.firstName());
|
||||||
|
}
|
||||||
|
function lastName(){
|
||||||
|
return (faker.name.lastName());
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(fake, "email", {get:email});
|
Object.defineProperty(fake, "email", {get:email});
|
||||||
Object.defineProperty(fake, "password", {get:password});
|
Object.defineProperty(fake, "password", {get:password});
|
||||||
|
Object.defineProperty(fake, "firstName", {get:firstName});
|
||||||
|
Object.defineProperty(fake, "lastName", {get:lastName});
|
||||||
120
cypress/integration/dashboard/profile.spec.js
Normal file
120
cypress/integration/dashboard/profile.spec.js
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
import { profileSelector } from "Selectors/profile";
|
||||||
|
import * as profile from "Support/utils/profile"
|
||||||
|
import * as common from "Support/utils/common"
|
||||||
|
import { profileText } from "Texts/profile";
|
||||||
|
import {commonSelectors} from "Selectors/common";
|
||||||
|
import { fake } from "Fixtures/fake";
|
||||||
|
import { commonText } from "Texts/common";
|
||||||
|
|
||||||
|
describe("Profile Settings",()=>{
|
||||||
|
let user;
|
||||||
|
const randomFirstName = fake.firstName;
|
||||||
|
const randomLastName = fake.lastName;
|
||||||
|
beforeEach(()=>{
|
||||||
|
cy.fixture("credentials/login.json").then(login=>{
|
||||||
|
user = login;
|
||||||
|
});
|
||||||
|
cy.appUILogin();
|
||||||
|
common.navigateToProfile();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should verify the elements on profile settings page and name reset functionality",()=>{
|
||||||
|
profile.profilePageElements();
|
||||||
|
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameSuccessToast);
|
||||||
|
|
||||||
|
cy.get(profileSelector.firstNameInput).clear();
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameErrorToast);
|
||||||
|
|
||||||
|
cy.get(profileSelector.lastNameInput).clear();
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameErrorToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.firstNameInput , profileText.firstName);
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameErrorToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.firstNameInput , randomFirstName);
|
||||||
|
cy.clearAndType(profileSelector.lastNameInput , randomLastName);
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameSuccessToast);
|
||||||
|
cy.get(profileSelector.firstNameInput).should("be.visible").and("have.value", randomFirstName);
|
||||||
|
cy.get(profileSelector.lastNameInput).should("be.visible").and("have.value", randomLastName);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.firstNameInput , profileText.firstName);
|
||||||
|
cy.clearAndType(profileSelector.lastNameInput , profileText.lastName);
|
||||||
|
cy.get(profileSelector.updateButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.nameSuccessToast);
|
||||||
|
cy.get(profileSelector.firstNameInput).should("be.visible").and("have.value", profileText.firstName);
|
||||||
|
cy.get(profileSelector.lastNameInput).should("be.visible").and("have.value", profileText.lastName);
|
||||||
|
common.logout();
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Should verify the password reset functionality",()=>{
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage, profileText.passwordErrorToast);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", "");
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", "");
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField, user.password);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", user.password);
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", "");
|
||||||
|
cy.wait(500);
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordSuccessToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField, profileText.newPassword);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", profileText.newPassword )
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordErrorToast);
|
||||||
|
|
||||||
|
cy.get(profileSelector.currentPasswordField).clear();
|
||||||
|
cy.clearAndType(profileSelector.newPasswordField,profileText.newPassword);
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", profileText.newPassword )
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordErrorToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField, profileText.newPassword);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", profileText.newPassword)
|
||||||
|
cy.clearAndType(profileSelector.newPasswordField, user.password);
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", user.password )
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordErrorToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField, user.password);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", user.password)
|
||||||
|
cy.clearAndType(profileSelector.newPasswordField,profileText.newPassword);
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", profileText.newPassword )
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordSuccessToast);
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField, user.password);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("have.value", user.password)
|
||||||
|
cy.clearAndType(profileSelector.newPasswordField,profileText.newPassword);
|
||||||
|
cy.get(profileSelector.newPasswordField).should("have.value", profileText.newPassword )
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordSuccessToast);
|
||||||
|
|
||||||
|
common.logout();
|
||||||
|
cy.wait(1000);
|
||||||
|
cy.clearAndType(commonSelectors.emailField, commonText.email);
|
||||||
|
cy.clearAndType(commonSelectors.passwordField, commonText.password);
|
||||||
|
cy.get(commonSelectors.signInButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.loginErrorToast);
|
||||||
|
|
||||||
|
cy.clearAndType(commonSelectors.passwordField, profileText.newPassword);
|
||||||
|
cy.get(commonSelectors.signInButton).click();
|
||||||
|
common.navigateToProfile();
|
||||||
|
|
||||||
|
cy.clearAndType(profileSelector.currentPasswordField,profileText.newPassword);
|
||||||
|
cy.clearAndType(profileSelector.newPasswordField, user.password);
|
||||||
|
cy.get(profileSelector.changePasswordButton).click();
|
||||||
|
cy.verifyToastMessage(commonSelectors.toastMessage,profileText.passwordSuccessToast);
|
||||||
|
common.logout();
|
||||||
|
|
||||||
|
cy.login(user.email,user.password);
|
||||||
|
common.logout();
|
||||||
|
})
|
||||||
|
});
|
||||||
14
cypress/support/utils/common.js
Normal file
14
cypress/support/utils/common.js
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { path } from "Texts/common";
|
||||||
|
import { profileSelector } from "Selectors/profile";
|
||||||
|
|
||||||
|
export const navigateToProfile=()=>{
|
||||||
|
cy.get(profileSelector.profileDropdown).invoke("show");
|
||||||
|
cy.contains("Profile").click();
|
||||||
|
cy.url().should("include", path.profilePath);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const logout=()=>{
|
||||||
|
cy.get(profileSelector.profileDropdown).invoke("show");
|
||||||
|
cy.contains("Logout").click();
|
||||||
|
cy.url().should("include",path.loginPath);
|
||||||
|
};
|
||||||
16
cypress/support/utils/profile.js
Normal file
16
cypress/support/utils/profile.js
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { profileSelector } from "Selectors/profile";
|
||||||
|
import { profileText } from "Texts/profile";
|
||||||
|
|
||||||
|
export const profilePageElements = () =>{
|
||||||
|
for(const elements in profileSelector.profileElements ){
|
||||||
|
cy.get(profileSelector.profileElements[elements]).should("be.visible").and("have.text",profileText.profileElements[elements]);
|
||||||
|
}
|
||||||
|
cy.get(profileSelector.updateButton).should("be.visible").and("have.text", profileText.updateButton);
|
||||||
|
cy.get(profileSelector.changePasswordButton).should("be.visible").and("have.text", profileText.changePasswordButton);
|
||||||
|
cy.get(profileSelector.firstNameInput).should("be.visible").and("have.value", profileText.firstName);
|
||||||
|
cy.get(profileSelector.lastNameInput).should("be.visible").and("have.value", profileText.lastName);
|
||||||
|
cy.get(profileSelector.emailInput).should("be.visible").and("have.value", profileText.email);
|
||||||
|
cy.get(profileSelector.currentPasswordField).should("be.visible").should("be.visible");
|
||||||
|
cy.get(profileSelector.newPasswordField).should("be.visible").should("be.visible");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -61,7 +61,9 @@ function SettingsPage(props) {
|
||||||
<div className="row align-items-center">
|
<div className="row align-items-center">
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="page-pretitle"></div>
|
<div className="page-pretitle"></div>
|
||||||
<h2 className="page-title">Profile Settings</h2>
|
<h2 className="page-title" data-cy="page-title">
|
||||||
|
Profile Settings
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -71,13 +73,17 @@ function SettingsPage(props) {
|
||||||
<div className="container-xl">
|
<div className="container-xl">
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<h3 className="card-title">Profile</h3>
|
<h3 className="card-title" data-cy="card-title-profile">
|
||||||
|
Profile
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">First name </label>
|
<label className="form-label" data-cy="first-name-label">
|
||||||
|
First name{' '}
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
|
@ -85,12 +91,15 @@ function SettingsPage(props) {
|
||||||
placeholder="Enter first name"
|
placeholder="Enter first name"
|
||||||
value={firstName}
|
value={firstName}
|
||||||
onChange={(event) => setFirstName(event.target.value)}
|
onChange={(event) => setFirstName(event.target.value)}
|
||||||
|
data-cy="first-name-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">Last name</label>
|
<label className="form-label" data-cy="last-name-label">
|
||||||
|
Last name
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
|
@ -98,14 +107,25 @@ function SettingsPage(props) {
|
||||||
placeholder="Enter last name"
|
placeholder="Enter last name"
|
||||||
value={lastName}
|
value={lastName}
|
||||||
onChange={(event) => setLastName(event.target.value)}
|
onChange={(event) => setLastName(event.target.value)}
|
||||||
|
data-cy="last-name-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-6">
|
<div className="col-6">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">Email </label>
|
<label className="form-label" data-cy="email-label">
|
||||||
<input type="text" className="form-control" name="email" value={email} readOnly disabled />
|
Email{' '}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="form-control"
|
||||||
|
name="email"
|
||||||
|
value={email}
|
||||||
|
readOnly
|
||||||
|
disabled
|
||||||
|
data-cy="email-input"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -115,6 +135,7 @@ function SettingsPage(props) {
|
||||||
href="#"
|
href="#"
|
||||||
className={'btn btn-primary' + (updateInProgress ? ' btn-loading' : '')}
|
className={'btn btn-primary' + (updateInProgress ? ' btn-loading' : '')}
|
||||||
onClick={updateDetails}
|
onClick={updateDetails}
|
||||||
|
data-cy="update-button"
|
||||||
>
|
>
|
||||||
Update
|
Update
|
||||||
</a>
|
</a>
|
||||||
|
|
@ -126,13 +147,17 @@ function SettingsPage(props) {
|
||||||
<br />
|
<br />
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<h3 className="card-title">Change password</h3>
|
<h3 className="card-title" data-cy="card-title-change-password">
|
||||||
|
Change password
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">Current password</label>
|
<label className="form-label" data-cy="current-password-label">
|
||||||
|
Current password
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
|
@ -140,12 +165,15 @@ function SettingsPage(props) {
|
||||||
placeholder="Enter current password"
|
placeholder="Enter current password"
|
||||||
value={currentpassword}
|
value={currentpassword}
|
||||||
onChange={(event) => setCurrentPassword(event.target.value)}
|
onChange={(event) => setCurrentPassword(event.target.value)}
|
||||||
|
data-cy="current-password-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<label className="form-label">New password</label>
|
<label className="form-label" data-cy="new-password-label">
|
||||||
|
New password
|
||||||
|
</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
className="form-control"
|
className="form-control"
|
||||||
|
|
@ -154,6 +182,7 @@ function SettingsPage(props) {
|
||||||
value={newPassword}
|
value={newPassword}
|
||||||
onChange={(event) => setNewPassword(event.target.value)}
|
onChange={(event) => setNewPassword(event.target.value)}
|
||||||
onKeyPress={newPasswordKeyPressHandler}
|
onKeyPress={newPasswordKeyPressHandler}
|
||||||
|
data-cy="new-password-input"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -162,6 +191,7 @@ function SettingsPage(props) {
|
||||||
href="#"
|
href="#"
|
||||||
className={'btn btn-primary' + (passwordChangeInProgress ? ' btn-loading' : '')}
|
className={'btn btn-primary' + (passwordChangeInProgress ? ' btn-loading' : '')}
|
||||||
onClick={changePassword}
|
onClick={changePassword}
|
||||||
|
data-cy="change-password-button"
|
||||||
>
|
>
|
||||||
Change password
|
Change password
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ export const Header = function Header({ switchDarkMode, darkMode }) {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<div className="dropdown-menu dropdown-menu-end dropdown-menu-arrow end-0">
|
<div className="dropdown-menu dropdown-menu-end dropdown-menu-arrow end-0" data-cy="dropdown-menu">
|
||||||
<Link
|
<Link
|
||||||
data-testid="settingsBtn"
|
data-testid="settingsBtn"
|
||||||
to="#"
|
to="#"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue