2019-08-16 18:32:16 +01:00
const helpers = require ( './support/helpers.js' );
beforeAll (() => {
2019-10-16 15:20:05 +01:00
require ( '../../app/assets/javascripts/enhancedTextbox.js' );
2019-08-16 18:32:16 +01:00
});
afterAll (() => {
require ( './support/teardown.js' );
});
2019-10-16 15:20:05 +01:00
describe ( 'Enhanced textbox' , () => {
2019-08-16 18:32:16 +01:00
let input ;
let textarea ;
let backgroundEl ;
2022-10-27 11:12:39 -04:00
const stylesheet = document . createElement ( 'style' );
2019-08-16 18:32:16 +01:00
beforeAll (() => {
// set some default styling
stylesheet . innerHTML = ".textbox-highlight-textbox { padding: 2px; width: 576px; border-width: 1px; }" ;
stylesheet . innerHTML += "textarea.textbox-highlight-textbox { height: 224px; }" ;
document . getElementsByTagName ( 'head' )[ 0 ]. appendChild ( stylesheet );
});
afterAll (() => {
stylesheet . parentNode . removeChild ( stylesheet );
});
beforeEach (() => {
// set up DOM
document . body . innerHTML = `
<div class="form-group">
<label for="subject">Subject</label>
2019-10-16 15:20:05 +01:00
<input class="form-control textbox-highlight-textbox" data-module="enhanced-textbox" type="text" name="subject" id="subject" />
2019-08-16 18:32:16 +01:00
</div>
<div class="form-group">
<label for="template_content">Message</label>
2019-10-16 15:20:05 +01:00
<textarea class="form-control form-control-1-1 textbox-highlight-textbox" data-module="enhanced-textbox" id="template_content" name="template_content" rows="8">
2019-08-16 18:32:16 +01:00
</textarea>
</div>` ;
input = document . querySelector ( 'input' );
textarea = document . querySelector ( 'textarea' );
});
afterEach (() => {
document . body . innerHTML = '' ;
});
describe ( "When the page loads" , () => {
describe ( "An element should be added as a layer below the textbox to hold the highlights" , () => {
beforeEach (() => {
// start module
window . GOVUK . modules . start ();
});
test ( "If the textbox is a <textarea>" , () => {
backgroundEl = textarea . nextElementSibling ;
// both the textbox and the element behind need a wrapping element
expect ( textarea . parentNode . classList . contains ( 'textbox-highlight-wrapper' )). toBe ( true );
expect ( backgroundEl ). not . toBeNull ();
expect ( backgroundEl . classList . contains ( 'textbox-highlight-background' )). toBe ( true );
});
test ( "If the textbox is an <input>" , () => {
backgroundEl = input . nextElementSibling ;
// both the textbox and the element behind need a wrapping element
expect ( input . parentNode . classList . contains ( 'textbox-highlight-wrapper' )). toBe ( true );
expect ( backgroundEl ). not . toBeNull ();
expect ( backgroundEl . classList . contains ( 'textbox-highlight-background' )). toBe ( true );
});
});
describe ( "The element's dimensions and border-width should match those of the textbox" , () => {
beforeEach (() => {
// start module
window . GOVUK . modules . start ();
});
test ( "If the textbox is an <textarea>" , () => {
backgroundEl = textarea . nextElementSibling ;
2020-03-05 15:44:31 +00:00
expect ( backgroundEl . style . width ). toEqual ( '576px' );
2019-08-16 18:32:16 +01:00
expect ( backgroundEl . style . borderWidth ). toEqual ( '1px' );
});
test ( "If the textbox is an <input>" , () => {
backgroundEl = input . nextElementSibling ;
2020-03-05 15:44:31 +00:00
expect ( backgroundEl . style . width ). toEqual ( '576px' );
2019-08-16 18:32:16 +01:00
expect ( backgroundEl . style . borderWidth ). toEqual ( '1px' );
});
});
2019-10-16 14:35:18 +01:00
describe ( "The element's width should match even when the textbox is initially hidden" , () => {
beforeEach (() => {
let setDisplayPropertyOfFormGroups = function ( property ) {
Array . prototype . forEach . call (
document . getElementsByClassName ( 'form-group' ),
element => element . style . display = property
);
};
setDisplayPropertyOfFormGroups ( 'none' );
window . GOVUK . modules . start ();
setDisplayPropertyOfFormGroups ( 'block' );
});
test ( "If the textbox is an <textarea>" , () => {
backgroundEl = textarea . nextElementSibling ;
2020-03-05 15:44:31 +00:00
expect ( backgroundEl . style . width ). toEqual ( '576px' );
2019-10-16 14:35:18 +01:00
});
});
2019-08-16 18:32:16 +01:00
test ( "The element should be hidden from assistive technologies" , () => {
expect ( backgroundEl . getAttribute ( 'aria-hidden' )). toEqual ( 'true' );
});
describe ( "If there is a variable in the content, its matching text in the element below should be wrapped in a highlight tag" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = "Dear ((title)) ((name))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((title))' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((name))' );
});
test ( "If the textbox is a <input>" , () => {
input . value = "Dear ((title)) ((name))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((title))' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((name))' );
});
2019-10-16 14:35:18 +01:00
test ( "Unless a data attribute is set to turn this feature off" , () => {
textarea . textContent = "Dear ((title)) ((name))" ;
textarea . setAttribute ( 'data-highlight-placeholders' , 'false' )
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 0 );
});
2019-08-16 18:32:16 +01:00
});
describe ( "If there is optional text in the content, its matching text in the element below should be wrapped in a highlight tag" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = "When you arrive, please go to the ((weekday??main entrance))((weekend??side entrance))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((weekday??' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((weekend??' );
});
test ( "If the textbox is an <input>" , () => {
input . value = "When you arrive, please go to the ((weekday??main entrance))((weekend??side entrance))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((weekday??' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((weekend??' );
});
});
});
describe ( "When the content of the textbox is updated" , () => {
// doesn't apply to inputs as they have a fixed height
2020-03-05 15:44:31 +00:00
test ( "If new input changes the textarea's height, the height of the element below should still match" , () => {
2019-08-16 18:32:16 +01:00
// set 10 lines of content
textarea . textContent = `
Ref: ((reference))
Date: ((date))
NHS number: ((nhs_number))
Dear ((name))
Thank you for attending the appointment on ((appointment_date)).
We will now pass on the results to your GP, ((doctor)), who will be in contact with you soon to arrange a follow up appointment.
` ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
// add another line of text to the content
textarea . textContent += "Best Regards\n\n((requester))" ;
// mock calls for the background element's current height
jest . spyOn ( backgroundEl , 'offsetHeight' , 'get' ). mockImplementation (() => 248 );
helpers . triggerEvent ( textarea , 'input' );
expect ( window . getComputedStyle ( textarea ). height ). toEqual ( "248px" );
});
2020-03-05 15:44:31 +00:00
test ( "If a resize changes the textarea's width, the width of the element below should still match" , () => {
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
expect ( window . getComputedStyle ( textarea ). width ). toEqual ( "576px" );
expect ( window . getComputedStyle ( backgroundEl ). width ). toEqual ( "576px" );
textarea . style . width = "500px"
helpers . triggerEvent ( window , 'resize' );
expect ( window . getComputedStyle ( textarea ). width ). toEqual ( "500px" );
expect ( window . getComputedStyle ( backgroundEl ). width ). toEqual ( "500px" );
});
2019-08-16 18:32:16 +01:00
describe ( "If a new variable is added to the textbox, it should also be added to the element below in a highlight tag" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = "Dear ((title)) ((name))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
// add some more content with a new variable
textarea . textContent += "\nRef: ((reference))" ;
helpers . triggerEvent ( textarea , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 3 );
expect ( highlightTags [ 2 ]. textContent ). toEqual ( '((reference))' );
});
test ( "If the textbox is an <input>" , () => {
input . value = "Hospital appointment for ((name))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
// add some more content with a new variable
input . value += ", ref: ((reference))" ;
helpers . triggerEvent ( input , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((name))' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((reference))' );
});
});
describe ( "If a new piece of optional text is added to the textbox, it should also be added to the element below in a highlight tag" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = "Dear ((title)) ((name))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
// add some more content with some optional content inside
textarea . textContent += "\nYour appointment will be on ((date)). When you arrive, please go to the ((weekday??main entrance))((weekend??side entrance))" ;
helpers . triggerEvent ( textarea , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
const optionalHighlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( highlightTags . length ). toEqual ( 3 );
expect ( optionalHighlightTags . length ). toEqual ( 2 );
expect ( optionalHighlightTags [ 0 ]. textContent ). toEqual ( '((weekday??' );
expect ( optionalHighlightTags [ 1 ]. textContent ). toEqual ( '((weekend??' );
});
test ( "If the textbox is an <input>" , () => {
input . value = "Hospital appointment" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
// add some more content with some optional content inside
input . value += "((important?? - IMPORTANT))" ;
helpers . triggerEvent ( input , 'input' );
const optionalHighlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( optionalHighlightTags . length ). toEqual ( 1 );
expect ( optionalHighlightTags [ 0 ]. textContent ). toEqual ( '((important??' );
});
});
describe ( "If a variable is removed from the textbox, its highlight should also be removed" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = `
Dear ((title)) ((name))
Ref: ((reference))` ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
// add some more content with a new variable
textarea . textContent = "Dear ((title)) ((name))" ;
helpers . triggerEvent ( textarea , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 2 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((title))' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((name))' );
});
test ( "If the textbox is an <input>" , () => {
input . value = "Hospital appointment for ((name)), ref: ((reference))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
// add some more content with a new variable
input . value = "Hospital appointment for ((name))" ;
helpers . triggerEvent ( input , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
expect ( highlightTags . length ). toEqual ( 1 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((name))' );
});
});
describe ( "If a piece of optional text has been removed from the textbox, its highlight should also be removed" , () => {
test ( "If the textbox is a <textarea>" , () => {
textarea . textContent = `
Dear ((title)) ((name))
Your appointment will be on ((date)). When you arrive, please go to the ((weekday??main entrance))((weekend??side entrance)).` ;
// start module
window . GOVUK . modules . start ();
backgroundEl = textarea . nextElementSibling ;
// add some more content with a new variable
textarea . textContent = `
Dear ((title)) ((name))
Your appointment will be on ((date)). When you arrive, please go to the ((weekday??main entrance))` ;
helpers . triggerEvent ( textarea , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
const optionalHighlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( highlightTags . length ). toEqual ( 3 );
expect ( optionalHighlightTags . length ). toEqual ( 1 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((title))' );
expect ( highlightTags [ 1 ]. textContent ). toEqual ( '((name))' );
expect ( optionalHighlightTags [ 0 ]. textContent ). toEqual ( '((weekday??' );
expect ( highlightTags [ 2 ]. textContent ). toEqual ( '((date))' );
});
test ( "If the textbox is an <input>" , () => {
input . value = "Hospital appointment for ((name))((important?? - IMPORTANT))" ;
// start module
window . GOVUK . modules . start ();
backgroundEl = input . nextElementSibling ;
// add some more content with a new variable
input . value = "Hospital appointment for ((name))"
helpers . triggerEvent ( input , 'input' );
const highlightTags = backgroundEl . querySelectorAll ( '.placeholder' );
const optionalHighlightTags = backgroundEl . querySelectorAll ( '.placeholder-conditional' );
expect ( highlightTags . length ). toEqual ( 1 );
expect ( optionalHighlightTags . length ). toEqual ( 0 );
expect ( highlightTags [ 0 ]. textContent ). toEqual ( '((name))' );
});
});
});
});