diff --git a/frontend/cypress/e2e/tab.cy.ts b/frontend/cypress/e2e/tab.cy.ts index 9ce4a096a6..c7d700b661 100644 --- a/frontend/cypress/e2e/tab.cy.ts +++ b/frontend/cypress/e2e/tab.cy.ts @@ -1,6 +1,8 @@ import * as users from '../fixtures/users.json'; import { onlyOn } from '@cypress/skip-test'; import CyOverviewPage from '../support/helper/pom-helper/pages/overviewPage'; +import { Unit } from '../../src/app/shared/types/enums/Unit'; +import KeyresultDetailPage from '../support/helper/pom-helper/pages/keyresultDetailPage'; describe('Tab workflow tests', () => { let overviewPage: CyOverviewPage; @@ -32,10 +34,14 @@ describe('Tab workflow tests', () => { cy.pressUntilContains('Logout', 'ArrowDown'); focusedShouldHaveTestId('logout'); cy.realPress('Escape'); + tabAndCheck('quarterFilter', 'GJ'); + tabAndCheck('objectiveSearch'); cy.tabForward(); - cy.focused().contains('GJ'); - cy.tabForward(); - cy.tabForward(); + cy.focused() + .children('img') + .first() + .should('have.attr', 'src') + .and('match', /search-icon.svg/); cy.tabForward(); cy.focused().contains('Alle'); }); @@ -49,8 +55,8 @@ describe('Tab workflow tests', () => { tabAndCheck('add-keyResult', 'Key Result hinzufügen'); }); - describe('Objective forms', () => { - it('objective add', () => { + describe('Objective', () => { + it('should be able to tab objective dialog', () => { tabAndCheck('add-objective', 'Objective hinzufügen'); cy.realPress('Enter'); cy.contains('h2', 'Objective für'); @@ -64,7 +70,7 @@ describe('Tab workflow tests', () => { tabAndCheck('cancel'); }); - it('focus to three dot menu should be restored after edit objective', () => { + it('should focus three dot menu after edit objective', () => { overviewPage.getObjectiveByState('ongoing').focus(); tabAndCheck('three-dot-menu'); cy.realPress('Enter'); @@ -81,46 +87,242 @@ describe('Tab workflow tests', () => { focusedShouldHaveTestId('three-dot-menu'); }); - it('objective complete', () => { + it('should be able to complete and reopen objective', () => { overviewPage.getObjectiveByState('ongoing').focus(); tabAndCheck('three-dot-menu'); cy.realPress('Enter'); tabToThreeDotMenuOption('Objective abschliessen'); cy.contains('h2', 'Objective abschliessen '); focusedShouldHaveTestId('close-dialog'); - cy.realPress('Tab'); + cy.tabForward(); cy.focused().contains('Objective erreicht'); + cy.realPress('Enter'); + cy.tabForward(); cy.focused().contains('Objective nicht erreicht'); tabAndCheck('completeComment'); - cy.realType('description'); - cy.realPress('Tab'); - cy.focused().contains('Abbrechen'); - tabAndCheck('submit', 'Speichern'); + tabAndCheck('cancel', 'Abbrechen'); + tabAndCheck('submit', 'Objective abschliessen'); + cy.realPress('Enter'); + + focusedShouldHaveTestId('three-dot-menu'); + cy.realPress('Enter'); + + tabToThreeDotMenuOption('Objective wiedereröffnen'); + cy.contains('h2', 'Objective wiedereröffnen'); + focusedShouldHaveTestId('close-dialog'); + cy.contains('Soll dieses Objective wiedereröffnet werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); cy.realPress('Enter'); focusedShouldHaveTestId('three-dot-menu'); }); - it('objective to draft', () => { + it('should be able to set objective to draft and publish it', () => { overviewPage.getObjectiveByState('ongoing').focus(); tabAndCheck('three-dot-menu'); cy.realPress('Enter'); tabToThreeDotMenuOption('Objective als Draft speichern'); - cy.contains('h2', 'Objective abschliessen '); + cy.contains('h2', 'Objective als Draft speichern'); focusedShouldHaveTestId('close-dialog'); - cy.realPress('Tab'); - cy.focused().contains('Objective erreicht'); - cy.focused().contains('Objective nicht erreicht'); - tabAndCheck('completeComment'); - cy.realType('description'); - cy.realPress('Tab'); - cy.focused().contains('Abbrechen'); - tabAndCheck('submit', 'Speichern'); + cy.contains('Soll dieses Objective als Draft gespeichert werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); cy.realPress('Enter'); + focusedShouldHaveTestId('three-dot-menu'); + cy.realPress('Enter'); + + tabToThreeDotMenuOption('Objective veröffentlichen'); + cy.contains('h2', 'Objective veröffentlichen'); + focusedShouldHaveTestId('close-dialog'); + cy.contains('Soll dieses Objective veröffentlicht werden?'); + tabAndCheck('confirm-no', 'Nein'); + tabAndCheck('confirm-yes', 'Ja'); + cy.realPress('Enter'); + focusedShouldHaveTestId('three-dot-menu'); + }); + + it('should be able to open objective detail view', () => { + overviewPage.getObjectiveByState('ongoing').focus(); + cy.realPress('Enter').tabForward(); + focusedShouldHaveTestId('closeDrawer'); + tabAndCheck('add-keyResult-objective-detail', 'Key Result hinzufügen'); + tabAndCheck('edit-objective', 'Objective bearbeiten'); + }); + }); + + describe('Keyresult & Check-In', () => { + it('Should be able to tab Keyresult dialog', () => { + tabAndCheck('add-keyResult', 'Key Result hinzufügen'); + cy.realPress('Enter'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('titleInput'); + cy.focused().type('Title'); + tabAndCheck('unit'); + tabAndCheck('baseline'); + tabAndCheck('stretchGoal'); + tabAndCheck('ownerInput'); + tabAndCheck('descriptionInput'); + tabAndCheck('actionInput'); + tabAndCheck('add-action-plan-line', 'Weitere Action hinzufügen'); + tabAndCheck('ordinalTab', 'Ordinal'); + cy.realPress('Enter'); + tabAndCheck('commitZone'); + cy.focused().type('Commit'); + tabAndCheck('targetZone'); + cy.focused().type('Target'); + tabAndCheck('stretchZone'); + cy.focused().type('Stretch'); + tabAndCheck('submit', 'Speichern'); + tabAndCheck('saveAndNew', 'Speichern & Neu'); + tabAndCheck('cancel', 'Abbrechen'); + }); + + it('Should tab keyresult detail view', () => { + cy.getByTestId('key-result').first().focus(); + cy.realPress('Enter').tabForward(); + focusedShouldHaveTestId('close-drawer'); + tabAndCheck('show-all-checkins', 'Alle Check-ins anzeigen'); + cy.realPress('Enter'); + cy.contains('Check-in History'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('edit-check-in'); + tabAndCheck('closeButton', 'Schliessen'); + cy.realPress('Enter'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + tabAndCheck('edit-keyResult', 'Key Result bearbeiten'); + }); + + it('Should tab create-check-in metric', () => { + overviewPage + .addKeyresult() + .fillKeyresultTitle('A metric Keyresult for tabbing tests') + .withMetricValues(Unit.CHF, '10', '100') + .submit(); + KeyresultDetailPage.do().visit('A metric Keyresult for tabbing tests'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + cy.realPress('Enter'); + cy.contains('Check-in erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('changeInfo'); + tabAndCheck('check-in-metric-value'); + cy.focused().type('20'); + tabAndCheck('initiatives'); + cy.contains('5/10'); + cy.tabForward(); + cy.realPress('ArrowLeft'); + cy.contains('4/10'); + tabAndCheck('submit-check-in', 'Check-in speichern'); + tabAndCheck('cancel', 'Abbrechen'); + }); + + it('Should tab create-check-in ordinal', () => { + overviewPage + .addKeyresult() + .fillKeyresultTitle('A ordinal Keyresult for tabbing tests') + .withOrdinalValues('Commit', 'Target', 'Stretch') + .submit(); + KeyresultDetailPage.do().visit('A ordinal Keyresult for tabbing tests'); + tabAndCheck('add-check-in', 'Check-in erfassen'); + cy.realPress('Enter'); + cy.contains('Check-in erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('changeInfo'); + cy.tabForward(); + cy.focused().closest('mat-radio-button').should('have.attr', 'data-testId', 'fail-radio'); + cy.realPress('ArrowDown'); + cy.focused().closest('mat-radio-button').should('have.attr', 'data-testId', 'commit-radio'); + cy.realPress('ArrowDown'); + cy.focused().closest('mat-radio-button').should('have.attr', 'data-testId', 'target-radio'); + cy.realPress('ArrowDown'); + cy.focused().closest('mat-radio-button').should('have.attr', 'data-testId', 'stretch-radio'); + tabAndCheck('initiatives'); + cy.contains('5/10'); + cy.tabForward(); + cy.realPress('ArrowLeft'); + cy.contains('4/10'); + tabAndCheck('submit-check-in', 'Check-in speichern'); + tabAndCheck('cancel', 'Abbrechen'); + }); + }); + + describe('Team management', () => { + it('Should tab team management', () => { + tabAndCheck('team-management', 'Teamverwaltung'); + cy.realPress('Enter'); + tabAndCheck('routerLink-to-overview', 'Zurück zur OKR Übersicht'); + tabAndCheck('teamManagementSearch'); + tabAndCheck('add-team', 'Team erfassen'); + tabAndCheck('all-teams-selector', 'Alle Teams (4)'); + tabAndCheck('invite-member', 'Member registrieren'); + }); + it('Should tab create team', () => { + cy.getByTestId('team-management').click(); + tabAndCheck('add-team'); + cy.realPress('Enter'); + cy.contains('Team erfassen'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('add-team-name'); + cy.focused().type('Name of new team'); + tabAndCheck('safe', 'Speichern'); + tabAndCheck('cancel', 'Abbrechen'); + }); + it('Should tab register member', () => { + cy.getByTestId('team-management').click(); + tabAndCheck('invite-member'); + cy.realPress('Enter'); + cy.contains('Member registrieren'); + focusedShouldHaveTestId('close-dialog'); + tabAndCheck('new-member-first-name'); + tabAndCheck('new-member-last-name'); + tabAndCheck('email-col_0'); + cy.tabForward(); + cy.focused().closest('app-puzzle-icon-button').should('have.attr', 'icon', 'delete-icon.svg'); + tabAndCheck('new-member-add-row', 'Weiterer Member hinzufügen'); + tabAndCheck('invite', 'Einladen'); + tabAndCheck('new-member-cancel', 'Abbrechen'); + }); + it('Should tab edit member', () => { + cy.getByTestId('team-management').click(); + cy.pressUntilContains('Alice Wunderland', 'Tab'); + cy.tabForward(); + cy.realPress('Enter'); + cy.tabForward(); + focusedShouldHaveTestId('close-drawer'); + + // Field to toggle if user is OKR-Champion + cy.tabForward(); + cy.focused().closest('app-puzzle-icon-button').should('have.attr', 'icon', 'edit.svg'); + cy.realPress('Enter'); + cy.tabForward(); + tabAndCheck('close-drawer'); + cy.tabForward(); + cy.focused().closest('mat-checkbox').should('have.attr', 'data-testId', 'edit-okr-champion-checkbox'); + + // Field to edit role of assigned team + cy.tabForward(); + cy.focused().closest('app-puzzle-icon-button').should('have.attr', 'icon', 'edit.svg'); + cy.realPress('Enter'); + cy.tabForward(); + tabAndCheck('select-team-role', 'Team-Member'); + + // Button to delete assigned team + cy.tabForward(); + cy.focused().closest('app-puzzle-icon-button').should('have.attr', 'icon', 'delete-icon.svg'); + + // Button to add user to another team + tabAndCheck('add-user'); + cy.realPress('Enter'); + cy.tabForward(); + tabAndCheck('select-team-dropdown', '/BBT'); + tabAndCheck('select-team-role', 'Team-Member'); + tabAndCheck('add-user-to-team-save', 'Hinzufügen'); + tabAndCheck('add-user-to-team-cancel', 'Abbrechen'); }); }); }); + function tabToThreeDotMenuOption(name: string) { - cy.tabForwardUntil(`:contains('${name}')`); + cy.pressUntilContains(name, 'ArrowDown'); cy.realPress('Enter'); } diff --git a/frontend/src/app/components/objective/objective.component.ts b/frontend/src/app/components/objective/objective.component.ts index d67984a57b..d3e5d50d1d 100644 --- a/frontend/src/app/components/objective/objective.component.ts +++ b/frontend/src/app/components/objective/objective.component.ts @@ -49,7 +49,9 @@ export class ObjectiveComponent { .pipe(take(1)) .subscribe((result) => { this.objectiveService.getFullObjective(objectiveMin.id).subscribe((objective) => { - menuEntry.afterAction(objective, result); + if (result) { + menuEntry.afterAction(objective, result); + } this.trigger?.focus(); }); }); diff --git a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.html b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.html index e4eae92721..b3950a20a5 100644 --- a/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.html +++ b/frontend/src/app/shared/dialog/complete-dialog/complete-dialog.component.html @@ -70,7 +70,7 @@