[DURACOM-309] improve e2e pipeline, fix cookie issues

This commit is contained in:
Andrea Barbasso
2025-05-13 16:19:42 +02:00
parent c0a5420e8b
commit f1a1aebe33
15 changed files with 79 additions and 100 deletions

View File

@@ -29,6 +29,8 @@ jobs:
DSPACE_CACHE_SERVERSIDE_ANONYMOUSCACHE_MAX: 0 DSPACE_CACHE_SERVERSIDE_ANONYMOUSCACHE_MAX: 0
# Tell Cypress to run e2e tests using the same UI URL # Tell Cypress to run e2e tests using the same UI URL
CYPRESS_BASE_URL: http://127.0.0.1:4000 CYPRESS_BASE_URL: http://127.0.0.1:4000
# Disable the cookie consent banner in e2e tests to avoid errors because of elements hidden by it
DSPACE_INFO_ENABLECOOKIECONSENTPOPUP: false
# When Chrome version is specified, we pin to a specific version of Chrome # When Chrome version is specified, we pin to a specific version of Chrome
# Comment this out to use the latest release # Comment this out to use the latest release
#CHROME_VERSION: "90.0.4430.212-1" #CHROME_VERSION: "90.0.4430.212-1"

View File

@@ -105,37 +105,6 @@
"maximumError": "300kb" "maximumError": "300kb"
} }
] ]
},
"production-e2e": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.production-e2e.ts"
},
{
"replace": "src/config/store/devtools.ts",
"with": "src/config/store/devtools.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true,
"budgets": [
{
"type": "initial",
"maximumWarning": "3mb",
"maximumError": "5mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "200kb",
"maximumError": "300kb"
}
]
} }
} }
}, },
@@ -151,9 +120,6 @@
}, },
"production": { "production": {
"buildTarget": "dspace-angular:build:production" "buildTarget": "dspace-angular:build:production"
},
"production-e2e": {
"buildTarget": "dspace-angular:build:production-e2e"
} }
} }
}, },
@@ -215,9 +181,6 @@
"configurations": { "configurations": {
"production": { "production": {
"devServerTarget": "dspace-angular:serve:production" "devServerTarget": "dspace-angular:serve:production"
},
"production-e2e": {
"devServerTarget": "dspace-angular:serve:production-e2e"
} }
} }
}, },
@@ -252,20 +215,6 @@
"with": "src/config/store/devtools.prod.ts" "with": "src/config/store/devtools.prod.ts"
} }
] ]
},
"production-e2e": {
"sourceMap": false,
"optimization": true,
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.production-e2e.ts"
},
{
"replace": "src/config/store/devtools.ts",
"with": "src/config/store/devtools.prod.ts"
}
]
} }
} }
}, },
@@ -280,10 +229,6 @@
"production": { "production": {
"buildTarget": "dspace-angular:build:production", "buildTarget": "dspace-angular:build:production",
"serverTarget": "dspace-angular:server:production" "serverTarget": "dspace-angular:server:production"
},
"production-e2e": {
"buildTarget": "dspace-angular:build:production-e2e",
"serverTarget": "dspace-angular:server:production-e2e"
} }
} }
}, },
@@ -297,8 +242,7 @@
] ]
}, },
"configurations": { "configurations": {
"production": {}, "production": {}
"production-e2e": {}
} }
}, },
"cypress-run": { "cypress-run": {
@@ -309,9 +253,6 @@
"configurations": { "configurations": {
"production": { "production": {
"devServerTarget": "dspace-angular:serve:production" "devServerTarget": "dspace-angular:serve:production"
},
"production-e2e": {
"devServerTarget": "dspace-angular:serve:production-e2e"
} }
} }
}, },

View File

@@ -16,9 +16,7 @@
"build": "ng build --configuration development", "build": "ng build --configuration development",
"build:stats": "ng build --stats-json", "build:stats": "ng build --stats-json",
"build:prod": "cross-env NODE_ENV=production npm run build:ssr", "build:prod": "cross-env NODE_ENV=production npm run build:ssr",
"build:prod-e2e": "cross-env NODE_ENV=production npm run build:ssr-e2e",
"build:ssr": "ng build --configuration production && ng run dspace-angular:server:production", "build:ssr": "ng build --configuration production && ng run dspace-angular:server:production",
"build:ssr-e2e": "ng build --configuration production-e2e && ng run dspace-angular:server:production-e2e",
"build:lint": "rimraf 'lint/dist/**/*.js' 'lint/dist/**/*.js.map' && tsc -b lint/tsconfig.json", "build:lint": "rimraf 'lint/dist/**/*.js' 'lint/dist/**/*.js.map' && tsc -b lint/tsconfig.json",
"test": "ng test --source-map=true --watch=false --configuration test", "test": "ng test --source-map=true --watch=false --configuration test",
"test:watch": "nodemon --exec \"ng test --source-map=true --watch=true --configuration test\"", "test:watch": "nodemon --exec \"ng test --source-map=true --watch=true --configuration test\"",

View File

@@ -16,7 +16,10 @@ import {
appReducers, appReducers,
storeModuleConfig, storeModuleConfig,
} from '../../app.reducer'; } from '../../app.reducer';
import { CorrelationIdService } from '../../correlation-id/correlation-id.service'; import {
CORRELATION_ID_COOKIE,
CorrelationIdService,
} from '../../correlation-id/correlation-id.service';
import { OrejimeService } from '../../shared/cookies/orejime.service'; import { OrejimeService } from '../../shared/cookies/orejime.service';
import { CORRELATION_ID_OREJIME_KEY } from '../../shared/cookies/orejime-configuration'; import { CORRELATION_ID_OREJIME_KEY } from '../../shared/cookies/orejime-configuration';
import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock'; import { CookieServiceMock } from '../../shared/mocks/cookie.service.mock';
@@ -72,8 +75,8 @@ describe('LogInterceptor', () => {
cookieService = TestBed.inject(CookieService); cookieService = TestBed.inject(CookieService);
correlationIdService = TestBed.inject(CorrelationIdService); correlationIdService = TestBed.inject(CorrelationIdService);
cookieService.set('CORRELATION-ID','123455'); cookieService.set(CORRELATION_ID_COOKIE,'123455');
correlationIdService.initCorrelationId(); correlationIdService.setCorrelationId();
}); });

View File

@@ -4,6 +4,7 @@ import {
StoreModule, StoreModule,
} from '@ngrx/store'; } from '@ngrx/store';
import { MockStore } from '@ngrx/store/testing'; import { MockStore } from '@ngrx/store/testing';
import { of } from 'rxjs';
import { import {
appReducers, appReducers,
@@ -13,7 +14,10 @@ import {
import { UUIDService } from '../core/shared/uuid.service'; import { UUIDService } from '../core/shared/uuid.service';
import { CookieServiceMock } from '../shared/mocks/cookie.service.mock'; import { CookieServiceMock } from '../shared/mocks/cookie.service.mock';
import { SetCorrelationIdAction } from './correlation-id.actions'; import { SetCorrelationIdAction } from './correlation-id.actions';
import { CorrelationIdService } from './correlation-id.service'; import {
CORRELATION_ID_COOKIE,
CorrelationIdService,
} from './correlation-id.service';
describe('CorrelationIdService', () => { describe('CorrelationIdService', () => {
let service: CorrelationIdService; let service: CorrelationIdService;
@@ -34,7 +38,13 @@ describe('CorrelationIdService', () => {
cookieService = new CookieServiceMock(); cookieService = new CookieServiceMock();
uuidService = new UUIDService(); uuidService = new UUIDService();
store = TestBed.inject(Store) as MockStore<AppState>; store = TestBed.inject(Store) as MockStore<AppState>;
service = new CorrelationIdService(cookieService, uuidService, store); const mockOrejimeService = {
getSavedPreferences: () => of({ CORRELATION_ID_OREJIME_KEY: true }),
initialize: jasmine.createSpy('initialize'),
showSettings: jasmine.createSpy('showSettings'),
};
service = new CorrelationIdService(cookieService, uuidService, store, mockOrejimeService, { nativeWindow: undefined });
}); });
describe('getCorrelationId', () => { describe('getCorrelationId', () => {
@@ -46,45 +56,45 @@ describe('CorrelationIdService', () => {
}); });
describe('initCorrelationId', () => { describe('setCorrelationId', () => {
const cookieCID = 'cookie CID'; const cookieCID = 'cookie CID';
const storeCID = 'store CID'; const storeCID = 'store CID';
it('should set cookie and store values to a newly generated value if neither ex', () => { it('should set cookie and store values to a newly generated value if neither ex', () => {
service.initCorrelationId(); service.setCorrelationId();
expect(cookieService.get('CORRELATION-ID')).toBeTruthy(); expect(cookieService.get(CORRELATION_ID_COOKIE)).toBeTruthy();
expect(service.getCorrelationId()).toBeTruthy(); expect(service.getCorrelationId()).toBeTruthy();
expect(cookieService.get('CORRELATION-ID')).toEqual(service.getCorrelationId()); expect(cookieService.get(CORRELATION_ID_COOKIE)).toEqual(service.getCorrelationId());
}); });
it('should set store value to cookie value if present', () => { it('should set store value to cookie value if present', () => {
expect(service.getCorrelationId()).toBe(null); expect(service.getCorrelationId()).toBe(null);
cookieService.set('CORRELATION-ID', cookieCID); cookieService.set(CORRELATION_ID_COOKIE, cookieCID);
service.initCorrelationId(); service.setCorrelationId();
expect(cookieService.get('CORRELATION-ID')).toBe(cookieCID); expect(cookieService.get(CORRELATION_ID_COOKIE)).toBe(cookieCID);
expect(service.getCorrelationId()).toBe(cookieCID); expect(service.getCorrelationId()).toBe(cookieCID);
}); });
it('should set cookie value to store value if present', () => { it('should set cookie value to store value if present', () => {
store.dispatch(new SetCorrelationIdAction(storeCID)); store.dispatch(new SetCorrelationIdAction(storeCID));
service.initCorrelationId(); service.setCorrelationId();
expect(cookieService.get('CORRELATION-ID')).toBe(storeCID); expect(cookieService.get(CORRELATION_ID_COOKIE)).toBe(storeCID);
expect(service.getCorrelationId()).toBe(storeCID); expect(service.getCorrelationId()).toBe(storeCID);
}); });
it('should set store value to cookie value if both are present', () => { it('should set store value to cookie value if both are present', () => {
cookieService.set('CORRELATION-ID', cookieCID); cookieService.set(CORRELATION_ID_COOKIE, cookieCID);
store.dispatch(new SetCorrelationIdAction(storeCID)); store.dispatch(new SetCorrelationIdAction(storeCID));
service.initCorrelationId(); service.setCorrelationId();
expect(cookieService.get('CORRELATION-ID')).toBe(cookieCID); expect(cookieService.get(CORRELATION_ID_COOKIE)).toBe(cookieCID);
expect(service.getCorrelationId()).toBe(cookieCID); expect(service.getCorrelationId()).toBe(cookieCID);
}); });
}); });

View File

@@ -1,4 +1,7 @@
import { Injectable } from '@angular/core'; import {
Inject,
Injectable,
} from '@angular/core';
import { import {
select, select,
Store, Store,
@@ -7,12 +10,18 @@ import { take } from 'rxjs/operators';
import { AppState } from '../app.reducer'; import { AppState } from '../app.reducer';
import { CookieService } from '../core/services/cookie.service'; import { CookieService } from '../core/services/cookie.service';
import {
NativeWindowRef,
NativeWindowService,
} from '../core/services/window.service';
import { UUIDService } from '../core/shared/uuid.service'; import { UUIDService } from '../core/shared/uuid.service';
import { OrejimeService } from '../shared/cookies/orejime.service';
import { CORRELATION_ID_OREJIME_KEY } from '../shared/cookies/orejime-configuration';
import { isEmpty } from '../shared/empty.util'; import { isEmpty } from '../shared/empty.util';
import { SetCorrelationIdAction } from './correlation-id.actions'; import { SetCorrelationIdAction } from './correlation-id.actions';
import { correlationIdSelector } from './correlation-id.selector'; import { correlationIdSelector } from './correlation-id.selector';
export const CORRELATION_ID_COOKIE = 'dsCorrelationId'; export const CORRELATION_ID_COOKIE = 'CORRELATION-ID';
/** /**
* Service to manage the correlation id, an id used to give context to server side logs * Service to manage the correlation id, an id used to give context to server side logs
@@ -26,15 +35,32 @@ export class CorrelationIdService {
protected cookieService: CookieService, protected cookieService: CookieService,
protected uuidService: UUIDService, protected uuidService: UUIDService,
protected store: Store<AppState>, protected store: Store<AppState>,
protected orejimeService: OrejimeService,
@Inject(NativeWindowService) protected _window: NativeWindowRef,
) { ) {
if (this._window?.nativeWindow) {
this._window.nativeWindow.initCorrelationId = () => this.initCorrelationId();
}
}
/**
* Check if the correlation id is allowed to be set, then set it
*/
initCorrelationId(): void {
this.orejimeService?.getSavedPreferences().subscribe(preferences => {
if (preferences[CORRELATION_ID_OREJIME_KEY]) {
this.setCorrelationId();
}
},
);
} }
/** /**
* Initialize the correlation id based on the cookie or the ngrx store * Initialize the correlation id based on the cookie or the ngrx store
*/ */
initCorrelationId(): void { setCorrelationId(): void {
// first see of there's a cookie with a correlation-id // first see of there's a cookie with a correlation-id
let correlationId = this.cookieService.get('CORRELATION-ID'); let correlationId = this.cookieService.get(CORRELATION_ID_COOKIE);
// if there isn't see if there's an ID in the store // if there isn't see if there's an ID in the store
if (isEmpty(correlationId)) { if (isEmpty(correlationId)) {
@@ -48,7 +74,7 @@ export class CorrelationIdService {
// Store the correct id both in the store and as a cookie to ensure they're in sync // Store the correct id both in the store and as a cookie to ensure they're in sync
this.store.dispatch(new SetCorrelationIdAction(correlationId)); this.store.dispatch(new SetCorrelationIdAction(correlationId));
this.cookieService.set('CORRELATION-ID', correlationId); this.cookieService.set(CORRELATION_ID_COOKIE, correlationId);
} }
/** /**

View File

@@ -191,7 +191,7 @@ export class BrowserOrejimeService extends OrejimeService {
*/ */
this.translateConfiguration(); this.translateConfiguration();
if (environment.isE2E) { if (!environment.info?.enableCookieConsentPopup) {
this.orejimeConfig.apps = []; this.orejimeConfig.apps = [];
} else { } else {
this.orejimeConfig.apps = this.filterConfigApps(appsToHide); this.orejimeConfig.apps = this.filterConfigApps(appsToHide);

View File

@@ -151,6 +151,9 @@ export function getOrejimeConfiguration(_window: NativeWindowRef): any {
cookies: [ cookies: [
CORRELATION_ID_COOKIE, CORRELATION_ID_COOKIE,
], ],
callback: () => {
_window?.nativeWindow.initCorrelationId();
},
}, },
{ {
name: MATOMO_OREJIME_KEY, name: MATOMO_OREJIME_KEY,

View File

@@ -3,5 +3,4 @@ import { SSRConfig } from './ssr-config.interface';
export interface BuildConfig extends AppConfig { export interface BuildConfig extends AppConfig {
ssr: SSRConfig; ssr: SSRConfig;
isE2E?: boolean;
} }

View File

@@ -1,7 +1,8 @@
import { Config } from './config.interface'; import { Config } from './config.interface';
export interface InfoConfig extends Config { export interface InfoConfig extends Config {
enableEndUserAgreement: boolean; enableEndUserAgreement?: boolean;
enablePrivacyStatement: boolean; enablePrivacyStatement?: boolean;
enableCOARNotifySupport: boolean; enableCOARNotifySupport?: boolean;
enableCookieConsentPopup?: boolean;
} }

View File

@@ -1,6 +1,5 @@
environment.*.ts environment.*.ts
!environment.production.ts !environment.production.ts
!environment.production-e2e.ts
!environment.test.ts !environment.test.ts
!environment.ts !environment.ts

View File

@@ -1,10 +0,0 @@
import { BuildConfig } from '../config/build-config.interface';
import { environment as prodEnvironment } from './environment.production';
export const environment: Partial<BuildConfig> = Object.assign(
{},
prodEnvironment,
{
isE2E: true,
},
);

View File

@@ -14,4 +14,7 @@ export const environment: Partial<BuildConfig> = {
enableSearchComponent: false, enableSearchComponent: false,
enableBrowseComponent: false, enableBrowseComponent: false,
}, },
info: {
enableCookieConsentPopup: true,
},
}; };

View File

@@ -324,6 +324,7 @@ export const environment: BuildConfig = {
enableEndUserAgreement: true, enableEndUserAgreement: true,
enablePrivacyStatement: true, enablePrivacyStatement: true,
enableCOARNotifySupport: true, enableCOARNotifySupport: true,
enableCookieConsentPopup: true,
}, },
markdown: { markdown: {
enabled: false, enabled: false,

View File

@@ -19,6 +19,9 @@ export const environment: Partial<BuildConfig> = {
enableSearchComponent: false, enableSearchComponent: false,
enableBrowseComponent: false, enableBrowseComponent: false,
}, },
info: {
enableCookieConsentPopup: true,
},
}; };
/* /*