Skip to content

Commit

Permalink
PLATUI-3352: add initial failing acceptance tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oscarduignan committed Dec 19, 2024
1 parent 0a490d5 commit 2bf9f07
Show file tree
Hide file tree
Showing 4 changed files with 482 additions and 5 deletions.
2 changes: 2 additions & 0 deletions lib/browser-tests/puppeteer-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export function withHmrcStylesAndScripts(body) {
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link rel="stylesheet" href="/assets/hmrc-frontend-${version}.min.css">
<link rel="stylesheet" href="/assets/accessible-autocomplete-${version}.css">
${preloadGovukFonts}
</head>
<body class="govuk-template__body">
Expand All @@ -49,6 +50,7 @@ export function withHmrcStylesAndScripts(body) {
</script>
${body}
<script src="/assets/hmrc-frontend-${version}.min.js" type="module"></script>
<script src="/assets/accessible-autocomplete-${version}.js" type="module"></script>
</body>
</html>
`;
Expand Down
21 changes: 16 additions & 5 deletions lib/jest-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ nunjucks.configure(
* @param {string} componentName
* @param {string} params parameters that are used in the component macro
* @param {any} children any child components or text, pass the children to the macro
* @returns {function} returns cheerio (jQuery) instance of the macro for easy DOM querying
* @returns {string} returns html
*/
function render(componentName, params, children = false) {
function renderString(componentName, params, children = false) {
if (typeof params === 'undefined') {
throw new Error('Parameters passed to `render` should be an object but are undefined');
}
Expand All @@ -42,9 +42,18 @@ function render(componentName, params, children = false) {
macroString += `{{- ${macroName}(${macroParams}) -}}`;
}

const output = nunjucks.renderString(macroString);
return nunjucks.renderString(macroString);
}

return cheerio.load(output);
/**
* Render a component's macro for testing
* @param {string} componentName
* @param {string} params parameters that are used in the component macro
* @param {any} children any child components or text, pass the children to the macro
* @returns {function} returns cheerio (jQuery) instance of the macro for easy DOM querying
*/
function render(componentName, params, children = false) {
return cheerio.load(renderString(componentName, params, children));
}

/**
Expand Down Expand Up @@ -87,4 +96,6 @@ function htmlWithClassName($, className) {
return $.html($component);
}

module.exports = { render, getExamples, htmlWithClassName };
module.exports = {
renderString, render, getExamples, htmlWithClassName,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// Copied from https://gist.github.com/adamliptrot-oc/f7cbb92f040082cc17cff27416ae348b
// Not intended for use by teams, fixes for the following are now built into hmrc-frontend
// This is included here for use during automated testing to check that our fixes don't
// conflict with the polyfill if teams are still using it when they upgrade to a new version
// of hmrc-frontend which has the fixes built in.
// ---------------------------

// Note - updated to work with the HMRC Frontend implementation
// https://github.com/hmrc/play-frontend-hmrc#adding-accessible-autocomplete-css-and-javascript

if (typeof HMRCAccessibleAutocomplete != 'undefined' && document.querySelector('[data-module="hmrc-accessible-autocomplete"]') != null) {
var originalSelect = document.querySelector('[data-module="hmrc-accessible-autocomplete"]');
// load autocomplete - now handled by the HMRC component wrapper in Twirl
// accessibleAutocomplete.enhanceSelectElement({
// selectElement: originalSelect,
// showAllValues: true
// });

// =====================================================
// Polyfill autocomplete once loaded
// =====================================================
var checkForLoad = setInterval(checkForAutocompleteLoad, 50);
var parentForm = upTo(originalSelect, 'form');

function polyfillAutocomplete(){
var combo = parentForm.querySelector('[role="combobox"]');

// =====================================================
// Update autocomplete once loaded with fallback's aria attributes
// Ensures hint and error are read out before usage instructions
// =====================================================
if(originalSelect && originalSelect.getAttribute('aria-describedby') > ""){
if(parentForm){
if(combo){
combo.setAttribute('aria-describedby', originalSelect.getAttribute('aria-describedby') + ' ' + combo.getAttribute('aria-describedby'));
}
}
}
// =====================================================
// Update autocomplete once loaded with error styling if needed
// This won't work if the autocomplete css is loaded after the frontend library css because
// the autocomplete's border will override the error class's border (they are both the same specificity)
// but we can use the class assigned to build a more specific rule
// =====================================================
setErrorClass();
function setErrorClass(){
if(originalSelect && originalSelect.classList.contains("govuk-select--error")){
if(parentForm){
if(combo){
combo.classList.add("govuk-input--error");
// Also set up an event listener to check for changes to input so we know when to repeat the copy
combo.addEventListener('focus', function(){setErrorClass()});
combo.addEventListener('blur', function(){setErrorClass()});
combo.addEventListener('change', function(){setErrorClass()});
}
}
}
}

// =====================================================
// Ensure when user replaces valid answer with a non-valid answer, then valid answer is not retained
// =====================================================
var holdSubmit = true;
parentForm.addEventListener('submit', function(e){
if(holdSubmit){
e.preventDefault()
if(originalSelect.querySelectorAll('[selected]').length > 0 || originalSelect.value > ""){

var resetSelect = false;

if(originalSelect.value){
if(combo.value != originalSelect.querySelector('option[value="' + originalSelect.value +'"]').text){
resetSelect = true;
}
}
if(resetSelect){
originalSelect.value = "";
if(originalSelect.querySelectorAll('[selected]').length > 0){
originalSelect.querySelectorAll('[selected]')[0].removeAttribute('selected');
}
}
}

holdSubmit = false;
//parentForm.submit();
HTMLFormElement.prototype.submit.call(parentForm); // because submit buttons have id of "submit" which masks the form's natural form.submit() function
}
})

}
function checkForAutocompleteLoad(){
if(parentForm.querySelector('[role="combobox"]')){
clearInterval(checkForLoad)
polyfillAutocomplete();
}
}


}


// Find first ancestor of el with tagName
// or undefined if not found
function upTo(el, tagName) {
tagName = tagName.toLowerCase();

while (el && el.parentNode) {
el = el.parentNode;
if (el.tagName && el.tagName.toLowerCase() == tagName) {
return el;
}
}

// Many DOM methods return null if they don't
// find the element they are searching for
// It would be OK to omit the following and just
// return undefined
return null;
}
Loading

0 comments on commit 2bf9f07

Please sign in to comment.