mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 07:46:23 -04:00
Make footer popup forms groups & add labelling
The existing behaviour focused the form control for each popup (radios or textbox) when opened. This gives no indication the submit button or cancel link have been added to the page. These changes: - make the parent element a region to group all the new content - label the region to link it to the button that opened it - add a description to the region so users know how to use it and that all the controls have been added to the page
This commit is contained in:
@@ -17,18 +17,59 @@
|
|||||||
|
|
||||||
// all the diff states that we want to show or hide
|
// all the diff states that we want to show or hide
|
||||||
this.states = [
|
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: 'nothing-selected-buttons',
|
||||||
{key: 'move-to-existing-folder', $el: this.$form.find('#move_to_folder_radios'), cancellable: true, setFocus: this.getFocusRoutine('#move_to_folder_radios fieldset', true), action: 'move to folder'},
|
$el: this.$form.find('#nothing_selected'),
|
||||||
{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), action: 'move to new folder'},
|
cancellable: false
|
||||||
{key: 'add-new-folder', $el: this.$form.find('#add_new_folder_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_folder_name', false), action: 'new folder'},
|
},
|
||||||
{key: 'add-new-template', $el: this.$form.find('#add_new_template_form'), cancellable: true, setFocus: this.getFocusRoutine('#add_new_template_form fieldset', true), action: 'new template'}
|
{
|
||||||
|
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
|
// 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.cancellable).forEach((x) => this.addCancelButton(x));
|
||||||
this.states.filter(state => state.key === 'items-selected-buttons').forEach(x => this.addClearButton(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
|
// activate stickiness of elements in each state
|
||||||
this.activateStickyElements();
|
this.activateStickyElements();
|
||||||
|
|
||||||
@@ -45,22 +86,16 @@
|
|||||||
this.$form.on('change', 'input[type=checkbox]', () => this.templateFolderCheckboxChanged());
|
this.$form.on('change', 'input[type=checkbox]', () => this.templateFolderCheckboxChanged());
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getFocusRoutine = function (selector, setTabindex) {
|
this.addDescriptionsToStates = function () {
|
||||||
return function () {
|
let id, description;
|
||||||
let $el = $(selector);
|
|
||||||
let removeTabindex = (e) => {
|
|
||||||
$(e.target)
|
|
||||||
.removeAttr('tabindex')
|
|
||||||
.off('blur', removeTabindex);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (setTabindex) {
|
$.each(this.states.filter(state => 'description' in state), (idx, state) => {
|
||||||
$el.attr('tabindex', '-1');
|
id = `${state.key}__description`;
|
||||||
$el.on('blur', removeTabindex);
|
description = `<p class="govuk-visually-hidden" id="${id}">${state.description}</p>`;
|
||||||
}
|
state.$el
|
||||||
|
.prepend(description)
|
||||||
$el.focus();
|
.attr('aria-describedby', id);
|
||||||
};
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.activateStickyElements = function() {
|
this.activateStickyElements = function() {
|
||||||
@@ -140,8 +175,7 @@
|
|||||||
this.currentState = 'nothing-selected-buttons';
|
this.currentState = 'nothing-selected-buttons';
|
||||||
this.templateFolderCheckboxChanged();
|
this.templateFolderCheckboxChanged();
|
||||||
if (targetSelector) {
|
if (targetSelector) {
|
||||||
let setFocus = this.getFocusRoutine(targetSelector, false);
|
$(targetSelector).focus();
|
||||||
setFocus();
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -240,6 +274,7 @@
|
|||||||
this.render = function() {
|
this.render = function() {
|
||||||
let mode = 'default';
|
let mode = 'default';
|
||||||
let currentStateObj = this.states.filter(state => { return (state.key === this.currentState); })[0];
|
let currentStateObj = this.states.filter(state => { return (state.key === this.currentState); })[0];
|
||||||
|
let scrollTop;
|
||||||
|
|
||||||
// detach everything, unless they are the currentState
|
// detach everything, unless they are the currentState
|
||||||
this.states.forEach(
|
this.states.forEach(
|
||||||
@@ -254,7 +289,11 @@
|
|||||||
// make sticky JS recalculate its cache of the element's position
|
// make sticky JS recalculate its cache of the element's position
|
||||||
GOVUK.stickAtBottomWhenScrolling.recalculate();
|
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 = $(`
|
this.nothingSelectedButtons = $(`
|
||||||
|
|||||||
@@ -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 {
|
.folder-heading {
|
||||||
|
|
||||||
.govuk-grid-row & {
|
.govuk-grid-row & {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<button type="submit" name="operation" value="unknown" hidden></button>
|
<button type="submit" name="operation" value="unknown" hidden></button>
|
||||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
|
||||||
{% if templates_and_folders_form.move_to.choices and template_list.templates_to_show %}
|
{% 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">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
{{ radios_nested(templates_and_folders_form.move_to, move_to_children, option_hints=option_hints) }}
|
{{ radios_nested(templates_and_folders_form.move_to, move_to_children, option_hints=option_hints) }}
|
||||||
</div>
|
</div>
|
||||||
@@ -13,22 +13,20 @@
|
|||||||
{{ page_footer('Move', button_name='operation', button_value='move-to-existing-folder', button_text_hidden_suffix=' selection to folder') }}
|
{{ page_footer('Move', button_name='operation', button_value='move-to-existing-folder', button_text_hidden_suffix=' selection to folder') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="move_to_new_folder_form">
|
<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">
|
||||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
<legend class="govuk-visually-hidden">Add to new folder</legend>
|
|
||||||
{{ templates_and_folders_form.move_to_new_folder_name(param_extensions={"classes": "govuk-!-width-full"}) }}
|
{{ 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') }}
|
{{ page_footer('Add to new folder', button_name='operation', button_value='move-to-new-folder') }}
|
||||||
</fieldset>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="add_new_folder_form">
|
<div id="add_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder">
|
||||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
<legend class="govuk-visually-hidden">Add new folder</legend>
|
|
||||||
{{ templates_and_folders_form.add_new_folder_name(param_extensions={"classes": "govuk-!-width-full"}) }}
|
{{ 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') }}
|
{{ page_footer('Add new folder', button_name='operation', button_value='add-new-folder') }}
|
||||||
</fieldset>
|
</div>
|
||||||
</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">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
{{ radios(templates_and_folders_form.add_template_by_template_type) }}
|
{{ radios(templates_and_folders_form.add_template_by_template_type) }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
|||||||
|
|
||||||
return `<div id="sticky_template_forms">
|
return `<div id="sticky_template_forms">
|
||||||
<button type="submit" name="operation" value="unknown" hidden=""></button>
|
<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="js-will-stick-at-bottom-when-scrolling">
|
||||||
<div class="form-group ">
|
<div class="form-group ">
|
||||||
<fieldset id="move_to">
|
<fieldset id="move_to">
|
||||||
@@ -50,9 +50,8 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="move_to_new_folder_form">
|
<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">
|
||||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
<legend class="visuallyhidden">Add to new folder</legend>
|
|
||||||
<div class="govuk-form-group">
|
<div class="govuk-form-group">
|
||||||
<label class="govuk-label" for="move_to_new_folder_name">
|
<label class="govuk-label" for="move_to_new_folder_name">
|
||||||
Folder name
|
Folder name
|
||||||
@@ -62,11 +61,10 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
|||||||
<div class="page-footer">
|
<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>
|
<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>
|
</div>
|
||||||
</fieldset>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="add_new_folder_form">
|
<div id="add_new_folder_form" class="sticky-template-form" role="region" aria-label="Enter name of the new folder">
|
||||||
<fieldset class="js-will-stick-at-bottom-when-scrolling">
|
<div class="js-will-stick-at-bottom-when-scrolling">
|
||||||
<legend class="visuallyhidden">Add new folder</legend>
|
|
||||||
<div class="govuk-form-group">
|
<div class="govuk-form-group">
|
||||||
<label class="govuk-label" for="add_new_folder_name">
|
<label class="govuk-label" for="add_new_folder_name">
|
||||||
Folder name
|
Folder name
|
||||||
@@ -76,9 +74,9 @@ function setFixtures (hierarchy, newTemplateDataModules = "") {
|
|||||||
<div class="page-footer">
|
<div class="page-footer">
|
||||||
<button type="submit" class="govuk-button page-footer__button" name="operation" value="add-new-folder">Add new folder</button>
|
<button type="submit" class="govuk-button page-footer__button" name="operation" value="add-new-folder">Add new folder</button>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</div>
|
||||||
</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="js-will-stick-at-bottom-when-scrolling">
|
||||||
<div class="form-group ">
|
<div class="form-group ">
|
||||||
<fieldset id="add_template_by_template_type">
|
<fieldset id="add_template_by_template_type">
|
||||||
@@ -141,10 +139,16 @@ function resetStickyMocks () {
|
|||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
require('../../app/assets/javascripts/templateFolderForm.js');
|
require('../../app/assets/javascripts/templateFolderForm.js');
|
||||||
|
|
||||||
|
// plug JSDOM's lack of support for window.scrollTo
|
||||||
|
window.scrollTo = () => {};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(() => {
|
afterAll(() => {
|
||||||
require('./support/teardown.js');
|
require('./support/teardown.js');
|
||||||
|
|
||||||
|
// tidy up
|
||||||
|
delete window.scrollTo;
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('TemplateFolderForm', () => {
|
describe('TemplateFolderForm', () => {
|
||||||
@@ -227,7 +231,7 @@ describe('TemplateFolderForm', () => {
|
|||||||
return formControls.querySelector('[role=status]');
|
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,
|
// 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.
|
// 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(() => {
|
beforeEach(() => {
|
||||||
|
|
||||||
@@ -360,40 +364,60 @@ describe('TemplateFolderForm', () => {
|
|||||||
|
|
||||||
afterEach(() => resetStickyMocks());
|
afterEach(() => resetStickyMocks());
|
||||||
|
|
||||||
test("should show options for all the types of template", () => {
|
describe("Should show a region", () => {
|
||||||
|
|
||||||
const options = [
|
test("with options for all the types of template", () => {
|
||||||
'Email', 'Text message', 'Letter', 'Copy an existing template'
|
|
||||||
];
|
|
||||||
|
|
||||||
const labels = Array.from(formControls.querySelectorAll('label'));
|
const options = [
|
||||||
const radios = Array.from(formControls.querySelectorAll('input[type=radio]'));
|
'Email', 'Text message', 'Letter', 'Copy an existing template'
|
||||||
|
];
|
||||||
|
|
||||||
options.forEach(option => {
|
const labels = Array.from(formControls.querySelectorAll('label'));
|
||||||
let matchingLabels = labels.filter(label => label.textContent.trim() === option);
|
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();
|
});
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('new template');
|
|
||||||
|
|
||||||
});
|
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'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -464,28 +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
|
let id, description;
|
||||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
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 show a 'Cancel' link", () => {
|
test("with a textbox for the folder name", () => {
|
||||||
|
|
||||||
const cancelLink = formControls.querySelector('.js-cancel');
|
expect(textbox).not.toBeNull();
|
||||||
|
|
||||||
expect(cancelLink).not.toBeNull();
|
// check textbox has a label
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('new folder');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should focus the textbox", () => {
|
test("with a 'Cancel' link", () => {
|
||||||
|
|
||||||
expect(document.activeElement).toBe(textbox);
|
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'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -643,51 +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);
|
test("with radios for all the folders in the hierarchy", () => {
|
||||||
if (node.children.length) { getFolders(node.children) }
|
|
||||||
|
|
||||||
}
|
const foldersInHierarchy = [];
|
||||||
});
|
|
||||||
|
|
||||||
};
|
function getFolders (nodes) {
|
||||||
|
|
||||||
getFolders(hierarchy);
|
nodes.forEach(node => {
|
||||||
|
if (node.type === 'folder') {
|
||||||
|
|
||||||
const folderLabels = Array.from(formControls.querySelectorAll('#move_to label'))
|
foldersInHierarchy.push(node.label);
|
||||||
.filter(label => label.textContent.trim() !== 'Templates');
|
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("should show a 'Cancel' link", () => {
|
expect(folderLabels.map(label => label.textContent.trim())).toEqual(foldersInHierarchy);
|
||||||
|
|
||||||
const cancelLink = formControls.querySelector('.js-cancel');
|
const radiosForLabels = folderLabels
|
||||||
|
.map(label => formControls.querySelector(`#${label.getAttribute('for')}`))
|
||||||
|
.filter(radio => radio !== null);
|
||||||
|
|
||||||
expect(cancelLink).not.toBeNull();
|
expect(radiosForLabels.length).toEqual(foldersInHierarchy.length);
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('move to folder');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("focus the 'Choose a folder' fieldset", () => {
|
test("with a 'Cancel' link", () => {
|
||||||
|
|
||||||
expect(document.activeElement).toBe(formControls.querySelector('#move_to'));
|
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'));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -748,28 +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
|
let id, description;
|
||||||
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
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 show a 'Cancel' link", () => {
|
test("with a textbox for the folder name", () => {
|
||||||
|
|
||||||
const cancelLink = formControls.querySelector('.js-cancel');
|
expect(textbox).not.toBeNull();
|
||||||
|
|
||||||
expect(cancelLink).not.toBeNull();
|
// check textbox has a label
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden')).not.toBeNull();
|
expect(formControls.querySelector(`label[for=${textbox.getAttribute('id')}]`)).not.toBeNull();
|
||||||
expect(cancelLink.querySelector('.govuk-visually-hidden').textContent.trim()).toEqual('move to new folder');
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should focus the textbox", () => {
|
test("with a 'Cancel' link", () => {
|
||||||
|
|
||||||
expect(document.activeElement).toBe(textbox);
|
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