Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor Accessibility Fixes & Enable accessibility scan on more pages #2468

Merged
merged 9 commits into from
Aug 30, 2023
10 changes: 1 addition & 9 deletions cypress/e2e/community-list.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Options } from 'cypress-axe';
import { testA11y } from 'cypress/support/utils';

describe('Community List Page', () => {
Expand All @@ -13,13 +12,6 @@ describe('Community List Page', () => {
cy.get('[data-test="expand-button"]').click({ multiple: true });

// Analyze <ds-community-list-page> for accessibility issues
// Disable heading-order checks until it is fixed
testA11y('ds-community-list-page',
{
rules: {
'heading-order': { enabled: false }
}
} as Options
);
testA11y('ds-community-list-page');
});
});
3 changes: 1 addition & 2 deletions cypress/e2e/header.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ describe('Header', () => {
testA11y({
include: ['ds-header'],
exclude: [
['#search-navbar-container'], // search in navbar has duplicative ID. Will be fixed in #1174
['.dropdownLogin'] // "Log in" link has color contrast issues. Will be fixed in #1149
['#search-navbar-container'] // search in navbar has duplicative ID. Will be fixed in #1174
],
});
});
Expand Down
20 changes: 11 additions & 9 deletions cypress/e2e/item-page.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Options } from 'cypress-axe';
import { TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e';
import { testA11y } from 'cypress/support/utils';

Expand All @@ -19,13 +18,16 @@ describe('Item Page', () => {
cy.get('ds-item-page').should('be.visible');

// Analyze <ds-item-page> for accessibility issues
// Disable heading-order checks until it is fixed
testA11y('ds-item-page',
{
rules: {
'heading-order': { enabled: false }
}
} as Options
);
testA11y('ds-item-page');
});

it('should pass accessibility tests on full item page', () => {
cy.visit(ENTITYPAGE + '/full');

// <ds-full-item-page> tag must be loaded
cy.get('ds-full-item-page').should('be.visible');

// Analyze <ds-full-item-page> for accessibility issues
testA11y('ds-full-item-page');
});
});
12 changes: 12 additions & 0 deletions cypress/e2e/login-modal.cy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { TEST_ADMIN_PASSWORD, TEST_ADMIN_USER, TEST_ENTITY_PUBLICATION } from 'cypress/support/e2e';
import { testA11y } from 'cypress/support/utils';

const page = {
openLoginMenu() {
Expand Down Expand Up @@ -123,4 +124,15 @@ describe('Login Modal', () => {
cy.location('pathname').should('eq', '/forgot');
cy.get('ds-forgot-email').should('exist');
});

it('should pass accessibility tests', () => {
cy.visit('/');

page.openLoginMenu();

cy.get('ds-log-in').should('exist');

// Analyze <ds-log-in> for accessibility issues
testA11y('ds-log-in');
});
});
16 changes: 1 addition & 15 deletions cypress/e2e/my-dspace.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,7 @@ describe('My DSpace page', () => {
cy.get('.filter-toggle').click({ multiple: true });

// Analyze <ds-my-dspace-page> for accessibility issues
testA11y(
{
include: ['ds-my-dspace-page'],
exclude: [
['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175
],
},
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
testA11y('ds-my-dspace-page');
});

it('should have a working detailed view that passes accessibility tests', () => {
Expand Down
5 changes: 5 additions & 0 deletions cypress/e2e/pagenotfound.cy.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { testA11y } from 'cypress/support/utils';

describe('PageNotFound', () => {
it('should contain element ds-pagenotfound when navigating to page that doesnt exist', () => {
// request an invalid page (UUIDs at root path aren't valid)
cy.visit('/e9019a69-d4f1-4773-b6a3-bd362caa46f2', { failOnStatusCode: false });
cy.get('ds-pagenotfound').should('be.visible');

// Analyze <ds-pagenotfound> for accessibility issues
testA11y('ds-pagenotfound');
});

it('should not contain element ds-pagenotfound when navigating to existing page', () => {
Expand Down
16 changes: 1 addition & 15 deletions cypress/e2e/search-page.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,7 @@ describe('Search Page', () => {
cy.get('[data-test="filter-toggle"]').click({ multiple: true });

// Analyze <ds-search-page> for accessibility issues
testA11y(
{
include: ['ds-search-page'],
exclude: [
['nouislider'] // Date filter slider is missing ARIA labels. Will be fixed by #1175
],
},
{
rules: {
// Search filters fail these two "moderate" impact rules
'heading-order': { enabled: false },
'landmark-unique': { enabled: false }
}
} as Options
);
testA11y('ds-search-page');
});

it('should have a working grid view that passes accessibility tests', () => {
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,12 @@
"morgan": "^1.10.0",
"ng-mocks": "^14.10.0",
"ng2-file-upload": "1.4.0",
"ng2-nouislider": "^1.8.3",
"ng2-nouislider": "^2.0.0",
"ngx-infinite-scroll": "^15.0.0",
"ngx-pagination": "6.0.3",
"ngx-sortablejs": "^11.1.0",
"ngx-ui-switch": "^14.0.3",
"nouislider": "^14.6.3",
"nouislider": "^15.7.1",
"pem": "1.14.7",
"prop-types": "^15.8.1",
"react-copy-to-clipboard": "^5.1.0",
Expand Down Expand Up @@ -159,11 +159,11 @@
"@types/sanitize-html": "^2.9.0",
"@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1",
"axe-core": "^4.7.0",
"axe-core": "^4.7.2",
"compression-webpack-plugin": "^9.2.0",
"copy-webpack-plugin": "^6.4.1",
"cross-env": "^7.0.3",
"cypress": "12.10.0",
"cypress": "12.17.4",
"cypress-axe": "^1.4.0",
"deep-freeze": "0.0.1",
"eslint": "^8.39.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h2 class="item-page-title-field">
<h1 class="item-page-title-field">
<div *ngIf="item.firstMetadataValue('dspace.entity.type') as type" class="d-inline">
{{ type.toLowerCase() + '.page.titleprefix' | translate }}
</div>
<span class="dont-break-out">{{ dsoNameService.getName(item) }}</span>
</h2>
</h1>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="simple-view-element" [class.d-none]="hideIfNoTextContent && content.textContent.trim().length === 0">
<h5 class="simple-view-element-header" *ngIf="label">{{ label }}</h5>
<h2 class="simple-view-element-header" *ngIf="label">{{ label }}</h2>
<div #content class="simple-view-element-body">
<ng-content></ng-content>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
.simple-view-element {
margin-bottom: 15px;
}
.simple-view-element-header {
font-size: 1.25rem;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
[attr.aria-label]="(((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate) + ' ' + (('search.filters.filter.' + filter.name + '.head') | translate | lowercase)"
[attr.data-test]="'filter-toggle' | dsBrowserOnly"
>
<h5 class="d-inline-block mb-0">
<h4 class="d-inline-block mb-0">
{{'search.filters.filter.' + filter.name + '.head'| translate}}
</h5>
</h4>
<span class="filter-toggle flex-grow-1 fas p-auto"
[ngClass]="(collapsed$ | async) ? 'fa-plus' : 'fa-minus'"
[title]="((collapsed$ | async) ? 'search.filters.filter.expand' : 'search.filters.filter.collapse') | translate">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</span>
<input type="text" [(ngModel)]="range[0]" [name]="filterConfig.paramName + '.min'"
class="form-control" (blur)="onSubmit()"
aria-label="Mininum value"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.min.placeholder' | translate"
[attr.aria-label]="minLabel"
[placeholder]="minLabel"
/>
</label>
</div>
Expand All @@ -21,8 +21,8 @@
</span>
<input type="text" [(ngModel)]="range[1]" [name]="filterConfig.paramName + '.max'"
class="form-control" (blur)="onSubmit()"
aria-label="Maximum value"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.max.placeholder' | translate"
[attr.aria-label]="maxLabel"
[placeholder]="maxLabel"
/>
</label>
</div>
Expand All @@ -33,7 +33,7 @@
</form>

<ng-container *ngIf="shouldShowSlider()">
<nouislider [connect]="true" [min]="min" [max]="max" [step]="1"
<nouislider [connect]="true" [config]="config" [min]="min" [max]="max" [step]="1"
[dsDebounce]="250" (onDebounce)="onSubmit()"
(keydown)="startKeyboardControl()" (keyup)="stopKeyboardControl()"
[(ngModel)]="range" ngDefaultControl>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BehaviorSubject, combineLatest as observableCombineLatest, Subscription
import { map, startWith } from 'rxjs/operators';
import { isPlatformBrowser } from '@angular/common';
import { Component, Inject, OnDestroy, OnInit, PLATFORM_ID } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { RemoteDataBuildService } from '../../../../../core/cache/builders/remote-data-build.service';
import { FilterType } from '../../../models/filter-type.model';
import { renderFacetFor } from '../search-filter-type-decorator';
Expand Down Expand Up @@ -53,11 +54,27 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
*/
min = 1950;

/**
* i18n Label to use for minimum field
*/
minLabel: string;

/**
* Fallback maximum for the range
*/
max = new Date().getUTCFullYear();

/**
* i18n Label to use for maximum field
*/
maxLabel: string;

/**
* Base configuration for nouislider
* https://refreshless.com/nouislider/slider-options/
*/
config = {};

/**
* The current range of the filter
*/
Expand All @@ -78,6 +95,7 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
protected filterService: SearchFilterService,
protected router: Router,
protected rdbs: RemoteDataBuildService,
private translateService: TranslateService,
@Inject(SEARCH_CONFIG_SERVICE) public searchConfigService: SearchConfigurationService,
@Inject(IN_PLACE_SEARCH) public inPlaceSearch: boolean,
@Inject(FILTER_CONFIG) public filterConfig: SearchFilterConfig,
Expand All @@ -96,6 +114,8 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
super.ngOnInit();
this.min = yearFromString(this.filterConfig.minValue) || this.min;
this.max = yearFromString(this.filterConfig.maxValue) || this.max;
this.minLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.min.placeholder');
this.maxLabel = this.translateService.instant('search.filters.filter.' + this.filterConfig.name + '.max.placeholder');
const iniMin = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MIN_SUFFIX).pipe(startWith(undefined));
const iniMax = this.route.getQueryParameterValue(this.filterConfig.paramName + RANGE_FILTER_MAX_SUFFIX).pipe(startWith(undefined));
this.sub = observableCombineLatest(iniMin, iniMax).pipe(
Expand All @@ -105,6 +125,15 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
return [minimum, maximum];
})
).subscribe((minmax) => this.range = minmax);

// Default/base config for nouislider
this.config = {
// Ensure draggable handles have labels
handleAttributes: [
{ 'aria-label': this.minLabel },
{ 'aria-label': this.maxLabel },
],
};
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/app/shared/sidebar/sidebar-dropdown.component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="setting-option mb-3 p-3">
<h5><label for="{{id}}">{{label | translate}}</label></h5>
<h4><label for="{{id}}">{{label | translate}}</label></h4>
<select id="{{id}}" class="form-control" (change)="change.emit($event)">
<ng-content></ng-content>
</select>
Expand Down
2 changes: 1 addition & 1 deletion src/styles/_vendor.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// node_modules imports meant for all the themes

@import '~node_modules/bootstrap/scss/bootstrap.scss';
@import '~node_modules/nouislider/distribute/nouislider.min';
@import '~node_modules/nouislider/dist/nouislider.min';
@import '~node_modules/ngx-ui-switch/ui-switch.component.scss';
2 changes: 1 addition & 1 deletion src/themes/dspace/styles/_global-styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
background-color: var(--bs-primary);
}

h5 {
h4 {
font-size: 1.1rem
}
}
Loading
Loading