Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions modules/ui/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ <h1 class="main-heading">Testrun</h1>
class="settings-drawer">
<app-general-settings
#settings
[settingsDisable]="isTestrunInProgress(vm.systemStatus?.status)"
(closeSettingEvent)="closeSetting(vm.hasDevices)">
</app-general-settings>
</mat-drawer>
Expand Down
5 changes: 2 additions & 3 deletions modules/ui/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ describe('AppComponent', () => {
'setIsOpenStartTestrun',
'fetchDevices',
'getTestModules',
'testrunInProgress',
]);

mockFocusManagerService = jasmine.createSpyObj('mockFocusManagerService', [
Expand Down Expand Up @@ -654,10 +655,8 @@ describe('AppComponent', () => {
template: '<div></div>',
})
class FakeGeneralSettingsComponent {
@Input() interfaces = [];
@Input() hasConnectionSettings = false;
@Input() settingsDisable = false;
@Output() closeSettingEvent = new EventEmitter<void>();
@Output() reloadInterfacesEvent = new EventEmitter<void>();
getSystemInterfaces = () => {};
}

Expand Down
6 changes: 6 additions & 0 deletions modules/ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import { appFeatureKey } from './store/reducers';
import { GeneralSettingsComponent } from './pages/settings/general-settings.component';
import { AppStore } from './app.store';
import { TestRunService } from './services/test-run.service';

const DEVICES_LOGO_URL = '/assets/icons/devices.svg';
const DEVICES_RUN_URL = '/assets/icons/device_run.svg';
Expand Down Expand Up @@ -65,6 +66,7 @@ export class AppComponent {
private store: Store<AppState>,
private state: State<AppState>,
private readonly focusManagerService: FocusManagerService,
private testRunService: TestRunService,
public appStore: AppStore
) {
this.appStore.getDevices();
Expand Down Expand Up @@ -147,4 +149,8 @@ export class AppComponent {
consentShown() {
this.appStore.setContent();
}

isTestrunInProgress(status?: string) {
return this.testRunService.testrunInProgress(status);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h2 class="settings-drawer-header-title">System settings</h2>
</button>
</div>
<div class="setting-drawer-content" *ngIf="viewModel$ | async as vm">
<div *ngIf="settingsDisable" class="settings-disabled-overlay"></div>
<form
[formGroup]="settingForm"
[class.setting-drawer-content-form-empty]="
Expand Down Expand Up @@ -57,14 +58,15 @@ <h2 class="settings-drawer-header-title">System settings</h2>
[options]="vm.internetOptions">
</app-settings-dropdown>
</ng-container>
<p class="message">
<p class="message" [ngClass]="{ disabled: settingsDisable }">
If a port is missing from this list, you can
<a
#reloadSettingLink
(click)="reloadSetting()"
(keydown.enter)="reloadSetting()"
(keydown.space)="reloadSetting()"
role="button"
tabindex="0"
[tabindex]="settingsDisable ? -1 : 0"
class="message-link">
Refresh
</a>
Expand Down Expand Up @@ -105,7 +107,9 @@ <h2 class="settings-drawer-header-title">System settings</h2>
class="save-button"
color="primary"
(click)="saveSetting()"
[disabled]="!isFormValues || vm.isLessThanOneInterface">
[disabled]="
!isFormValues || vm.isLessThanOneInterface || settingsDisable
">
Save
</button>
</div>
Expand Down
22 changes: 22 additions & 0 deletions modules/ui/src/app/pages/settings/general-settings.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,25 @@
}
}
}

.settings-disabled-overlay {
position: absolute;
width: 100%;
left: 0;
right: 0;
top: 75px;
bottom: 45px;
background-color: rgba(255, 255, 255, 0.7);
z-index: 2;
}

.disabled {
.message-link {
cursor: default;
pointer-events: none;

&:focus-visible {
outline: none;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,47 @@ describe('GeneralSettingsComponent', () => {
expect(mockLoaderService.setLoading).toHaveBeenCalledWith(true);
});

describe('#settingsDisable', () => {
it('should disable setting form when get settingDisable as true ', () => {
spyOn(component.settingForm, 'disable');

component.settingsDisable = true;

expect(component.settingForm.disable).toHaveBeenCalled();
});

it('should enable setting form when get settingDisable as false ', () => {
spyOn(component.settingForm, 'enable');

component.settingsDisable = false;

expect(component.settingForm.enable).toHaveBeenCalled();
});

it('should disable "Save" button when get settingDisable as true', () => {
component.settingsDisable = true;

const saveBtn = compiled.querySelector(
'.save-button'
) as HTMLButtonElement;

expect(saveBtn.disabled).toBeTrue();
});

it('should disable "Refresh" link when settingDisable', () => {
component.settingsDisable = true;

const refreshLink = compiled.querySelector(
'.message-link'
) as HTMLAnchorElement;

refreshLink.click();

expect(refreshLink.hasAttribute('aria-disabled')).toBeTrue();
expect(mockLoaderService.setLoading).not.toHaveBeenCalled();
});
});

describe('#closeSetting', () => {
beforeEach(() => {
component.ngOnInit();
Expand Down
26 changes: 26 additions & 0 deletions modules/ui/src/app/pages/settings/general-settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
*/
import {
Component,
ElementRef,
EventEmitter,
Input,
OnDestroy,
OnInit,
Output,
ViewChild,
} from '@angular/core';
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
import { Subject, takeUntil, tap } from 'rxjs';
Expand All @@ -38,7 +41,17 @@ import { LoaderService } from '../../services/loader.service';
providers: [SettingsStore],
})
export class GeneralSettingsComponent implements OnInit, OnDestroy {
@ViewChild('reloadSettingLink') public reloadSettingLink!: ElementRef;
@Output() closeSettingEvent = new EventEmitter<void>();

private isSettingsDisable = false;
get settingsDisable(): boolean {
return this.isSettingsDisable;
}
@Input() set settingsDisable(value: boolean) {
this.isSettingsDisable = value;
value ? this.disableSettings() : this.enableSettings();
}
public readonly CalloutType = CalloutType;
public readonly EventType = EventType;
public readonly FormKey = FormKey;
Expand Down Expand Up @@ -88,6 +101,9 @@ export class GeneralSettingsComponent implements OnInit, OnDestroy {
}

reloadSetting(): void {
if (this.settingsDisable) {
return;
}
this.showLoading();
this.getSystemInterfaces();
this.settingsStore.getSystemConfig();
Expand All @@ -111,6 +127,16 @@ export class GeneralSettingsComponent implements OnInit, OnDestroy {
}
}

private disableSettings(): void {
this.settingForm?.disable();
this.reloadSettingLink?.nativeElement.setAttribute('aria-disabled', 'true');
}

private enableSettings(): void {
this.settingForm?.enable();
this.reloadSettingLink?.nativeElement.removeAttribute('aria-disabled');
}

private createSettingForm() {
this.settingForm = this.fb.group(
{
Expand Down
8 changes: 4 additions & 4 deletions modules/ui/src/app/pages/testrun/progress.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<ng-container *ngIf="vm.systemStatus as data; else empty">
<ng-container
*ngIf="
testrunInProgress(data.status) ||
isTestrunInProgress(data.status) ||
data.status === StatusOfTestrun.Cancelled ||
data.status === StatusOfTestrun.Cancelling ||
data.finished
Expand All @@ -41,7 +41,7 @@ <h2 class="title progress-title">
}}
</h2>
<button
*ngIf="testrunInProgress(data.status)"
*ngIf="isTestrunInProgress(data.status)"
(click)="openStopTestrunDialog(vm.systemStatus)"
class="stop-button"
aria-label="Stop testrun"
Expand All @@ -66,7 +66,7 @@ <h2 class="title progress-title">
<section
class="progress-table"
[class.progress-table-progress-empty]="
testrunInProgress(data.status) && resultIsEmpty(data.tests)
isTestrunInProgress(data.status) && resultIsEmpty(data.tests)
">
<app-progress-table
[dataSource]="vm.dataSource"
Expand Down Expand Up @@ -100,7 +100,7 @@ <h2 class="title progress-title">
aria-label="Start new testrun"
color="primary"
[disabled]="
hasDevices === false || testrunInProgress(systemStatus?.status)
hasDevices === false || isTestrunInProgress(systemStatus?.status)
"
(click)="openTestRunModal()"
mat-flat-button>
Expand Down
5 changes: 5 additions & 0 deletions modules/ui/src/app/pages/testrun/progress.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ describe('ProgressComponent', () => {
'isTestrunStarted$',
'fetchSystemStatus',
'getTestModules',
'testrunInProgress',
]);

const loaderServiceMock: jasmine.SpyObj<LoaderService> = jasmine.createSpyObj(
Expand Down Expand Up @@ -209,6 +210,7 @@ describe('ProgressComponent', () => {
describe('DOM tests', () => {
beforeEach(async () => {
testRunServiceMock.stopTestrun.and.returnValue(of(true));
testRunServiceMock.testrunInProgress.and.returnValue(false);

await TestBed.configureTestingModule({
declarations: [
Expand Down Expand Up @@ -334,6 +336,7 @@ describe('ProgressComponent', () => {
selectSystemStatus,
MOCK_PROGRESS_DATA_IN_PROGRESS
);
testRunServiceMock.testrunInProgress.and.returnValue(true);
store.overrideSelector(selectHasDevices, true);
fixture.detectChanges();
});
Expand Down Expand Up @@ -459,6 +462,7 @@ describe('ProgressComponent', () => {
selectSystemStatus,
MOCK_PROGRESS_DATA_WAITING_FOR_DEVICE
);
testRunServiceMock.testrunInProgress.and.returnValue(true);
store.overrideSelector(selectHasDevices, true);
fixture.detectChanges();
});
Expand All @@ -484,6 +488,7 @@ describe('ProgressComponent', () => {
selectSystemStatus,
MOCK_PROGRESS_DATA_MONITORING
);
testRunServiceMock.testrunInProgress.and.returnValue(true);
store.overrideSelector(selectHasDevices, true);
fixture.detectChanges();
});
Expand Down
10 changes: 4 additions & 6 deletions modules/ui/src/app/pages/testrun/progress.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { LOADER_TIMEOUT_CONFIG_TOKEN } from '../../services/loaderConfig';
import { FocusManagerService } from '../../services/focus-manager.service';
import { combineLatest } from 'rxjs/internal/observable/combineLatest';
import { TestrunStore } from './testrun.store';
import { TestRunService } from '../../services/test-run.service';

@Component({
selector: 'app-progress',
Expand All @@ -51,6 +52,7 @@ export class ProgressComponent implements OnInit, OnDestroy {
viewModel$ = this.testrunStore.viewModel$;

constructor(
private readonly testRunService: TestRunService,
public dialog: MatDialog,
private readonly focusManagerService: FocusManagerService,
public testrunStore: TestrunStore
Expand All @@ -70,12 +72,8 @@ export class ProgressComponent implements OnInit, OnDestroy {
});
}

testrunInProgress(status?: string): boolean {
return (
status === StatusOfTestrun.InProgress ||
status === StatusOfTestrun.WaitingForDevice ||
status === StatusOfTestrun.Monitoring
);
isTestrunInProgress(status?: string) {
return this.testRunService.testrunInProgress(status);
}

public openStopTestrunDialog(systemStatus: TestrunStatus) {
Expand Down
37 changes: 36 additions & 1 deletion modules/ui/src/app/services/test-run.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import { Device, TestModule } from '../model/device';
import { TestRunService, UNAVAILABLE_VERSION } from './test-run.service';
import { SystemConfig, SystemInterfaces } from '../model/setting';
import { MOCK_PROGRESS_DATA_IN_PROGRESS } from '../mocks/progress.mock';
import { StatusOfTestResult, TestrunStatus } from '../model/testrun-status';
import {
StatusOfTestResult,
StatusOfTestrun,
TestrunStatus,
} from '../model/testrun-status';
import { device } from '../mocks/device.mock';
import { NEW_VERSION, VERSION } from '../mocks/version.mock';

Expand Down Expand Up @@ -297,6 +301,37 @@ describe('TestRunService', () => {
});
});

describe('#testrunInProgress', () => {
const resultsInProgress = [
StatusOfTestrun.InProgress,
StatusOfTestrun.WaitingForDevice,
StatusOfTestrun.Monitoring,
];

const resultsNotInProgress = [
StatusOfTestrun.Idle,
StatusOfTestrun.Cancelled,
StatusOfTestrun.Compliant,
StatusOfTestrun.NonCompliant,
];

resultsInProgress.forEach(testCase => {
it(`should return true if testrun result is "${testCase}"`, () => {
const result = service.testrunInProgress(testCase);

expect(result).toBeTrue();
});
});

resultsNotInProgress.forEach(testCase => {
it(`should return false if testrun result is "${testCase}"`, () => {
const result = service.testrunInProgress(testCase);

expect(result).toBeFalse();
});
});
});

it('deleteDevice should have necessary request data', () => {
const apiUrl = 'http://localhost:8000/device';

Expand Down
Loading