Skip to content

Commit

Permalink
control id of main area's initial part in e2e tests (instead of activ…
Browse files Browse the repository at this point in the history
…ePartId)
  • Loading branch information
danielwiehl committed Dec 18, 2024
1 parent 198ac0a commit b51bfaf
Show file tree
Hide file tree
Showing 16 changed files with 135 additions and 71 deletions.
2 changes: 2 additions & 0 deletions apps/workbench-testing-app/src/app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {Perspectives} from './workbench.perspectives';
import {environment} from '../environments/environment';
import {provideAnimations, provideNoopAnimations} from '@angular/platform-browser/animations';
import {provideWorkbench} from '@scion/workbench';
import {provideMainAreaInitialPartId} from './workbench/main-area-initial-part-id.provider';

/**
* Central place to configure the workbench-testing-app.
Expand All @@ -31,6 +32,7 @@ export const appConfig: ApplicationConfig = {
provideWorkbench(workbenchConfig),
provideConfirmWorkbenchStartupInitializer(),
provideThrottleCapabilityLookupInterceptor(),
provideMainAreaInitialPartId(),
provideWorkbenchLifecycleHookLoggers(),
provideDevToolsInterceptor(),
provideNotificationPage(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2018-2024 Swiss Federal Railways
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/

import {EnvironmentProviders, makeEnvironmentProviders} from '@angular/core';
import {MAIN_AREA_INITIAL_PART_ID} from '@scion/workbench';
import {WorkbenchStartupQueryParams} from './workbench-startup-query-params';

/**
* Provides a set of DI providers to control the identity of the initial part in the main area.
*/
export function provideMainAreaInitialPartId(): EnvironmentProviders | [] {
if (WorkbenchStartupQueryParams.mainAreaInitialPartId()) {
return makeEnvironmentProviders([
{provide: MAIN_AREA_INITIAL_PART_ID, useValue: WorkbenchStartupQueryParams.mainAreaInitialPartId()},
]);
}
return [];
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ class CapabilityLookupMessageInterceptor implements MessageInterceptor {
* Returns an empty provider array if the query parameter {@link WorkbenchStartupQueryParams#SIMULATE_SLOW_CAPABILITY_LOOKUP} is not set.
*/
export function provideThrottleCapabilityLookupInterceptor(): EnvironmentProviders | [] {
if (WorkbenchStartupQueryParams.standalone()) {
return [];
}
if (WorkbenchStartupQueryParams.simulateSlowCapabilityLookup()) {
return makeEnvironmentProviders([
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ export const WorkbenchStartupQueryParams = {
*/
DIALOG_MODALITY_SCOPE: 'dialogModalityScope',

/**
* Query param to control the identity of the initial part in the main area.
*
* The initial part is automatically created by the workbench if the main area has no part, but it has no
* special meaning to the workbench and can be removed by the user. If not set, a UUID is assigned.
*/
MAIN_AREA_INITIAL_PART_ID: 'mainAreaInitialPartId',

/**
* Reads the query param to set the workbench launching strategy.
*/
Expand Down Expand Up @@ -89,4 +97,11 @@ export const WorkbenchStartupQueryParams = {
simulateSlowCapabilityLookup: (): boolean => {
return coerceBooleanProperty(new URL(window.location.href).searchParams.get(WorkbenchStartupQueryParams.SIMULATE_SLOW_CAPABILITY_LOOKUP));
},

/**
* Reads the query param to control the identity of the initial part in the main area.
*/
mainAreaInitialPartId: (): string | undefined => {
return new URL(window.location.href).searchParams.get(WorkbenchStartupQueryParams.MAIN_AREA_INITIAL_PART_ID) ?? undefined;
},
} as const;
40 changes: 32 additions & 8 deletions projects/scion/e2e-testing/src/app.po.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,31 @@ export class AppPO {
}

this._workbenchStartupQueryParams = new URLSearchParams();
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.LAUNCHER, options?.launcher ?? 'LAZY');
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.STANDALONE, `${(options?.microfrontendSupport ?? true) === false}`);
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.CONFIRM_STARTUP, `${options?.confirmStartup ?? false}`);
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.SIMULATE_SLOW_CAPABILITY_LOOKUP, `${options?.simulateSlowCapabilityLookup ?? false}`);
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.PERSPECTIVES, `${(options?.perspectives ?? []).join(';')}`);
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.DIALOG_MODALITY_SCOPE, options?.dialogModalityScope ?? 'workbench');
if (options?.launcher) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.LAUNCHER, options.launcher);
}
if (!(options?.microfrontendSupport ?? true)) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.STANDALONE, `${true}`);
}
if (options?.confirmStartup) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.CONFIRM_STARTUP, `${true}`);
}
if (options?.simulateSlowCapabilityLookup) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.SIMULATE_SLOW_CAPABILITY_LOOKUP, `${true}`);
}
if (options?.perspectives?.length) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.PERSPECTIVES, `${options.perspectives.join(';')}`);
}
if (options?.dialogModalityScope) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.DIALOG_MODALITY_SCOPE, options?.dialogModalityScope);
}
if (options?.mainAreaInitialPartId) {
this._workbenchStartupQueryParams.append(WorkenchStartupQueryParams.MAIN_AREA_INITIAL_PART_ID, options.mainAreaInitialPartId);
}

const featureQueryParams = new URLSearchParams();
if (options?.stickyStartViewTab !== undefined) {
featureQueryParams.append('stickyStartViewTab', `${options.stickyStartViewTab}`);
if (options?.stickyStartViewTab) {
featureQueryParams.append('stickyStartViewTab', `${true}`);
}

// Perform navigation.
Expand Down Expand Up @@ -433,6 +448,10 @@ export interface Options {
* Controls the scope of application-modal workbench dialogs. By default, if not specified, workbench scope will be used.
*/
dialogModalityScope?: 'workbench' | 'viewport';
/**
* Controls the identity of the initial part in the main area. If not set, a UUID is assigned.
*/
mainAreaInitialPartId?: string;
/**
* Specifies data to be in local storage.
*/
Expand Down Expand Up @@ -472,4 +491,9 @@ export enum WorkenchStartupQueryParams {
* Query param to set the scope for application-modal dialogs.
*/
DIALOG_MODALITY_SCOPE = 'dialogModalityScope',

/**
* Query param to control the identity of the initial part in the main area.
*/
MAIN_AREA_INITIAL_PART_ID = 'mainAreaInitialPartId',
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ export class LayoutPagePO implements WorkbenchViewPagePO {
*
* @see WorkbenchRouter.navigate
*/
public async modifyLayout(fn: (layout: WorkbenchLayout, activePartId: string) => WorkbenchLayout): Promise<void> {
public async modifyLayout(fn: (layout: WorkbenchLayout) => WorkbenchLayout): Promise<void> {
await this.view.tab.click();
await this._tabbar.selectTab('e2e-modify-layout');

const modifyLayoutPage = new ModifyLayoutPagePO(this.view, this.locator.locator('app-modify-layout-page'));
const modifyLayoutPage = new ModifyLayoutPagePO(this.locator.locator('app-modify-layout-page'));
return modifyLayoutPage.modify(fn);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,18 @@ import {Locator} from '@playwright/test';
import {WorkbenchLayout} from '@scion/workbench';
import {LayoutPages} from './layout-pages.po';
import {AppPO} from '../../../app.po';
import {ViewPO} from '../../../view.po';
import {ɵWorkbenchLayout} from './layout.model';

/**
* Page object to interact with {@link ModifyLayoutPageComponent}.
*/
export class ModifyLayoutPagePO {

constructor(public view: ViewPO, public locator: Locator) {
constructor(public locator: Locator) {
}

public async modify(fn: (layout: WorkbenchLayout, activePartId: string) => WorkbenchLayout): Promise<void> {
const activePartId = await this.view.part.getPartId();
const {parts, views, viewNavigations} = fn(new ɵWorkbenchLayout(), activePartId) as ɵWorkbenchLayout;
public async modify(fn: (layout: WorkbenchLayout) => WorkbenchLayout): Promise<void> {
const {parts, views, viewNavigations} = fn(new ɵWorkbenchLayout()) as ɵWorkbenchLayout;

// Enter the layout.
await LayoutPages.enterParts(this.locator.locator('app-add-parts'), parts);
Expand Down
36 changes: 18 additions & 18 deletions projects/scion/e2e-testing/src/workbench/router-link.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from path-based route to path-based route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as path-based route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', ['test-router']),
);

Expand All @@ -272,11 +272,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from path-based route to empty-path route (1/2)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as path-based route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', ['test-router']),
);

Expand All @@ -300,11 +300,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from path-based route to empty-path route (2/2)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as path-based route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', ['test-router']),
);

Expand All @@ -325,11 +325,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from empty-path route to empty-path route (1/2)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as empty-path route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', [], {hint: 'test-router'}),
);

Expand All @@ -350,11 +350,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from empty-path route to empty-path route (2/2)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as empty-path route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', [], {hint: 'test-router'}),
);

Expand All @@ -375,11 +375,11 @@ test.describe('Workbench RouterLink', () => {
});

test('should navigate current view when navigating from empty-path route to path-based route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as empty-path route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', [], {hint: 'test-router'}),
);

Expand Down
24 changes: 12 additions & 12 deletions projects/scion/e2e-testing/src/workbench/router.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1502,11 +1502,11 @@ test.describe('Workbench Router', () => {
});

test('should navigate from path-based route to path-based route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as path-based route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', ['test-router']),
);

Expand All @@ -1529,11 +1529,11 @@ test.describe('Workbench Router', () => {
});

test('should navigate from path-based route to empty-path route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as path-based route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', ['test-router']),
);

Expand All @@ -1557,11 +1557,11 @@ test.describe('Workbench Router', () => {
});

test('should navigate from empty-path route to empty-path route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as empty-path route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', [], {hint: 'test-router'}),
);

Expand All @@ -1585,11 +1585,11 @@ test.describe('Workbench Router', () => {
});

test('should navigate from empty-path route to path-based route', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

// Open router page as empty-path route.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main'})
.navigateView('view.100', [], {hint: 'test-router'}),
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,10 @@ test.describe('Workbench View CSS Class', () => {
});

test('should add CSS classes to inactive view (WorkbenchLayout.navigateView)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addView('view.100', {partId: activePartId, activateView: false})
await workbenchNavigator.modifyLayout(layout => layout
.addView('view.100', {partId: 'main', activateView: false})
.navigateView('view.100', ['test-view'], {cssClass: 'testee'}),
);

Expand Down
8 changes: 4 additions & 4 deletions projects/scion/e2e-testing/src/workbench/view-dnd.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ test.describe('View Drag & Drop', () => {
});

test('should drop view on start page of the main area (grid root is MTreeNode)', async ({appPO, workbenchNavigator}) => {
await appPO.navigateTo({microfrontendSupport: false});
await appPO.navigateTo({microfrontendSupport: false, mainAreaInitialPartId: 'main'});

await workbenchNavigator.createPerspective(factory => factory
.addPart(MAIN_AREA)
Expand All @@ -657,9 +657,9 @@ test.describe('View Drag & Drop', () => {
);

// Change the grid root of the main area to a `MTreeNode`.
await workbenchNavigator.modifyLayout((layout, activePartId) => layout
.addPart('main-left', {relativeTo: activePartId, align: 'left'})
.addPart('main-right', {relativeTo: activePartId, align: 'right'}),
await workbenchNavigator.modifyLayout(layout => layout
.addPart('main-left', {relativeTo: 'main', align: 'left'})
.addPart('main-right', {relativeTo: 'main', align: 'right'}),
);

// Drop view on the start page of the main area.
Expand Down
Loading

0 comments on commit b51bfaf

Please sign in to comment.