mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
90978: Fix e2e tests failing due to interactions before page fully loaded
Now that we use initialNavigation: 'enabledBlocking', pages can appear to be loaded before some functionality is fully active. In some cases this trips up Cypress, and it tries to interact with the app too soon. We address this by introducing a new dsBrowserOnly pipe in order to defer the data-test attributes Cypress relies on to CSR.
This commit is contained in:
@@ -65,7 +65,7 @@ describe('My DSpace page', () => {
|
||||
cy.visit('/mydspace');
|
||||
|
||||
// Open the New Submission dropdown
|
||||
cy.get('#dropdownSubmission').click();
|
||||
cy.get('button[data-test="submission-dropdown"]').click();
|
||||
// Click on the "Item" type in that dropdown
|
||||
cy.get('#entityControlsDropdownMenu button[title="none"]').click();
|
||||
|
||||
@@ -98,7 +98,7 @@ describe('My DSpace page', () => {
|
||||
const id = subpaths[2];
|
||||
|
||||
// Click the "Save for Later" button to save this submission
|
||||
cy.get('button#saveForLater').click();
|
||||
cy.get('ds-submission-form-footer [data-test="save-for-later"]').click();
|
||||
|
||||
// "Save for Later" should send us to MyDSpace
|
||||
cy.url().should('include', '/mydspace');
|
||||
@@ -122,7 +122,7 @@ describe('My DSpace page', () => {
|
||||
cy.url().should('include', '/workspaceitems/' + id + '/edit');
|
||||
|
||||
// Discard our new submission by clicking Discard in Submission form & confirming
|
||||
cy.get('button#discard').click();
|
||||
cy.get('ds-submission-form-footer [data-test="discard"]').click();
|
||||
cy.get('button#discard_submit').click();
|
||||
|
||||
// Discarding should send us back to MyDSpace
|
||||
@@ -135,7 +135,7 @@ describe('My DSpace page', () => {
|
||||
cy.visit('/mydspace');
|
||||
|
||||
// Open the New Import dropdown
|
||||
cy.get('#dropdownImport').click();
|
||||
cy.get('button[data-test="import-dropdown"]').click();
|
||||
// Click on the "Item" type in that dropdown
|
||||
cy.get('#importControlsDropdownMenu button[title="none"]').click();
|
||||
|
||||
|
@@ -24,7 +24,7 @@ describe('Search Page', () => {
|
||||
|
||||
// Click each filter toggle to open *every* filter
|
||||
// (As we want to scan filter section for accessibility issues as well)
|
||||
cy.get('.filter-toggle').click({ multiple: true });
|
||||
cy.get('[data-test="filter-toggle"]').click({ multiple: true });
|
||||
|
||||
// Analyze <ds-search-page> for accessibility issues
|
||||
testA11y(
|
||||
|
@@ -27,7 +27,7 @@
|
||||
<a *ngIf="bitstreamDownloadUrl != null" [href]="bitstreamDownloadUrl"
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
title="{{'item.edit.bitstreams.edit.buttons.download' | translate}}"
|
||||
data-test="download-button">
|
||||
[attr.data-test]="'download-button' | dsBrowserOnly">
|
||||
<i class="fas fa-download fa-fw"></i>
|
||||
</a>
|
||||
<button [routerLink]="['/bitstreams/', bitstream.id, 'edit']" class="btn btn-outline-primary btn-sm"
|
||||
|
@@ -12,6 +12,7 @@ import { ResponsiveColumnSizes } from '../../../../shared/responsive-table-sizes
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../../shared/remote-data.utils';
|
||||
import { getBitstreamDownloadRoute } from '../../../../app-routing-paths';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { BrowserOnlyMockPipe } from '../../../../shared/testing/browser-only-mock.pipe';
|
||||
|
||||
let comp: ItemEditBitstreamComponent;
|
||||
let fixture: ComponentFixture<ItemEditBitstreamComponent>;
|
||||
@@ -72,7 +73,11 @@ describe('ItemEditBitstreamComponent', () => {
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot()],
|
||||
declarations: [ItemEditBitstreamComponent, VarDirective],
|
||||
declarations: [
|
||||
ItemEditBitstreamComponent,
|
||||
VarDirective,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: ObjectUpdatesService, useValue: objectUpdatesService }
|
||||
], schemas: [
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<button class="btn btn-lg btn-outline-primary mt-1 ml-2" id="dropdownImport" ngbDropdownToggle
|
||||
type="button" [disabled]="!(initialized$|async)"
|
||||
attr.aria-label="{{'mydspace.new-submission-external' | translate}}"
|
||||
[attr.data-test]="'import-dropdown' | dsBrowserOnly"
|
||||
title="{{'mydspace.new-submission-external' | translate}}">
|
||||
<i class="fa fa-file-import" aria-hidden="true"></i>
|
||||
<span class="caret"></span>
|
||||
|
@@ -13,6 +13,7 @@ import { ResourceType } from '../../../core/shared/resource-type';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { RouterStub } from '../../../shared/testing/router.stub';
|
||||
import { BrowserOnlyMockPipe } from '../../../shared/testing/browser-only-mock.pipe';
|
||||
|
||||
export function getMockEntityTypeService(): EntityTypeService {
|
||||
const pageInfo = { elementsPerPage: 20, totalElements: 4, totalPages: 1, currentPage: 0 } as PageInfo;
|
||||
@@ -83,7 +84,8 @@ describe('MyDSpaceNewExternalDropdownComponent test', () => {
|
||||
],
|
||||
declarations: [
|
||||
MyDSpaceNewExternalDropdownComponent,
|
||||
TestComponent
|
||||
TestComponent,
|
||||
BrowserOnlyMockPipe
|
||||
],
|
||||
providers: [
|
||||
{ provide: EntityTypeService, useValue: getMockEmptyEntityTypeService() },
|
||||
@@ -134,7 +136,8 @@ describe('MyDSpaceNewExternalDropdownComponent test', () => {
|
||||
],
|
||||
declarations: [
|
||||
MyDSpaceNewExternalDropdownComponent,
|
||||
TestComponent
|
||||
TestComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: EntityTypeService, useValue: getMockEntityTypeService() },
|
||||
|
@@ -9,6 +9,7 @@
|
||||
<button class="btn btn-lg btn-primary mt-1 ml-2" id="dropdownSubmission" ngbDropdownToggle
|
||||
type="button" [disabled]="!(initialized$|async)"
|
||||
attr.aria-label="{{'mydspace.new-submission' | translate}}"
|
||||
[attr.data-test]="'submission-dropdown' | dsBrowserOnly"
|
||||
title="{{'mydspace.new-submission' | translate}}">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i>
|
||||
<span class="caret"></span>
|
||||
|
@@ -12,6 +12,7 @@ import { ItemType } from '../../../core/shared/item-relationships/item-type.mode
|
||||
import { ResourceType } from '../../../core/shared/resource-type';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { PageInfo } from '../../../core/shared/page-info.model';
|
||||
import { BrowserOnlyMockPipe } from '../../../shared/testing/browser-only-mock.pipe';
|
||||
|
||||
export function getMockEntityTypeService(): EntityTypeService {
|
||||
const type1: ItemType = {
|
||||
@@ -87,7 +88,8 @@ describe('MyDSpaceNewSubmissionDropdownComponent test', () => {
|
||||
],
|
||||
declarations: [
|
||||
MyDSpaceNewSubmissionDropdownComponent,
|
||||
TestComponent
|
||||
TestComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: EntityTypeService, useValue: getMockEmptyEntityTypeService() },
|
||||
@@ -138,7 +140,8 @@ describe('MyDSpaceNewSubmissionDropdownComponent test', () => {
|
||||
],
|
||||
declarations: [
|
||||
MyDSpaceNewSubmissionDropdownComponent,
|
||||
TestComponent
|
||||
TestComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: EntityTypeService, useValue: getMockEntityTypeService() },
|
||||
|
@@ -3,8 +3,8 @@
|
||||
<form [formGroup]="searchForm" (ngSubmit)="onSubmit(searchForm.value)" autocomplete="on">
|
||||
<input #searchInput [@toggleAnimation]="isExpanded" [attr.aria-label]="('nav.search' | translate)" name="query"
|
||||
formControlName="query" type="text" placeholder="{{searchExpanded ? ('nav.search' | translate) : ''}}"
|
||||
class="d-inline-block bg-transparent position-absolute form-control dropdown-menu-right p-1" data-test="header-search-box">
|
||||
<a class="submit-icon" [routerLink]="" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()" data-test="header-search-icon">
|
||||
class="d-inline-block bg-transparent position-absolute form-control dropdown-menu-right p-1" [attr.data-test]="'header-search-box' | dsBrowserOnly">
|
||||
<a class="submit-icon" [routerLink]="" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()" [attr.data-test]="'header-search-icon' | dsBrowserOnly">
|
||||
<em class="fas fa-search fa-lg fa-fw"></em>
|
||||
</a>
|
||||
</form>
|
||||
|
@@ -10,6 +10,7 @@ import { TranslateLoaderMock } from '../shared/mocks/translate-loader.mock';
|
||||
import { SearchNavbarComponent } from './search-navbar.component';
|
||||
import { PaginationServiceStub } from '../shared/testing/pagination-service.stub';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { BrowserOnlyMockPipe } from '../shared/testing/browser-only-mock.pipe';
|
||||
|
||||
describe('SearchNavbarComponent', () => {
|
||||
let component: SearchNavbarComponent;
|
||||
@@ -44,7 +45,10 @@ describe('SearchNavbarComponent', () => {
|
||||
useClass: TranslateLoaderMock
|
||||
}
|
||||
})],
|
||||
declarations: [SearchNavbarComponent],
|
||||
declarations: [
|
||||
SearchNavbarComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: mockSearchService }
|
||||
]
|
||||
|
@@ -1,8 +1,8 @@
|
||||
<ul class="navbar-nav" [ngClass]="{'mr-auto': (isXsOrSm$ | async)}">
|
||||
<li *ngIf="!(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item"
|
||||
(click)="$event.stopPropagation();">
|
||||
<div ngbDropdown #loginDrop display="dynamic" placement="bottom-right" class="d-inline-block" data-test="login-menu" @fadeInOut>
|
||||
<a href="javascript:void(0);" class="dropdownLogin px-1 " [attr.aria-label]="'nav.login' |translate" (click)="$event.preventDefault()" ngbDropdownToggle>
|
||||
<div ngbDropdown #loginDrop display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
|
||||
<a href="javascript:void(0);" class="dropdownLogin px-1 " [attr.aria-label]="'nav.login' |translate" (click)="$event.preventDefault()" [attr.data-test]="'login-menu' | dsBrowserOnly" ngbDropdownToggle>
|
||||
{{ 'nav.login' | translate }}
|
||||
</a>
|
||||
<div class="loginDropdownMenu" [ngClass]="{'pl-3 pr-3': (loading | async)}" ngbDropdownMenu
|
||||
@@ -17,9 +17,9 @@
|
||||
{{ 'nav.login' | translate }}<span class="sr-only">(current)</span>
|
||||
</a>
|
||||
</li>
|
||||
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item" data-test="user-menu">
|
||||
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item">
|
||||
<div ngbDropdown display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
|
||||
<a href="javascript:void(0);" role="button" [attr.aria-label]="'nav.logout' |translate" (click)="$event.preventDefault()" [title]="'nav.logout' | translate" class="px-1" ngbDropdownToggle>
|
||||
<a href="javascript:void(0);" role="button" [attr.aria-label]="'nav.logout' |translate" (click)="$event.preventDefault()" [title]="'nav.logout' | translate" class="px-1" [attr.data-test]="'user-menu' | dsBrowserOnly" ngbDropdownToggle>
|
||||
<i class="fas fa-user-circle fa-lg fa-fw"></i></a>
|
||||
<div class="logoutDropdownMenu" ngbDropdownMenu [attr.aria-label]="'nav.logout' |translate">
|
||||
<ds-user-menu></ds-user-menu>
|
||||
|
@@ -15,6 +15,7 @@ import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model';
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { of } from 'rxjs';
|
||||
import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe';
|
||||
|
||||
describe('AuthNavMenuComponent', () => {
|
||||
|
||||
@@ -77,7 +78,8 @@ describe('AuthNavMenuComponent', () => {
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
AuthNavMenuComponent
|
||||
AuthNavMenuComponent,
|
||||
BrowserOnlyMockPipe
|
||||
],
|
||||
providers: [
|
||||
{ provide: HostWindowService, useValue: window },
|
||||
|
@@ -8,6 +8,6 @@
|
||||
</ng-container>
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" *ngIf="canRegister$ | async" [routerLink]="[getRegisterRoute()]" data-test="register">{{"login.form.new-user" | translate}}</a>
|
||||
<a class="dropdown-item" [routerLink]="[getForgotRoute()]" data-test="forgot">{{"login.form.forgot-password" | translate}}</a>
|
||||
<a class="dropdown-item" *ngIf="canRegister$ | async" [routerLink]="[getRegisterRoute()]" [attr.data-test]="'register' | dsBrowserOnly">{{"login.form.new-user" | translate}}</a>
|
||||
<a class="dropdown-item" [routerLink]="[getForgotRoute()]" [attr.data-test]="'forgot' | dsBrowserOnly">{{"login.form.forgot-password" | translate}}</a>
|
||||
</div>
|
||||
|
@@ -10,7 +10,7 @@
|
||||
placeholder="{{'login.form.email' | translate}}"
|
||||
required
|
||||
type="email"
|
||||
data-test="email">
|
||||
[attr.data-test]="'email' | dsBrowserOnly">
|
||||
<label class="sr-only">{{"login.form.password" | translate}}</label>
|
||||
<input [attr.aria-label]="'login.form.password' |translate"
|
||||
autocomplete="off"
|
||||
@@ -19,12 +19,12 @@
|
||||
formControlName="password"
|
||||
required
|
||||
type="password"
|
||||
data-test="password">
|
||||
[attr.data-test]="'password' | dsBrowserOnly">
|
||||
<div *ngIf="(error | async) && hasError" class="alert alert-danger" role="alert"
|
||||
@fadeOut>{{ (error | async) | translate }}</div>
|
||||
<div *ngIf="(message | async) && hasMessage" class="alert alert-info" role="alert"
|
||||
@fadeOut>{{ (message | async) | translate }}</div>
|
||||
|
||||
<button class="btn btn-lg btn-primary btn-block mt-3" type="submit" data-test="login-button"
|
||||
<button class="btn btn-lg btn-primary btn-block mt-3" type="submit" [attr.data-test]="'login-button' | dsBrowserOnly"
|
||||
[disabled]="!form.valid"><i class="fas fa-sign-in-alt"></i> {{"login.form.submit" | translate}}</button>
|
||||
</form>
|
||||
|
@@ -17,6 +17,7 @@ import { storeModuleConfig } from '../../../../app.reducer';
|
||||
import { AuthMethod } from '../../../../core/auth/models/auth.method';
|
||||
import { AuthMethodType } from '../../../../core/auth/models/auth.method-type';
|
||||
import { HardRedirectService } from '../../../../core/services/hard-redirect.service';
|
||||
import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe';
|
||||
|
||||
describe('LogInPasswordComponent', () => {
|
||||
|
||||
@@ -57,7 +58,8 @@ describe('LogInPasswordComponent', () => {
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
LogInPasswordComponent
|
||||
LogInPasswordComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: AuthService, useClass: AuthServiceStub },
|
||||
|
@@ -2,5 +2,5 @@
|
||||
|
||||
<div *ngIf="(error | async)" class="alert alert-danger" role="alert" @fadeOut>{{ error | async }}</div>
|
||||
|
||||
<button class="btn btn-lg btn-primary btn-block mt-3" (click)="logOut()" data-test="logout-button"><i class="fas fa-sign-out-alt"></i> {{"logout.form.submit" | translate}}</button>
|
||||
<button class="btn btn-lg btn-primary btn-block mt-3" (click)="logOut()" [attr.data-test]="'logout-button' | dsBrowserOnly"><i class="fas fa-sign-out-alt"></i> {{"logout.form.submit" | translate}}</button>
|
||||
</div>
|
||||
|
@@ -12,6 +12,7 @@ import { Router } from '@angular/router';
|
||||
import { AppState } from '../../app.reducer';
|
||||
import { LogOutComponent } from './log-out.component';
|
||||
import { RouterStub } from '../testing/router.stub';
|
||||
import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe';
|
||||
|
||||
describe('LogOutComponent', () => {
|
||||
|
||||
@@ -46,7 +47,8 @@ describe('LogOutComponent', () => {
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
declarations: [
|
||||
LogOutComponent
|
||||
LogOutComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: Router, useValue: routerStub },
|
||||
|
@@ -18,7 +18,7 @@
|
||||
>
|
||||
<div class="card-columns row" *ngIf="objects?.hasSucceeded">
|
||||
<div class="card-column col col-sm-6 col-lg-4" *ngFor="let column of (columns$ | async)" @fadeIn>
|
||||
<div class="card-element" *ngFor="let object of column" data-test="grid-object">
|
||||
<div class="card-element" *ngFor="let object of column" [attr.data-test]="'grid-object' | dsBrowserOnly">
|
||||
<ds-listable-object-component-loader [object]="object" [viewMode]="viewMode" [context]="context" [linkType]="linkType"></ds-listable-object-component-loader>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -17,7 +17,7 @@
|
||||
(next)="goNext()"
|
||||
>
|
||||
<ul *ngIf="objects?.hasSucceeded" class="list-unstyled" [ngClass]="{'ml-4': selectable}">
|
||||
<li *ngFor="let object of objects?.payload?.page; let i = index; let last = last" class="mt-4 mb-4 d-flex" [class.border-bottom]="hasBorder && !last" data-test="list-object">
|
||||
<li *ngFor="let object of objects?.payload?.page; let i = index; let last = last" class="mt-4 mb-4 d-flex" [class.border-bottom]="hasBorder && !last" [attr.data-test]="'list-object' | dsBrowserOnly">
|
||||
<ds-selectable-list-item-control *ngIf="selectable" [index]="i"
|
||||
[object]="object"
|
||||
[selectionConfig]="selectionConfig"
|
||||
|
@@ -4,10 +4,10 @@
|
||||
<div *ngIf="showScopeSelector === true" class="input-group-prepend">
|
||||
<button class="scope-button btn btn-outline-secondary text-truncate" [ngbTooltip]="(selectedScope | async)?.name" type="button" (click)="openScopeModal()">{{(selectedScope | async)?.name || ('search.form.scope.all' | translate)}}</button>
|
||||
</div>
|
||||
<input type="text" [(ngModel)]="query" name="query" class="form-control" attr.aria-label="{{ searchPlaceholder }}" data-test="search-box"
|
||||
<input type="text" [(ngModel)]="query" name="query" class="form-control" attr.aria-label="{{ searchPlaceholder }}" [attr.data-test]="'search-box' | dsBrowserOnly"
|
||||
[placeholder]="searchPlaceholder">
|
||||
<span class="input-group-append">
|
||||
<button type="submit" class="search-button btn btn-{{brandColor}}" data-test="search-button"><i class="fas fa-search"></i> {{ ('search.form.search' | translate) }}</button>
|
||||
<button type="submit" class="search-button btn btn-{{brandColor}}" [attr.data-test]="'search-button' | dsBrowserOnly"><i class="fas fa-search"></i> {{ ('search.form.search' | translate) }}</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -14,6 +14,7 @@ import { PaginationServiceStub } from '../testing/pagination-service.stub';
|
||||
import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.service';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
|
||||
import { FindListOptions } from '../../core/data/find-list-options.model';
|
||||
import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe';
|
||||
|
||||
describe('SearchFormComponent', () => {
|
||||
let comp: SearchFormComponent;
|
||||
@@ -37,7 +38,10 @@ describe('SearchFormComponent', () => {
|
||||
{ provide: SearchConfigurationService, useValue: searchConfigService },
|
||||
{ provide: DSpaceObjectDataService, useValue: { findById: () => createSuccessfulRemoteDataObject$(undefined)} }
|
||||
],
|
||||
declarations: [SearchFormComponent]
|
||||
declarations: [
|
||||
SearchFormComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
]
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
class="filter-name d-flex" [attr.aria-controls]="regionId" [id]="toggleId"
|
||||
[attr.aria-expanded]="false"
|
||||
[attr.aria-label]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate"
|
||||
[attr.data-test]="'filter-toggle' | dsBrowserOnly"
|
||||
>
|
||||
<h5 class="d-inline-block mb-0">
|
||||
{{'search.filters.filter.' + filter.name + '.head'| translate}}
|
||||
|
@@ -13,6 +13,7 @@ import { FilterType } from '../../models/filter-type.model';
|
||||
import { SearchConfigurationServiceStub } from '../../../testing/search-configuration-service.stub';
|
||||
import { SEARCH_CONFIG_SERVICE } from '../../../../my-dspace-page/my-dspace-page.component';
|
||||
import { SequenceService } from '../../../../core/shared/sequence.service';
|
||||
import { BrowserOnlyMockPipe } from '../../../testing/browser-only-mock.pipe';
|
||||
|
||||
describe('SearchFilterComponent', () => {
|
||||
let comp: SearchFilterComponent;
|
||||
@@ -62,7 +63,10 @@ describe('SearchFilterComponent', () => {
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule],
|
||||
declarations: [SearchFilterComponent],
|
||||
declarations: [
|
||||
SearchFilterComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: searchServiceStub },
|
||||
{
|
||||
|
@@ -173,7 +173,7 @@ import { DsSelectComponent } from './ds-select/ds-select.component';
|
||||
import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component';
|
||||
import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
||||
import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component';
|
||||
|
||||
import { BrowserOnlyPipe } from './utils/browser-only.pipe';
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
CommonModule,
|
||||
@@ -215,7 +215,8 @@ const PIPES = [
|
||||
ObjectKeysPipe,
|
||||
ObjectValuesPipe,
|
||||
ConsolePipe,
|
||||
ObjNgFor
|
||||
ObjNgFor,
|
||||
BrowserOnlyPipe,
|
||||
];
|
||||
|
||||
const COMPONENTS = [
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<div class="facet-filter d-block mb-3 p-3">
|
||||
<div (click)="toggle()" class="filter-name">
|
||||
<div (click)="toggle()" class="filter-name" [attr.data-test]="'filter-toggle' | dsBrowserOnly">
|
||||
<h5 class="d-inline-block mb-0">
|
||||
{{ label | translate }}
|
||||
</h5>
|
||||
|
13
src/app/shared/testing/browser-only-mock.pipe.ts
Normal file
13
src/app/shared/testing/browser-only-mock.pipe.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
|
||||
/**
|
||||
* Support dsBrowserOnly in unit tests.
|
||||
*/
|
||||
@Pipe({
|
||||
name: 'dsBrowserOnly'
|
||||
})
|
||||
export class BrowserOnlyMockPipe implements PipeTransform {
|
||||
transform(value: string): string | undefined {
|
||||
return value;
|
||||
}
|
||||
}
|
@@ -5,6 +5,7 @@ import { SharedModule } from '../shared.module';
|
||||
import { NgComponentOutletDirectiveStub } from './ng-component-outlet-directive.stub';
|
||||
import { QueryParamsDirectiveStub } from './query-params-directive.stub';
|
||||
import { RouterLinkDirectiveStub } from './router-link-directive.stub';
|
||||
import { BrowserOnlyMockPipe } from './browser-only-mock.pipe';
|
||||
|
||||
/**
|
||||
* This module isn't used. It serves to prevent the AoT compiler
|
||||
@@ -21,7 +22,8 @@ import { RouterLinkDirectiveStub } from './router-link-directive.stub';
|
||||
QueryParamsDirectiveStub,
|
||||
MySimpleItemActionComponent,
|
||||
RouterLinkDirectiveStub,
|
||||
NgComponentOutletDirectiveStub
|
||||
NgComponentOutletDirectiveStub,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
exports: [
|
||||
QueryParamsDirectiveStub
|
||||
|
24
src/app/shared/utils/browser-only.pipe.ts
Normal file
24
src/app/shared/utils/browser-only.pipe.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Inject, Pipe, PipeTransform, PLATFORM_ID } from '@angular/core';
|
||||
import { isPlatformBrowser } from '@angular/common';
|
||||
|
||||
/**
|
||||
* A pipe that only returns its intput when run in the browser.
|
||||
* Used to distinguish client-side rendered content from server-side rendered content.
|
||||
*/
|
||||
@Pipe({
|
||||
name: 'dsBrowserOnly'
|
||||
})
|
||||
export class BrowserOnlyPipe implements PipeTransform {
|
||||
constructor(
|
||||
@Inject(PLATFORM_ID) private platformID: any,
|
||||
) {
|
||||
}
|
||||
|
||||
transform(value: string): string | undefined {
|
||||
if (isPlatformBrowser((this.platformID))) {
|
||||
return value;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode === viewModeEnum.ListElement"
|
||||
class="btn btn-secondary"
|
||||
data-test="list-view">
|
||||
[attr.data-test]="'list-view' | dsBrowserOnly">
|
||||
<i class="fas fa-list" title="{{'search.view-switch.show-list' | translate}}"></i>
|
||||
</a>
|
||||
<a *ngIf="isToShow(viewModeEnum.GridElement)"
|
||||
@@ -18,7 +18,7 @@
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode === viewModeEnum.GridElement"
|
||||
class="btn btn-secondary"
|
||||
data-test="grid-view">
|
||||
[attr.data-test]="'grid-view' | dsBrowserOnly">
|
||||
<i class="fas fa-th-large" title="{{'search.view-switch.show-grid' | translate}}"></i>
|
||||
</a>
|
||||
<a *ngIf="isToShow(viewModeEnum.DetailedListElement)"
|
||||
@@ -29,7 +29,7 @@
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode === viewModeEnum.DetailedListElement"
|
||||
class="btn btn-secondary"
|
||||
data-test="detail-view">
|
||||
[attr.data-test]="'detail-view' | dsBrowserOnly">
|
||||
<i class="far fa-square" title="{{'search.view-switch.show-detail' | translate}}"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
@@ -9,6 +9,7 @@ import { SearchService } from '../../core/shared/search/search.service';
|
||||
import { ViewModeSwitchComponent } from './view-mode-switch.component';
|
||||
import { SearchServiceStub } from '../testing/search-service.stub';
|
||||
import { ViewMode } from '../../core/shared/view-mode.model';
|
||||
import { BrowserOnlyMockPipe } from '../testing/browser-only-mock.pipe';
|
||||
|
||||
@Component({ template: '' })
|
||||
class DummyComponent {
|
||||
@@ -36,7 +37,8 @@ describe('ViewModeSwitchComponent', () => {
|
||||
],
|
||||
declarations: [
|
||||
ViewModeSwitchComponent,
|
||||
DummyComponent
|
||||
DummyComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: searchService },
|
||||
|
@@ -3,6 +3,7 @@
|
||||
<button *ngIf="(showDepositAndDiscard | async)"
|
||||
type="button"
|
||||
id="discard"
|
||||
[attr.data-test]="'discard' | dsBrowserOnly"
|
||||
class="btn btn-danger"
|
||||
[disabled]="(processingSaveStatus | async) || (processingDepositStatus | async)"
|
||||
(click)="$event.preventDefault();confirmDiscard(content)">
|
||||
@@ -26,6 +27,7 @@
|
||||
<button type="button"
|
||||
class="btn btn-secondary"
|
||||
id="save"
|
||||
[attr.data-test]="'save' | dsBrowserOnly"
|
||||
[disabled]="(processingSaveStatus | async) || !(hasUnsavedModification | async)"
|
||||
(click)="save($event)">
|
||||
<span><i class="fas fa-save"></i> {{'submission.general.save' | translate}}</span>
|
||||
@@ -35,6 +37,7 @@
|
||||
[class.btn-secondary]="(showDepositAndDiscard | async)"
|
||||
class="btn"
|
||||
id="saveForLater"
|
||||
[attr.data-test]="'save-for-later' | dsBrowserOnly"
|
||||
[disabled]="(processingSaveStatus | async) || (processingDepositStatus | async)"
|
||||
(click)="saveLater($event)">
|
||||
<span><i class="fas fa-save"></i> {{'submission.general.save-later' | translate}}</span>
|
||||
@@ -42,6 +45,7 @@
|
||||
<button *ngIf="(showDepositAndDiscard | async)"
|
||||
type="button"
|
||||
id="deposit"
|
||||
[attr.data-test]="'deposit' | dsBrowserOnly"
|
||||
class="btn btn-success"
|
||||
[disabled]="(processingSaveStatus | async) || (processingDepositStatus | async)"
|
||||
(click)="deposit($event)">
|
||||
|
@@ -15,12 +15,13 @@ import { SubmissionRestServiceStub } from '../../../shared/testing/submission-re
|
||||
import { SubmissionFormFooterComponent } from './submission-form-footer.component';
|
||||
import { SubmissionRestService } from '../../../core/submission/submission-rest.service';
|
||||
import { createTestComponent } from '../../../shared/testing/utils.test';
|
||||
import { BrowserOnlyMockPipe } from '../../../shared/testing/browser-only-mock.pipe';
|
||||
|
||||
const submissionServiceStub: SubmissionServiceStub = new SubmissionServiceStub();
|
||||
|
||||
const submissionId = mockSubmissionId;
|
||||
|
||||
describe('SubmissionFormFooterComponent Component', () => {
|
||||
describe('SubmissionFormFooterComponent', () => {
|
||||
|
||||
let comp: SubmissionFormFooterComponent;
|
||||
let compAsAny: any;
|
||||
@@ -36,7 +37,8 @@ describe('SubmissionFormFooterComponent Component', () => {
|
||||
],
|
||||
declarations: [
|
||||
SubmissionFormFooterComponent,
|
||||
TestComponent
|
||||
TestComponent,
|
||||
BrowserOnlyMockPipe,
|
||||
],
|
||||
providers: [
|
||||
{ provide: SubmissionService, useValue: submissionServiceStub },
|
||||
|
Reference in New Issue
Block a user