mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-03-16 00:05:53 -04:00
Merge pull request #3664 from alphagov/fix-template-controls-for-screenreaders
Fix template controls for screenreaders
This commit is contained in:
@@ -17,18 +17,59 @@
|
||||
|
||||
// all the diff states that we want to show or hide
|
||||
this.states = [
|
||||
{key: 'nothing-selected-buttons', $el: this.$form.find('#nothing_selected'), cancellable: false},
|
||||
{key: 'items-selected-buttons', $el: this.$form.find('#items_selected'), cancellable: false},
|
||||
{key: 'move-to-existing-folder', $el: this.$form.find('#move_to_folder_radios'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_folder_radios fieldset', true)},
|
||||
{key: 'move-to-new-folder', $el: this.$form.find('#move_to_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_new_folder_name', false)},
|
||||
{key: 'add-new-folder', $el: this.$form.find('#add_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_folder_name', false)},
|
||||
{key: 'add-new-template', $el: this.$form.find('#add_new_template_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_template_form fieldset', true)}
|
||||
{
|
||||
key: 'nothing-selected-buttons',
|
||||
$el: this.$form.find('#nothing_selected'),
|
||||
cancellable: false
|
||||
},
|
||||
{
|
||||
key: 'items-selected-buttons',
|
||||
$el: this.$form.find('#items_selected'),
|
||||
cancellable: false
|
||||
},
|
||||
{
|
||||
key: 'move-to-existing-folder',
|
||||
$el: this.$form.find('#move_to_folder_radios'),
|
||||
cancellable: true,
|
||||
setFocus: () => $('#move_to_folder_radios').focus(),
|
||||
action: 'move to folder',
|
||||
description: 'Press move to confirm or cancel to close'
|
||||
},
|
||||
{
|
||||
key: 'move-to-new-folder',
|
||||
$el: this.$form.find('#move_to_new_folder_form'),
|
||||
cancellable: true,
|
||||
setFocus: () => $('#move_to_new_folder_form').focus(),
|
||||
action: 'move to new folder',
|
||||
description: 'Press add to new folder to confirm name or cancel to close'
|
||||
},
|
||||
{
|
||||
key: 'add-new-folder',
|
||||
$el: this.$form.find('#add_new_folder_form'),
|
||||
cancellable: true,
|
||||
setFocus: () => $('#add_new_folder_form').focus(),
|
||||
action: 'new folder',
|
||||
description: 'Press add new folder to confirm name or cancel to close'
|
||||
},
|
||||
{
|
||||
key: 'add-new-template',
|
||||
$el: this.$form.find('#add_new_template_form'),
|
||||
cancellable: true,
|
||||
setFocus: () => $('#add_new_template_form').focus(),
|
||||
action: 'new template',
|
||||
description: 'Press continue to confirm selection or cancel to close'
|
||||
}
|
||||
];
|
||||
|
||||
// cancel/clear buttons only relevant if JS enabled, so
|
||||
this.states.filter(state => state.cancellable).forEach((x) => this.addCancelButton(x));
|
||||
this.states.filter(state => state.key === 'items-selected-buttons').forEach(x => this.addClearButton(x));
|
||||
|
||||
// make elements focusabled
|
||||
this.states.filter(state => state.setFocus).forEach(x => x.$el.attr('tabindex', '0'));
|
||||
|
||||
this.addDescriptionsToStates();
|
||||
|
||||
// activate stickiness of elements in each state
|
||||
this.activateStickyElements();
|
||||
|
||||
@@ -45,22 +86,16 @@
|
||||
this.$form.on('change', 'input[type=checkbox]', () => this.templateFolderCheckboxChanged());
|
||||
};
|
||||
|
||||
this.getFocusRoutine = function (selector, setTabindex) {
|
||||
return function () {
|
||||
let $el = $(selector);
|
||||
let removeTabindex = (e) => {
|
||||
$(e.target)
|
||||
.removeAttr('tabindex')
|
||||
.off('blur', removeTabindex);
|
||||
};
|
||||
this.addDescriptionsToStates = function () {
|
||||
let id, description;
|
||||
|
||||
if (setTabindex) {
|
||||
$el.attr('tabindex', '-1');
|
||||
$el.on('blur', removeTabindex);
|
||||
}
|
||||
|
||||
$el.focus();
|
||||
};
|
||||
$.each(this.states.filter(state => 'description' in state), (idx, state) => {
|
||||
id = `${state.key}__description`;
|
||||
description = `<p class="govuk-visually-hidden" id="${id}">${state.description}</p>`;
|
||||
state.$el
|
||||
.prepend(description)
|
||||
.attr('aria-describedby', id);
|
||||
});
|
||||
};
|
||||
|
||||
this.activateStickyElements = function() {
|
||||
@@ -88,7 +123,7 @@
|
||||
this.selectActionButtons(selector);
|
||||
},
|
||||
'cancelSelector': selector,
|
||||
'nonvisualText': "this step"
|
||||
'nonvisualText': state.action
|
||||
});
|
||||
|
||||
state.$el.find('[type=submit]').after($cancel);
|
||||
@@ -140,8 +175,7 @@
|
||||
this.currentState = 'nothing-selected-buttons';
|
||||
this.templateFolderCheckboxChanged();
|
||||
if (targetSelector) {
|
||||
let setFocus = this.getFocusRoutine(targetSelector, false);
|
||||
setFocus();
|
||||
$(targetSelector).focus();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -240,6 +274,7 @@
|
||||
this.render = function() {
|
||||
let mode = 'default';
|
||||
let currentStateObj = this.states.filter(state => { return (state.key === this.currentState); })[0];
|
||||
let scrollTop;
|
||||
|
||||
// detach everything, unless they are the currentState
|
||||
this.states.forEach(
|
||||
@@ -254,14 +289,20 @@
|
||||
// make sticky JS recalculate its cache of the element's position
|
||||
GOVUK.stickAtBottomWhenScrolling.recalculate();
|
||||
|
||||
if (currentStateObj && ('setFocus' in currentStateObj)) { currentStateObj.setFocus(); }
|
||||
if (currentStateObj && ('setFocus' in currentStateObj)) {
|
||||
scrollTop = $(window).scrollTop();
|
||||
currentStateObj.setFocus();
|
||||
$(window).scrollTop(scrollTop);
|
||||
}
|
||||
};
|
||||
|
||||
this.nothingSelectedButtons = $(`
|
||||
<div id="nothing_selected">
|
||||
<div class="js-stick-at-bottom-when-scrolling">
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-right-3 govuk-!-margin-bottom-1" value="add-new-template">New template</button>
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-bottom-1" value="add-new-folder">New folder</button>
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-right-3 govuk-!-margin-bottom-1" value="add-new-template" aria-expanded="false">
|
||||
New template
|
||||
</button>
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-bottom-1" value="add-new-folder" aria-expanded="false">New folder</button>
|
||||
<div class="template-list-selected-counter">
|
||||
<span class="template-list-selected-counter__count" aria-hidden="true">
|
||||
${this.selectionStatus.default}
|
||||
@@ -274,10 +315,10 @@
|
||||
this.itemsSelectedButtons = $(`
|
||||
<div id="items_selected">
|
||||
<div class="js-stick-at-bottom-when-scrolling">
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-right-3 govuk-!-margin-bottom-1" value="move-to-existing-folder">
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-right-3 govuk-!-margin-bottom-1" value="move-to-existing-folder" aria-expanded="false">
|
||||
Move<span class="govuk-visually-hidden"> selection to folder</span>
|
||||
</button>
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-bottom-1" value="move-to-new-folder">Add to new folder</button>
|
||||
<button class="govuk-button govuk-button--secondary govuk-!-margin-bottom-1" value="move-to-new-folder" aria-expanded="false">Add to new folder</button>
|
||||
<div class="template-list-selected-counter" aria-hidden="true">
|
||||
<span class="template-list-selected-counter__count" aria-hidden="true">
|
||||
${this.selectionStatus.selected(1)}
|
||||
|
||||
@@ -176,6 +176,17 @@ $message-type-bottom-spacing: govuk-spacing(4);
|
||||
|
||||
}
|
||||
|
||||
.sticky-template-form {
|
||||
|
||||
padding: govuk-spacing(3);
|
||||
margin: govuk-spacing(3) * -1;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.folder-heading {
|
||||
|
||||
.govuk-grid-row & {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<button type="submit" name="operation" value="unknown" hidden></button>
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||
{% if templates_and_folders_form.move_to.choices and template_list.templates_to_show %}
|
||||
<div id="move_to_folder_radios">
|
||||
<div id="move_to_folder_radios" class="sticky-template-form" role="region" aria-label="Choose the folder to move selected items to">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
{{ radios_nested(templates_and_folders_form.move_to, move_to_children, option_hints=option_hints) }}
|
||||
</div>
|
||||
@@ -13,22 +13,20 @@
|
||||
{{ page_footer('Move', button_name='operation', button_value='move-to-existing-folder', button_text_hidden_suffix=' selection to folder') }}
|
||||
</div>
|
||||
</div>
|
||||
<div id="move_to_new_folder_form">
|
||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
||||
<legend class="govuk-visually-hidden">Add to new folder</legend>
|
||||
<div id="move_to_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder to move selected items to">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
{{ templates_and_folders_form.move_to_new_folder_name(param_extensions={"classes": "govuk-!-width-full"}) }}
|
||||
{{ page_footer('Add to new folder', button_name='operation', button_value='move-to-new-folder') }}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div id="add_new_folder_form">
|
||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
||||
<legend class="govuk-visually-hidden">Add new folder</legend>
|
||||
<div id="add_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
{{ templates_and_folders_form.add_new_folder_name(param_extensions={"classes": "govuk-!-width-full"}) }}
|
||||
{{ page_footer('Add new folder', button_name='operation', button_value='add-new-folder') }}
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div id="add_new_template_form" {% if single_notification_channel %}data-channel="{{single_notification_channel}}" data-service="{{current_service.id}}"{% endif %}>
|
||||
<div id="add_new_template_form" class="sticky-template-form" role="region" aria-label="Choose template type" {% if single_notification_channel %}data-channel="{{single_notification_channel}}" data-service="{{current_service.id}}"{% endif %}>
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
{{ radios(templates_and_folders_form.add_template_by_template_type) }}
|
||||
</div>
|
||||
|
||||
@@ -31,7 +31,7 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
||||
|
||||
return `<div id="sticky_template_forms">
|
||||
<button type="submit" name="operation" value="unknown" hidden=""></button>
|
||||
<div id="move_to_folder_radios">
|
||||
<div id="move_to_folder_radios" class="sticky-template-form" role="region" aria-label="Choose the folder to move selected items to">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
<div class="form-group ">
|
||||
<fieldset id="move_to">
|
||||
@@ -50,9 +50,8 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="move_to_new_folder_form">
|
||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
||||
<legend class="visuallyhidden">Add to new folder</legend>
|
||||
<div id="move_to_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder to move selected items to">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
<div class="govuk-form-group">
|
||||
<label class="govuk-label" for="move_to_new_folder_name">
|
||||
Folder name
|
||||
@@ -62,11 +61,10 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
||||
<div class="page-footer">
|
||||
<button type="submit" class="govuk-button govuk-button--secondary govuk-!-margin-bottom-1" name="operation" value="move-to-new-folder">Add to new folder</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div id="add_new_folder_form">
|
||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
||||
<legend class="visuallyhidden">Add new folder</legend>
|
||||
<div id="add_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder">
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
<div class="govuk-form-group">
|
||||
<label class="govuk-label" for="add_new_folder_name">
|
||||
Folder name
|
||||
@@ -76,9 +74,9 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
||||
<div class="page-footer">
|
||||
<button type="submit" class="govuk-button page-footer__button" name="operation" value="add-new-folder">Add new folder</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
<div id="add_new_template_form" ${newTemplateDataModules}>
|
||||
<div id="add_new_template_form" class="sticky-template-form" role="region" aria-label="Choose template type" ${newTemplateDataModules}>
|
||||
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||
<div class="form-group ">
|
||||
<fieldset id="add_template_by_template_type">
|
||||
@@ -141,10 +139,16 @@ function resetStickyMocks () {
|
||||
|
||||
beforeAll(() => {
|
||||
require('../../app/assets/javascripts/templateFolderForm.js');
|
||||
|
||||
// plug JSDOM's lack of support for window.scrollTo
|
||||
window.scrollTo = () => {};
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
require('./support/teardown.js');
|
||||
|
||||
// tidy up
|
||||
delete window.scrollTo;
|
||||
});
|
||||
|
||||
describe('TemplateFolderForm', () => {
|
||||
@@ -227,7 +231,7 @@ describe('TemplateFolderForm', () => {
|
||||
return formControls.querySelector('[role=status]');
|
||||
};
|
||||
|
||||
describe("Before the page loads", () => {
|
||||
describe("Before the module starts", () => {
|
||||
|
||||
// We need parts of the module to be made sticky, but by the module code,
|
||||
// not the sticky JS code that operates on the HTML at page load.
|
||||
@@ -243,7 +247,7 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
});
|
||||
|
||||
describe("When the page loads", () => {
|
||||
describe("When the module starts", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
@@ -261,6 +265,8 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
expect(document.querySelector('button[value=add-new-template]')).not.toBeNull();
|
||||
expect(document.querySelector('button[value=add-new-folder]')).not.toBeNull();
|
||||
expect(document.querySelector('button[value=add-new-template]').getAttribute('aria-expanded')).toEqual('false');
|
||||
expect(document.querySelector('button[value=add-new-folder]').getAttribute('aria-expanded')).toEqual('false');
|
||||
expect(visibleCounter).not.toBeNull();
|
||||
|
||||
});
|
||||
@@ -358,38 +364,60 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
afterEach(() => resetStickyMocks());
|
||||
|
||||
test("should show options for all the types of template", () => {
|
||||
describe("Should show a region", () => {
|
||||
|
||||
const options = [
|
||||
'Email', 'Text message', 'Letter', 'Copy an existing template'
|
||||
];
|
||||
test("with options for all the types of template", () => {
|
||||
|
||||
const labels = Array.from(formControls.querySelectorAll('label'));
|
||||
const radios = Array.from(formControls.querySelectorAll('input[type=radio]'));
|
||||
const options = [
|
||||
'Email', 'Text message', 'Letter', 'Copy an existing template'
|
||||
];
|
||||
|
||||
options.forEach(option => {
|
||||
let matchingLabels = labels.filter(label => label.textContent.trim() === option);
|
||||
const labels = Array.from(formControls.querySelectorAll('label'));
|
||||
const radios = Array.from(formControls.querySelectorAll('input[type=radio]'));
|
||||
|
||||
expect(matchingLabels.length > 0).toBe(true);
|
||||
options.forEach(option => {
|
||||
let matchingLabels = labels.filter(label => label.textContent.trim() === option);
|
||||
|
||||
let matchingRadio = formControls.querySelector(`#${matchingLabels[0].getAttribute('for')}`)
|
||||
expect(matchingLabels.length > 0).toBe(true);
|
||||
|
||||
let matchingRadio = formControls.querySelector(`#${matchingLabels[0].getAttribute('for')}`)
|
||||
|
||||
expect(matchingRadio).not.toBeNull();
|
||||
});
|
||||
|
||||
expect(matchingRadio).not.toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
test("with a 'Cancel' link", () => {
|
||||
|
||||
test("should show a 'Cancel' link", () => {
|
||||
const cancelLink = formControls.querySelector('.js-cancel');
|
||||
|
||||
const cancelLink = formControls.querySelector('.js-cancel');
|
||||
expect(cancelLink).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('new template');
|
||||
|
||||
expect(cancelLink).not.toBeNull();
|
||||
});
|
||||
|
||||
});
|
||||
test("with an accessible role, name and description", () => {
|
||||
|
||||
test("should focus the fieldset", () => {
|
||||
let id, description;
|
||||
const region = document.querySelector('#add_new_template_form');
|
||||
expect(region.hasAttribute('role')).toBe(true);
|
||||
expect(region.getAttribute('role')).toEqual('region');
|
||||
expect(region.hasAttribute('aria-label')).toBe(true);
|
||||
expect(region.getAttribute('aria-label')).toEqual('Choose template type');
|
||||
expect(region.hasAttribute('aria-describedby')).toBe(true);
|
||||
id = region.getAttribute('aria-describedby');
|
||||
description = document.getElementById(id);
|
||||
expect(description).not.toBeNull();
|
||||
expect(description.textContent.trim()).toEqual('Press continue to confirm selection or cancel to close');
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('fieldset'));
|
||||
});
|
||||
|
||||
test("and focus it", () => {
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('#add_new_template_form'));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -460,18 +488,48 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
});
|
||||
|
||||
test("should show a textbox for the folder name", () => {
|
||||
describe("should show a parent region", () => {
|
||||
|
||||
expect(textbox).not.toBeNull();
|
||||
test("with an accessible role, name and description", () => {
|
||||
|
||||
// check textbox has a label
|
||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||
let id, description;
|
||||
const region = document.querySelector('#add_new_folder_form');
|
||||
expect(region.hasAttribute('role')).toBe(true);
|
||||
expect(region.getAttribute('role')).toEqual('region');
|
||||
expect(region.hasAttribute('aria-label')).toBe(true);
|
||||
expect(region.getAttribute('aria-label')).toEqual('Enter name of the new folder');
|
||||
expect(region.hasAttribute('aria-describedby')).toBe(true);
|
||||
id = region.getAttribute('aria-describedby');
|
||||
description = document.getElementById(id);
|
||||
expect(description).not.toBeNull();
|
||||
expect(description.textContent.trim()).toEqual('Press add new folder to confirm name or cancel to close');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test("should focus the textbox", () => {
|
||||
test("with a textbox for the folder name", () => {
|
||||
|
||||
expect(document.activeElement).toBe(textbox);
|
||||
expect(textbox).not.toBeNull();
|
||||
|
||||
// check textbox has a label
|
||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||
|
||||
});
|
||||
|
||||
test("with a 'Cancel' link", () => {
|
||||
|
||||
const cancelLink = formControls.querySelector('.js-cancel');
|
||||
|
||||
expect(cancelLink).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('new folder');
|
||||
|
||||
});
|
||||
|
||||
test("and focus it", () => {
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('#add_new_folder_form'));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -544,6 +602,8 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
expect(formControls.querySelector('button[value=move-to-new-folder]')).not.toBeNull();
|
||||
expect(formControls.querySelector('button[value=move-to-existing-folder]')).not.toBeNull();
|
||||
expect(formControls.querySelector('button[value=move-to-new-folder]').getAttribute('aria-expanded')).toEqual('false');
|
||||
expect(formControls.querySelector('button[value=move-to-existing-folder]').getAttribute('aria-expanded')).toEqual('false');
|
||||
|
||||
});
|
||||
|
||||
@@ -627,41 +687,71 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
});
|
||||
|
||||
test("should show radios for all the folders in the hierarchy", () => {
|
||||
describe("Should show a region", () => {
|
||||
|
||||
const foldersInHierarchy = [];
|
||||
test("with an accessible role, name and description", () => {
|
||||
|
||||
function getFolders (nodes) {
|
||||
let id, description;
|
||||
const region = document.querySelector('#move_to_folder_radios');
|
||||
expect(region.hasAttribute('role')).toBe(true);
|
||||
expect(region.getAttribute('role')).toEqual('region');
|
||||
expect(region.hasAttribute('aria-label')).toBe(true);
|
||||
expect(region.getAttribute('aria-label')).toEqual('Choose the folder to move selected items to');
|
||||
expect(region.hasAttribute('aria-describedby')).toBe(true);
|
||||
id = region.getAttribute('aria-describedby');
|
||||
description = document.getElementById(id);
|
||||
expect(description).not.toBeNull();
|
||||
expect(description.textContent.trim()).toEqual('Press move to confirm or cancel to close');
|
||||
|
||||
nodes.forEach(node => {
|
||||
if (node.type === 'folder') {
|
||||
});
|
||||
|
||||
foldersInHierarchy.push(node.label);
|
||||
if (node.children.length) { getFolders(node.children) }
|
||||
test("with radios for all the folders in the hierarchy", () => {
|
||||
|
||||
}
|
||||
});
|
||||
const foldersInHierarchy = [];
|
||||
|
||||
};
|
||||
function getFolders (nodes) {
|
||||
|
||||
getFolders(hierarchy);
|
||||
nodes.forEach(node => {
|
||||
if (node.type === 'folder') {
|
||||
|
||||
const folderLabels = Array.from(formControls.querySelectorAll('#move_to label'))
|
||||
.filter(label => label.textContent.trim() !== 'Templates');
|
||||
foldersInHierarchy.push(node.label);
|
||||
if (node.children.length) { getFolders(node.children) }
|
||||
|
||||
expect(folderLabels.map(label => label.textContent.trim())).toEqual(foldersInHierarchy);
|
||||
}
|
||||
});
|
||||
|
||||
const radiosForLabels = folderLabels
|
||||
.map(label => formControls.querySelector(`#${label.getAttribute('for')}`))
|
||||
.filter(radio => radio !== null);
|
||||
};
|
||||
|
||||
expect(radiosForLabels.length).toEqual(foldersInHierarchy.length);
|
||||
getFolders(hierarchy);
|
||||
|
||||
});
|
||||
const folderLabels = Array.from(formControls.querySelectorAll('#move_to label'))
|
||||
.filter(label => label.textContent.trim() !== 'Templates');
|
||||
|
||||
test("focus the 'Choose a folder' fieldset", () => {
|
||||
expect(folderLabels.map(label => label.textContent.trim())).toEqual(foldersInHierarchy);
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('#move_to'));
|
||||
const radiosForLabels = folderLabels
|
||||
.map(label => formControls.querySelector(`#${label.getAttribute('for')}`))
|
||||
.filter(radio => radio !== null);
|
||||
|
||||
expect(radiosForLabels.length).toEqual(foldersInHierarchy.length);
|
||||
|
||||
});
|
||||
|
||||
test("with a 'Cancel' link", () => {
|
||||
|
||||
const cancelLink = formControls.querySelector('.js-cancel');
|
||||
|
||||
expect(cancelLink).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('move to folder');
|
||||
|
||||
});
|
||||
|
||||
test("and focus it", () => {
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('#move_to_folder_radios'));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -722,18 +812,48 @@ describe('TemplateFolderForm', () => {
|
||||
|
||||
});
|
||||
|
||||
test("should show a textbox for the folder name", () => {
|
||||
describe("Should show a region", () => {
|
||||
|
||||
expect(textbox).not.toBeNull();
|
||||
test("with an accessible role, name and description", () => {
|
||||
|
||||
// check textbox has a label
|
||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||
let id, description;
|
||||
const region = document.querySelector('#move_to_new_folder_form');
|
||||
expect(region.hasAttribute('role')).toBe(true);
|
||||
expect(region.getAttribute('role')).toEqual('region');
|
||||
expect(region.hasAttribute('aria-label')).toBe(true);
|
||||
expect(region.getAttribute('aria-label')).toEqual('Enter name of the new folder to move selected items to');
|
||||
expect(region.hasAttribute('aria-describedby')).toBe(true);
|
||||
id = region.getAttribute('aria-describedby');
|
||||
description = document.getElementById(id);
|
||||
expect(description).not.toBeNull();
|
||||
expect(description.textContent.trim()).toEqual('Press add to new folder to confirm name or cancel to close');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
test("should focus the textbox", () => {
|
||||
test("with a textbox for the folder name", () => {
|
||||
|
||||
expect(document.activeElement).toBe(textbox);
|
||||
expect(textbox).not.toBeNull();
|
||||
|
||||
// check textbox has a label
|
||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||
|
||||
});
|
||||
|
||||
test("with a 'Cancel' link", () => {
|
||||
|
||||
const cancelLink = formControls.querySelector('.js-cancel');
|
||||
|
||||
expect(cancelLink).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('move to new folder');
|
||||
|
||||
});
|
||||
|
||||
test("and focus it", () => {
|
||||
|
||||
expect(document.activeElement).toBe(formControls.querySelector('#move_to_new_folder_form'));
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user