mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 10:04:11 +00:00
Merge pull request #1315 from tdonohue/header_keyboard_fix
Header Accessibility Fix: Allow enter key or spacebar to expand or contract menu based on current active status
This commit is contained in:
14
README.md
14
README.md
@@ -212,13 +212,17 @@ Once you have tested the Pull Request, please add a comment and/or approval to t
|
|||||||
|
|
||||||
### Unit Tests
|
### Unit Tests
|
||||||
|
|
||||||
Unit tests use Karma. You can find the configuration file at the same level of this README file:`./karma.conf.js` If you are going to use a remote test environment you need to edit the `./karma.conf.js`. Follow the instructions you will find inside it. To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'. A coverage report is also available at: http://localhost:9876/ after you run: `yarn run coverage`.
|
Unit tests use the [Jasmine test framework](https://jasmine.github.io/), and are run via [Karma](https://karma-runner.github.io/).
|
||||||
|
|
||||||
|
You can find the Karma configuration file at the same level of this README file:`./karma.conf.js` If you are going to use a remote test environment you need to edit the `./karma.conf.js`. Follow the instructions you will find inside it. To executing tests whenever any file changes you can modify the 'autoWatch' option to 'true' and 'singleRun' option to 'false'. A coverage report is also available at: http://localhost:9876/ after you run: `yarn run coverage`.
|
||||||
|
|
||||||
The default browser is Google Chrome.
|
The default browser is Google Chrome.
|
||||||
|
|
||||||
Place your tests in the same location of the application source code files that they test.
|
Place your tests in the same location of the application source code files that they test, e.g. ending with `*.component.spec.ts`
|
||||||
|
|
||||||
and run: `yarn run test`
|
and run: `yarn test`
|
||||||
|
|
||||||
|
If you run into odd test errors, see the Angular guide to debugging tests: https://angular.io/guide/test-debugging
|
||||||
|
|
||||||
### E2E Tests
|
### E2E Tests
|
||||||
|
|
||||||
@@ -258,6 +262,10 @@ _Hint: Creating e2e tests is easiest in an IDE (like Visual Studio), as it can h
|
|||||||
|
|
||||||
More Information: [docs.cypress.io](https://docs.cypress.io/) has great guides & documentation helping you learn more about writing/debugging e2e tests in Cypress.
|
More Information: [docs.cypress.io](https://docs.cypress.io/) has great guides & documentation helping you learn more about writing/debugging e2e tests in Cypress.
|
||||||
|
|
||||||
|
### Learning how to build tests
|
||||||
|
|
||||||
|
See our [DSpace Code Testing Guide](https://wiki.lyrasis.org/display/DSPACE/Code+Testing+Guide) for more hints/tips.
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
@@ -1,5 +1,8 @@
|
|||||||
<div class="nav-item dropdown expandable-navbar-section"
|
<div class="nav-item dropdown expandable-navbar-section"
|
||||||
(keyup.enter)="activateSection($event)"
|
*ngVar="(active | async) as isActive"
|
||||||
|
(keyup.enter)="isActive ? deactivateSection($event) : activateSection($event)"
|
||||||
|
(keyup.space)="isActive ? deactivateSection($event) : activateSection($event)"
|
||||||
|
(keydown.space)="$event.preventDefault()"
|
||||||
(mouseenter)="activateSection($event)"
|
(mouseenter)="activateSection($event)"
|
||||||
(mouseleave)="deactivateSection($event)">
|
(mouseleave)="deactivateSection($event)">
|
||||||
<a href="#" class="nav-link dropdown-toggle" routerLinkActive="active"
|
<a href="#" class="nav-link dropdown-toggle" routerLinkActive="active"
|
||||||
|
@@ -9,6 +9,7 @@ import { HostWindowService } from '../../shared/host-window.service';
|
|||||||
import { MenuService } from '../../shared/menu/menu.service';
|
import { MenuService } from '../../shared/menu/menu.service';
|
||||||
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
|
import { HostWindowServiceStub } from '../../shared/testing/host-window-service.stub';
|
||||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { VarDirective } from '../../shared/utils/var.directive';
|
||||||
|
|
||||||
describe('ExpandableNavbarSectionComponent', () => {
|
describe('ExpandableNavbarSectionComponent', () => {
|
||||||
let component: ExpandableNavbarSectionComponent;
|
let component: ExpandableNavbarSectionComponent;
|
||||||
@@ -19,7 +20,7 @@ describe('ExpandableNavbarSectionComponent', () => {
|
|||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
declarations: [ExpandableNavbarSectionComponent, TestComponent],
|
declarations: [ExpandableNavbarSectionComponent, TestComponent, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: 'sectionDataProvider', useValue: {} },
|
{ provide: 'sectionDataProvider', useValue: {} },
|
||||||
{ provide: MenuService, useValue: menuService },
|
{ provide: MenuService, useValue: menuService },
|
||||||
@@ -76,6 +77,78 @@ describe('ExpandableNavbarSectionComponent', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when Enter key is pressed on section header (while inactive)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(menuService, 'activateSection');
|
||||||
|
// Make sure section is 'inactive'. Requires calling ngOnInit() to update component 'active' property.
|
||||||
|
spyOn(menuService, 'isSectionActive').and.returnValue(observableOf(false));
|
||||||
|
component.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const sidebarToggler = fixture.debugElement.query(By.css('div.nav-item.dropdown'));
|
||||||
|
// dispatch the (keyup.enter) action used in our component HTML
|
||||||
|
sidebarToggler.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call activateSection on the menuService', () => {
|
||||||
|
expect(menuService.activateSection).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when Enter key is pressed on section header (while active)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(menuService, 'deactivateSection');
|
||||||
|
// Make sure section is 'active'. Requires calling ngOnInit() to update component 'active' property.
|
||||||
|
spyOn(menuService, 'isSectionActive').and.returnValue(observableOf(true));
|
||||||
|
component.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const sidebarToggler = fixture.debugElement.query(By.css('div.nav-item.dropdown'));
|
||||||
|
// dispatch the (keyup.enter) action used in our component HTML
|
||||||
|
sidebarToggler.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call deactivateSection on the menuService', () => {
|
||||||
|
expect(menuService.deactivateSection).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when spacebar is pressed on section header (while inactive)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(menuService, 'activateSection');
|
||||||
|
// Make sure section is 'inactive'. Requires calling ngOnInit() to update component 'active' property.
|
||||||
|
spyOn(menuService, 'isSectionActive').and.returnValue(observableOf(false));
|
||||||
|
component.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const sidebarToggler = fixture.debugElement.query(By.css('div.nav-item.dropdown'));
|
||||||
|
// dispatch the (keyup.space) action used in our component HTML
|
||||||
|
sidebarToggler.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: ' ' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call activateSection on the menuService', () => {
|
||||||
|
expect(menuService.activateSection).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when spacebar is pressed on section header (while active)', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
spyOn(menuService, 'deactivateSection');
|
||||||
|
// Make sure section is 'active'. Requires calling ngOnInit() to update component 'active' property.
|
||||||
|
spyOn(menuService, 'isSectionActive').and.returnValue(observableOf(true));
|
||||||
|
component.ngOnInit();
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
const sidebarToggler = fixture.debugElement.query(By.css('div.nav-item.dropdown'));
|
||||||
|
// dispatch the (keyup.space) action used in our component HTML
|
||||||
|
sidebarToggler.nativeElement.dispatchEvent(new KeyboardEvent('keyup', { key: ' ' }));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call deactivateSection on the menuService', () => {
|
||||||
|
expect(menuService.deactivateSection).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when a click occurs on the section header', () => {
|
describe('when a click occurs on the section header', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
spyOn(menuService, 'toggleActiveSection');
|
spyOn(menuService, 'toggleActiveSection');
|
||||||
@@ -96,7 +169,7 @@ describe('ExpandableNavbarSectionComponent', () => {
|
|||||||
beforeEach(waitForAsync(() => {
|
beforeEach(waitForAsync(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [NoopAnimationsModule],
|
imports: [NoopAnimationsModule],
|
||||||
declarations: [ExpandableNavbarSectionComponent, TestComponent],
|
declarations: [ExpandableNavbarSectionComponent, TestComponent, VarDirective],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: 'sectionDataProvider', useValue: {} },
|
{ provide: 'sectionDataProvider', useValue: {} },
|
||||||
{ provide: MenuService, useValue: menuService },
|
{ provide: MenuService, useValue: menuService },
|
||||||
|
Reference in New Issue
Block a user