From 4ce8cdf97732aa0aa4a0317a8461fe30cdfaf8d9 Mon Sep 17 00:00:00 2001 From: Martin <git@mail.de> Date: Fri, 28 Feb 2025 09:57:57 +0100 Subject: [PATCH 1/6] OZG-7620 adjust hint text for roles --- .../user-form-roles/user-form-roles.component.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html index 129d847663..10b190c0ac 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html @@ -6,7 +6,7 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.ADMIN" label="Admin" inputId="admin" /> <button - tooltip='Wird nur in Kombination mit "User" verwendet. Diese Rolle kann Funktionen in Keycloak und der Administration konfigurieren, z.B. Benutzer anlegen, Gruppen erstellen bzw. Organisationseinheiten hinzufügen und Rollen zuweisen.' + tooltip="Diese Rolle kann Funktionen der OZG-Cloud konfigurieren, z.B. Benutzer anlegen, Organisationseinheiten hinzufügen und Rollen zuweisen." > <ods-info-icon /> </button> @@ -17,7 +17,7 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.LOESCHEN" label="Löschen" inputId="delete" /> <button - tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" ausgewählte Vorgänge aus Alfa löschen. Diese Rolle sollten zwei Benutzer haben, da das Löschen einem Vieraugen-Prinzip folgt.' + tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" Löschanträge aus Alfa bestätigen. ' > <ods-info-icon /> </button> @@ -25,16 +25,14 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.USER" label="User" inputId="user" /> <button - tooltip='Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind. Ist kompatibel mit "Löschen" und "Admin".' + tooltip="Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind." > <ods-info-icon /> </button> </div> <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.POSTSTELLE" label="Poststelle" inputId="post_office" /> - <button - tooltip='Diese Rolle kann ausschließlich alle neu eingegangenen Vorgänge sehen und anderen Benutzern zuweisen. Sie sollte nur einem Benutzer zugewiesen sein. Dieser sollte keine weiteren Rollen besitzen. (Sie ist aber kompatibel mit der "Admin")' - > + <button tooltip="Diese Rolle kann alle neu eingegangenen Vorgänge sehen."> <ods-info-icon /> </button> </div> -- GitLab From fbe82da5fb03739295dd189260a5ef058dc43a16 Mon Sep 17 00:00:00 2001 From: Martin <git@mail.de> Date: Fri, 28 Feb 2025 12:40:20 +0100 Subject: [PATCH 2/6] OZG-7619 add data-test-id to tooltip component --- .../src/lib/tooltip/tooltip.component.ts | 3 + .../src/lib/tooltip/tooltip.directive.spec.ts | 63 +++++++++++++++---- .../src/lib/tooltip/tooltip.directive.ts | 12 +++- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts index 671af95796..f62b0e9248 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.component.ts @@ -29,6 +29,7 @@ import { TooltipPosition } from './tooltip.directive'; selector: 'ods-tooltip', imports: [NgClass], template: `<span + [attr.data-test-id]="dataTestId" class="tooltip fixed z-[100] animate-fadeIn cursor-default break-words rounded bg-ozggray-900 px-3 py-2 text-sm font-normal text-whitetext before:absolute before:border-l-[0.5rem] before:border-r-[0.5rem] before:border-l-transparent before:border-r-transparent dark:bg-white" [ngClass]="class" [class.visible]="show" @@ -58,6 +59,8 @@ export class TooltipComponent { class: string; leftOffset: number; + dataTestId: string; + set position(value: TooltipPosition) { if (value === TooltipPosition.ABOVE) { this.class = diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts index 76c569e424..3b775dd56d 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.spec.ts @@ -21,6 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ +import { assignValue, mock, useFromMock } from '@alfa-client/test-utils'; import { InteractivityChecker } from '@angular/cdk/a11y'; import { ComponentRef, ElementRef, Renderer2, ViewContainerRef } from '@angular/core'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; @@ -37,6 +38,18 @@ class MockElementRef extends ElementRef { describe('TooltipDirective', () => { let directive: TooltipDirective; + const mockComponentRefInstance: TooltipComponent = { + id: '', + left: 0, + top: 0, + text: '', + show: false, + position: TooltipPosition.BELOW, + class: '', + leftOffset: 0, + width: null, + dataTestId: undefined, + }; const mockComponentRef: ComponentRef<TooltipComponent> = { setInput: jest.fn(), destroy: jest.fn(), @@ -46,17 +59,7 @@ describe('TooltipDirective', () => { location: null, hostView: null, injector: null, - instance: { - id: '', - left: 0, - top: 0, - text: '', - show: false, - position: TooltipPosition.BELOW, - class: '', - leftOffset: 0, - width: null, - }, + instance: mockComponentRefInstance, }; const parentRect: DOMRect = { bottom: 0, top: 0, height: 0, left: 0, right: 0, toJSON: jest.fn(), width: 0, x: 0, y: 0 }; @@ -119,6 +122,7 @@ describe('TooltipDirective', () => { directive.setInitialTooltipProperties = jest.fn(); directive.getParentElement = jest.fn().mockReturnValue({ appendChild: jest.fn() }); directive.interactivityChecker.isFocusable = jest.fn(); + directive._addDataTestId = jest.fn(); }); it('should create tooltip component', () => { @@ -156,6 +160,43 @@ describe('TooltipDirective', () => { expect(directive.getParentElement).not.toHaveBeenCalled(); }); + + it('should call add data test id', () => { + directive.createTooltip(tooltipText); + + expect(directive._addDataTestId).toHaveBeenCalled(); + }); + }); + + describe('add data test id', () => { + const dataTestId: string = 'dummyDataTestId'; + + beforeEach(() => { + directive.componentRef = assignValue(mockComponentRef, 'instance', { ...mockComponentRef.instance, dataTestId: undefined }); + }); + + it('should set attribute to tooltip component if exists', () => { + directive.parentElement = mockParentAttribute(dataTestId); + + directive._addDataTestId(); + + expect(directive.componentRef.instance.dataTestId).toBe(dataTestId + directive.dataTestIdTooltipSuffix); + }); + + it('should NOT set attribute to tooltip component if undefined', () => { + directive.parentElement = mockParentAttribute(undefined); + + directive._addDataTestId(); + + expect(directive.componentRef.instance.dataTestId).toBeUndefined(); + }); + + function mockParentAttribute(value: any): HTMLElement { + return useFromMock<HTMLElement>({ + ...mock(HTMLElement), + getAttribute: jest.fn().mockReturnValue(value), + }); + } }); describe('showTooltip', () => { diff --git a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts index d8f42d4ab8..10cca117f0 100644 --- a/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts +++ b/alfa-client/libs/design-system/src/lib/tooltip/tooltip.directive.ts @@ -21,7 +21,7 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { isEscapeKey, isNotNull } from '@alfa-client/tech-shared'; +import { isEscapeKey, isNotNull, isNotUndefined } from '@alfa-client/tech-shared'; import { InteractivityChecker } from '@angular/cdk/a11y'; import { ComponentRef, @@ -80,6 +80,10 @@ export class TooltipDirective implements OnDestroy { public readonly renderer: Renderer2 = inject(Renderer2); public readonly interactivityChecker: InteractivityChecker = inject(InteractivityChecker); + dataTestIdParentAttribute: string = 'data-test-id'; + dataTestIdAttribute: string = 'dataTestId'; + dataTestIdTooltipSuffix: string = '-tooltip'; + ngOnDestroy(): void { this.destroy(); } @@ -120,12 +124,18 @@ export class TooltipDirective implements OnDestroy { const nativeElement: HTMLElement = this.elementRef.nativeElement; this.componentRef = this.viewContainerRef.createComponent(TooltipComponent); this.parentElement = this.getParentElement(nativeElement); + this._addDataTestId(); this.parentElement.appendChild(this.componentRef.location.nativeElement); this.tooltipId = uniqueId('tooltip'); this.setInitialTooltipProperties(tooltipText, this.tooltipId); this.setAriaAttribute(this.tooltipAriaType); } + _addDataTestId(): void { + const dataTestId: string = this.parentElement.getAttribute(this.dataTestIdParentAttribute); + if (isNotUndefined(dataTestId)) this.componentRef.instance.dataTestId = dataTestId + this.dataTestIdTooltipSuffix; + } + setInitialTooltipProperties(text: string, id: string) { this.componentRef.instance.text = text; this.componentRef.instance.id = id; -- GitLab From 83dd535d4fd881e470624993fb9035d8efe223cf Mon Sep 17 00:00:00 2001 From: Martin <git@mail.de> Date: Fri, 28 Feb 2025 12:41:03 +0100 Subject: [PATCH 3/6] OZG-7619 add e2e tests for user role tooltips --- .../benutzer/benutzer.e2e.component.ts | 50 ++++++-- .../benutzer_rollen/benutzer_rollen.cy.ts | 121 +++++++++++------- .../src/helper/benutzer/benutzer.executor.ts | 8 +- .../admin-e2e/src/support/cypress.util.ts | 4 - .../apps/admin-e2e/src/support/tech-util.ts | 2 +- .../user-form-roles.component.html | 5 +- .../libs/test-utils/src/lib/mocking.ts | 4 + 7 files changed, 129 insertions(+), 65 deletions(-) diff --git a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts index 7b9027ffdc..5fcf929338 100644 --- a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts @@ -94,10 +94,10 @@ export class BenutzerE2EComponent { private readonly userBenutzername: string = 'Benutzername-text-input'; private readonly userMail: string = 'E-Mail-text-input'; - private readonly adminCheckbox: string = 'Admin-checkbox-editor'; - private readonly loeschenCheckbox: string = 'Loschen-checkbox-editor'; - private readonly userCheckbox: string = 'User-checkbox-editor'; - private readonly postCheckbox: string = 'Poststelle-checkbox-editor'; + private readonly adminCheckboxLabel: string = 'Admin'; + private readonly loeschenCheckboxLabel: string = 'Löschen'; + private readonly userCheckboxLabel: string = 'User'; + private readonly postCheckboxLabel: string = 'Poststelle'; private readonly organisationsEinheitCheckboxSuffix: string = '-checkbox-editor'; @@ -119,20 +119,20 @@ export class BenutzerE2EComponent { return cy.getTestElement(this.userMail); } - public getAdminCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.adminCheckbox); + public getAdminCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.adminCheckboxLabel); } - public getLoeschenCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.loeschenCheckbox); + public getLoeschenCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.loeschenCheckboxLabel); } - public getUserCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.userCheckbox); + public getUserCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.userCheckboxLabel); } - public getPostCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.postCheckbox); + public getPostCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.postCheckboxLabel); } public getSaveButton(): Cypress.Chainable<Element> { @@ -147,3 +147,29 @@ export class BenutzerE2EComponent { return cy.getTestElement(this.headline); } } + +export class BenutzerCheckboxE2EComponent { + private rootPrefix: string; + private prefix: string; + + private readonly adminCheckbox: string = '-checkbox-editor'; + private readonly adminInfoButtonSuffix: string = '-role-info-button'; + private readonly adminInfoButtonTooltipSuffix: string = '-role-info-button-tooltip'; + + constructor(label: string) { + this.rootPrefix = convertToDataTestId(label); + this.prefix = convertToDataTestId(label.toLocaleLowerCase()); + } + + public getRoot(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.rootPrefix}${this.adminCheckbox}`); + } + + public getInfoButton(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.prefix}${this.adminInfoButtonSuffix}`); + } + + public getInfoButtonTooltip(): Cypress.Chainable<Element> { + return cy.getTestElement(`${this.prefix}${this.adminInfoButtonTooltipSuffix}`); + } +} diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts index 6f2aeed207..b45dc8f07d 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts @@ -21,15 +21,24 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; -import { OrganisationsEinheitE2E } from 'apps/admin-e2e/src/model/organisations-einheit'; import { BenutzerE2EComponent, BenutzerListE2EComponent, BenutzerListItemE2EComponent, -} from '../../../components/benutzer/benutzer.e2e.component'; -import { beChecked, beEnabled, contains, exist, notBeChecked, notBeEnabled } from '../../../support/cypress.util'; -import { AlfaRollen, AlfaUsers, loginAsAriane } from '../../../support/user-util'; +} from 'apps/admin-e2e/src/components/benutzer/benutzer.e2e.component'; +import { E2EBenutzerHelper } from 'apps/admin-e2e/src/helper/benutzer/benutzer.helper'; +import { OrganisationsEinheitE2E } from 'apps/admin-e2e/src/model/organisations-einheit'; +import { + beChecked, + beEnabled, + contains, + exist, + mouseEnter, + notBeChecked, + notBeEnabled, + visible, +} from 'apps/admin-e2e/src/support/cypress.util'; +import { AlfaRollen, AlfaUsers, loginAsAriane } from 'apps/admin-e2e/src/support/user-util'; describe('Benutzer und Rollen', () => { const benutzerPage: BenutzerE2EComponent = new BenutzerE2EComponent(); @@ -84,56 +93,82 @@ describe('Benutzer und Rollen', () => { exist(benutzerPage.getBenutzernameInput()); exist(benutzerPage.getMailInput()); - notBeChecked(benutzerPage.getAdminCheckbox()); - notBeChecked(benutzerPage.getLoeschenCheckbox()); - notBeChecked(benutzerPage.getUserCheckbox()); - notBeChecked(benutzerPage.getPostCheckbox()); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); + notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); }); it('should activate loeschen checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getLoeschenCheckbox().click(); - beChecked(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); - - benutzerPage.getLoeschenCheckbox().click(); - notBeChecked(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getUserCheckbox()); - beEnabled(benutzerPage.getPostCheckbox()); + benutzerPage.getLoeschenCheckbox().getRoot().click(); + beChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); + + benutzerPage.getLoeschenCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getUserCheckbox().getRoot()); + beEnabled(benutzerPage.getPostCheckbox().getRoot()); }); it('should additionally activate and deactivate admin checkbox', () => { - benutzerPage.getLoeschenCheckbox().click(); - benutzerPage.getAdminCheckbox().click(); - beChecked(benutzerPage.getLoeschenCheckbox()); - beChecked(benutzerPage.getAdminCheckbox()); + benutzerPage.getLoeschenCheckbox().getRoot().click(); + benutzerPage.getAdminCheckbox().getRoot().click(); + beChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + beChecked(benutzerPage.getAdminCheckbox().getRoot()); - benutzerPage.getAdminCheckbox().click(); - notBeChecked(benutzerPage.getAdminCheckbox()); + benutzerPage.getAdminCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); }); it('should activate user checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getLoeschenCheckbox().click(); - benutzerPage.getUserCheckbox().click(); - beChecked(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); - - benutzerPage.getUserCheckbox().click(); - notBeChecked(benutzerPage.getUserCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getPostCheckbox()); + benutzerPage.getLoeschenCheckbox().getRoot().click(); + benutzerPage.getUserCheckbox().getRoot().click(); + beChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); + + benutzerPage.getUserCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getPostCheckbox().getRoot()); }); it('should activate post checkbox and deactivate the other two checkboxes', () => { - benutzerPage.getPostCheckbox().click(); - beChecked(benutzerPage.getPostCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); - - benutzerPage.getPostCheckbox().click(); - notBeChecked(benutzerPage.getPostCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getUserCheckbox()); + benutzerPage.getPostCheckbox().getRoot().click(); + beChecked(benutzerPage.getPostCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); + + benutzerPage.getPostCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getUserCheckbox().getRoot()); + }); + + describe('hint text', () => { + it('should be visible on admin role mouse hover', () => { + mouseEnter(benutzerPage.getAdminCheckbox().getInfoButton()); + + visible(benutzerPage.getAdminCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on loeschen role mouse hover', () => { + mouseEnter(benutzerPage.getLoeschenCheckbox().getInfoButton()); + + visible(benutzerPage.getLoeschenCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on user role mouse hover', () => { + mouseEnter(benutzerPage.getUserCheckbox().getInfoButton()); + + visible(benutzerPage.getUserCheckbox().getInfoButtonTooltip()); + }); + + it('should be visible on poststellt role mouse hover', () => { + mouseEnter(benutzerPage.getPostCheckbox().getInfoButton()); + + visible(benutzerPage.getPostCheckbox().getInfoButtonTooltip()); + }); }); }); diff --git a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts index 9c8898bc0f..938ddad236 100644 --- a/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts +++ b/alfa-client/apps/admin-e2e/src/helper/benutzer/benutzer.executor.ts @@ -15,16 +15,16 @@ export class E2EBenutzerExecutor { this.benutzerPage.getMailInput().type(user.email); if (user.isAdmin) { - this.benutzerPage.getAdminCheckbox().click(); + this.benutzerPage.getAdminCheckbox().getRoot().click(); } if (user.isUser) { - this.benutzerPage.getUserCheckbox().click(); + this.benutzerPage.getUserCheckbox().getRoot().click(); } if (user.isLoeschen) { - this.benutzerPage.getLoeschenCheckbox().click(); + this.benutzerPage.getLoeschenCheckbox().getRoot().click(); } if (user.isPoststelle) { - this.benutzerPage.getPostCheckbox().click(); + this.benutzerPage.getPostCheckbox().getRoot().click(); } this.modifyOrganisationsEinheiten(user.organisationseinheiten); diff --git a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts index 6379636090..d18cc34fbf 100644 --- a/alfa-client/apps/admin-e2e/src/support/cypress.util.ts +++ b/alfa-client/apps/admin-e2e/src/support/cypress.util.ts @@ -60,10 +60,6 @@ export function mouseEnter(element: Cypress.Chainable<Element>): void { element.trigger('mouseenter'); } -export function mouseOver(element: Cypress.Chainable<Element>): void { - element.trigger('mouseover'); -} - export function contains(element: Cypress.Chainable<Element>, containing: string): void { element.should('exist').contains(containing); } diff --git a/alfa-client/apps/admin-e2e/src/support/tech-util.ts b/alfa-client/apps/admin-e2e/src/support/tech-util.ts index a1bbcb74ae..6e6c57d156 100644 --- a/alfa-client/apps/admin-e2e/src/support/tech-util.ts +++ b/alfa-client/apps/admin-e2e/src/support/tech-util.ts @@ -10,6 +10,6 @@ export function replaceAllWhitespaces(value: string, replaceWith: string): strin return value.replace(/ /g, replaceWith); } -export function simpleTransliteration(value: string) { +export function simpleTransliteration(value: string): string { return value.normalize('NFKD').replace(/[^-A-Za-z0-9_]/g, ''); } diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html index 10b190c0ac..b604db4158 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html @@ -6,6 +6,7 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.ADMIN" label="Admin" inputId="admin" /> <button + data-test-id="admin-role-info-button" tooltip="Diese Rolle kann Funktionen der OZG-Cloud konfigurieren, z.B. Benutzer anlegen, Organisationseinheiten hinzufügen und Rollen zuweisen." > <ods-info-icon /> @@ -17,6 +18,7 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.LOESCHEN" label="Löschen" inputId="delete" /> <button + data-test-id="loschen-role-info-button" tooltip='Diese Rolle hat dieselben Rechte wie die Rolle "User". Zusätzlich kann "Löschen" Löschanträge aus Alfa bestätigen. ' > <ods-info-icon /> @@ -25,6 +27,7 @@ <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.USER" label="User" inputId="user" /> <button + data-test-id="user-role-info-button" tooltip="Diese Rolle kann alle Vorgänge sehen und bearbeiten, wenn diese seiner Organisationseinheit zugewiesen sind." > <ods-info-icon /> @@ -32,7 +35,7 @@ </div> <div class="flex items-center gap-2"> <ods-checkbox-editor [formControlName]="UserFormService.POSTSTELLE" label="Poststelle" inputId="post_office" /> - <button tooltip="Diese Rolle kann alle neu eingegangenen Vorgänge sehen."> + <button data-test-id="poststelle-role-info-button" tooltip="Diese Rolle kann alle neu eingegangenen Vorgänge sehen."> <ods-info-icon /> </button> </div> diff --git a/alfa-client/libs/test-utils/src/lib/mocking.ts b/alfa-client/libs/test-utils/src/lib/mocking.ts index 0fb616db60..13ea6f602d 100644 --- a/alfa-client/libs/test-utils/src/lib/mocking.ts +++ b/alfa-client/libs/test-utils/src/lib/mocking.ts @@ -53,3 +53,7 @@ export function mockGetValue(object: any, name: string, returnValue: any): void get: jest.fn(() => returnValue), }); } + +export function assignValue<T>(object: any, attributeName: string, toAssignValue: any): T { + return Object.assign(object, { [attributeName]: toAssignValue }); +} -- GitLab From 1551c927a3be75604b5e54de8db8791202ba09bf Mon Sep 17 00:00:00 2001 From: sebo <sebastian.bergandy@external.mgm-cp.com> Date: Sat, 1 Mar 2025 18:45:07 +0100 Subject: [PATCH 4/6] OZG-7619 fix e2e test --- .../e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts index 0d4a3c538f..e2cbf35c6a 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer-anlegen.cy.ts @@ -57,4 +57,9 @@ describe('Benutzer anlegen', () => { it('should show created user in list', () => { benutzerVerifier.verifyUserInList(newUser); }); + + it('should remove benutzer', () => { + benutzerHelper.deleteBenutzer(newUser.username); + benutzerVerifier.verifyUserNotInList(newUser.username); + }); }); -- GitLab From 6d5745801ace52c67f92d1c16ad1ecedf05845e5 Mon Sep 17 00:00:00 2001 From: Albert <Albert.Bruns@mgm-tp.com> Date: Mon, 3 Mar 2025 16:13:44 +0100 Subject: [PATCH 5/6] OZG-7619 e2e tests datenbeauftragung --- .../src/components/benutzer/benutzer.e2e.component.ts | 4 ++-- .../e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts index a69793b146..bdf514f6f2 100644 --- a/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts +++ b/alfa-client/apps/admin-e2e/src/components/benutzer/benutzer.e2e.component.ts @@ -147,8 +147,8 @@ export class BenutzerE2EComponent { return new BenutzerCheckboxE2EComponent(this.postCheckboxLabel); } - public getDatenbeauftragungCheckbox(): Cypress.Chainable<Element> { - return cy.getTestElement(this.datenbeauftragungLabel); + public getDatenbeauftragungCheckbox(): BenutzerCheckboxE2EComponent { + return new BenutzerCheckboxE2EComponent(this.datenbeauftragungLabel); } public getOrganisationsEinheitCheckbox(einheit: string): Cypress.Chainable<Element> { diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts index b45dc8f07d..faa2082e1c 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts @@ -170,5 +170,11 @@ describe('Benutzer und Rollen', () => { visible(benutzerPage.getPostCheckbox().getInfoButtonTooltip()); }); + + it('should be visible on datenbeauftragung role mouse hover', () => { + mouseEnter(benutzerPage.getDatenbeauftragungCheckbox().getInfoButton()); + + visible(benutzerPage.getPostCheckbox().getInfoButtonTooltip()); + }); }); }); -- GitLab From c01196765a7f694dea5124fe05632087e6a26525 Mon Sep 17 00:00:00 2001 From: sebo <sebastian.bergandy@external.mgm-cp.com> Date: Mon, 3 Mar 2025 17:04:39 +0100 Subject: [PATCH 6/6] OZG-7619 fix e2e test --- .../benutzer_rollen/benutzer_rollen.cy.ts | 74 +++++++++---------- .../user-form-roles.component.html | 7 +- 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts index 9c1ff6974d..205d661f91 100644 --- a/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts +++ b/alfa-client/apps/admin-e2e/src/e2e/main-tests/benutzer_rollen/benutzer_rollen.cy.ts @@ -75,18 +75,18 @@ describe('Benutzer und Rollen', () => { it('should show checkbox for each role', () => { helper.openNewBenutzerPage(); - notBeChecked(benutzerPage.getAdminCheckbox()); - notBeChecked(benutzerPage.getDatenbeauftragungCheckbox()); - notBeChecked(benutzerPage.getLoeschenCheckbox()); - notBeChecked(benutzerPage.getUserCheckbox()); - notBeChecked(benutzerPage.getPostCheckbox()); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); + notBeChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); + notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); }); it('should deactivate other alfa roles if "loeschen" role is selected', () => { - benutzerPage.getLoeschenCheckbox().click(); - beChecked(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); + benutzerPage.getLoeschenCheckbox().getRoot().click(); + beChecked(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); benutzerPage.getLoeschenCheckbox().getRoot().click(); notBeChecked(benutzerPage.getLoeschenCheckbox().getRoot()); @@ -95,39 +95,39 @@ describe('Benutzer und Rollen', () => { }); it('should deactivate other alfa roles if "user" role is selected', () => { - benutzerPage.getUserCheckbox().click(); - beChecked(benutzerPage.getUserCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getPostCheckbox()); - - benutzerPage.getUserCheckbox().click(); - notBeChecked(benutzerPage.getUserCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getPostCheckbox()); + benutzerPage.getUserCheckbox().getRoot().click(); + beChecked(benutzerPage.getUserCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getPostCheckbox().getRoot()); + + benutzerPage.getUserCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getUserCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getPostCheckbox().getRoot()); }); it('should deactivate other alfa roles if "poststelle" role is selected', () => { - benutzerPage.getPostCheckbox().click(); - beChecked(benutzerPage.getPostCheckbox()); - notBeEnabled(benutzerPage.getLoeschenCheckbox()); - notBeEnabled(benutzerPage.getUserCheckbox()); - - benutzerPage.getPostCheckbox().click(); - notBeChecked(benutzerPage.getPostCheckbox()); - beEnabled(benutzerPage.getLoeschenCheckbox()); - beEnabled(benutzerPage.getUserCheckbox()); + benutzerPage.getPostCheckbox().getRoot().click(); + beChecked(benutzerPage.getPostCheckbox().getRoot()); + notBeEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + notBeEnabled(benutzerPage.getUserCheckbox().getRoot()); + + benutzerPage.getPostCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getPostCheckbox().getRoot()); + beEnabled(benutzerPage.getLoeschenCheckbox().getRoot()); + beEnabled(benutzerPage.getUserCheckbox().getRoot()); }); it('should activate and deactivate admin roles', () => { - benutzerPage.getAdminCheckbox().click(); - benutzerPage.getDatenbeauftragungCheckbox().click(); - beChecked(benutzerPage.getAdminCheckbox()); - beChecked(benutzerPage.getDatenbeauftragungCheckbox()); - - benutzerPage.getAdminCheckbox().click(); - benutzerPage.getDatenbeauftragungCheckbox().click(); - notBeChecked(benutzerPage.getAdminCheckbox()); - notBeChecked(benutzerPage.getDatenbeauftragungCheckbox()); + benutzerPage.getAdminCheckbox().getRoot().click(); + benutzerPage.getDatenbeauftragungCheckbox().getRoot().click(); + beChecked(benutzerPage.getAdminCheckbox().getRoot()); + beChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); + + benutzerPage.getAdminCheckbox().getRoot().click(); + benutzerPage.getDatenbeauftragungCheckbox().getRoot().click(); + notBeChecked(benutzerPage.getAdminCheckbox().getRoot()); + notBeChecked(benutzerPage.getDatenbeauftragungCheckbox().getRoot()); }); describe('hint text', () => { @@ -158,7 +158,7 @@ describe('Benutzer und Rollen', () => { it('should be visible on datenbeauftragung role mouse hover', () => { mouseEnter(benutzerPage.getDatenbeauftragungCheckbox().getInfoButton()); - visible(benutzerPage.getPostCheckbox().getInfoButtonTooltip()); + visible(benutzerPage.getDatenbeauftragungCheckbox().getInfoButtonTooltip()); }); }); }); diff --git a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html index d25b43725b..a8931fbcb6 100644 --- a/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html +++ b/alfa-client/libs/admin/user/src/lib/user-form/user-form-roles/user-form-roles.component.html @@ -18,9 +18,12 @@ label="Datenbeauftragung" inputId="datenbeauftragung" /> - <ods-info-icon + <button + data-test-id="datenbeauftragung-role-info-button" tooltip='Diese Rolle kann in der Administration unter dem Menüpunkt "Statistik" Felder zur Auswertung konfigurieren. Sie ist mit allen anderen Rollen kompatibel.' - /> + > + <ods-info-icon /> + </button> </div> </div> <div [formGroupName]="UserFormService.ALFA_GROUP" class="flex flex-col gap-2"> -- GitLab