mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-02-06 03:13:42 -05:00
Add tests for full-screen table module
This commit is contained in:
committed by
Chris Hill-Scott
parent
cb63d44c08
commit
435334ba9c
370
tests/javascripts/fullscreenTable.test.js
Normal file
370
tests/javascripts/fullscreenTable.test.js
Normal file
@@ -0,0 +1,370 @@
|
||||
const helpers = require('./support/helpers');
|
||||
|
||||
beforeAll(() => {
|
||||
// set up jQuery
|
||||
window.jQuery = require('jquery');
|
||||
$ = window.jQuery;
|
||||
|
||||
// load module code
|
||||
require('govuk_frontend_toolkit/javascripts/govuk/modules.js');
|
||||
require('../../app/assets/javascripts/fullscreenTable.js');
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
window.jQuery = null;
|
||||
$ = null;
|
||||
|
||||
delete window.GOVUK;
|
||||
});
|
||||
|
||||
describe('FullscreenTable', () => {
|
||||
let container;
|
||||
let tableFrame;
|
||||
let table;
|
||||
let numberColumnFrame;
|
||||
|
||||
function setWindowHeightTo (height) {
|
||||
|
||||
// mock DOM calls for window height
|
||||
window.innerHeight = height;
|
||||
// remove calls to document.documentElement.clientHeight when jQuery is gone. It's called to support older browsers like IE8
|
||||
jest.spyOn(document.documentElement, 'clientHeight', 'get').mockImplementation(() => height);
|
||||
|
||||
};
|
||||
|
||||
function setWindowWidthTo (width) {
|
||||
|
||||
// mock DOM calls for window width
|
||||
window.innerWidth = width;
|
||||
// remove calls to document.documentElement.clientWidth when jQuery is gone. It's called to support older browsers like IE8
|
||||
jest.spyOn(document.documentElement, 'clientWidth', 'get').mockImplementation(() => height);
|
||||
|
||||
};
|
||||
|
||||
function resizeWindowTo (dimensions) {
|
||||
|
||||
setWindowHeightTo(dimensions.height);
|
||||
setWindowWidthTo(dimensions.width);
|
||||
helpers.triggerEvent(window, 'resize');
|
||||
|
||||
};
|
||||
|
||||
function scrollWindowBy (scrollTop) {
|
||||
|
||||
document.documentElement.scrollTop = scrollTop;
|
||||
helpers.triggerEvent(window, 'scroll');
|
||||
|
||||
};
|
||||
|
||||
function resetWindowDimensions () {
|
||||
|
||||
setWindowHeightTo(768);
|
||||
setWindowWidthTo(1024);
|
||||
|
||||
};
|
||||
|
||||
function setElementDimensionsAndOffset (el, opts) {
|
||||
|
||||
const elOffsetSpy = jest.spyOn(el, 'getBoundingClientRect');
|
||||
|
||||
if (opts.height) {
|
||||
el.setAttribute('style', `height: ${opts.height}px`);
|
||||
}
|
||||
|
||||
if (opts.width) {
|
||||
el.setAttribute('style', `width: ${opts.width}px`);
|
||||
}
|
||||
|
||||
if (opts.offset) {
|
||||
elOffsetSpy.mockImplementation(() => opts.offset);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
function setElementWidth (el, width) {
|
||||
|
||||
el.setAttribute('style', `.width: ${width}px`);
|
||||
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
const tableHeadings = () => {
|
||||
let result = '';
|
||||
const headings = ['1', 'name', 'email address', 'age', 'building number', 'address line 1', 'address line 2', 'postcode'];
|
||||
|
||||
headings.forEach((heading, idx) => {
|
||||
if (idx === 0) {
|
||||
result += `<th scope="col" class="table-field-heading-first">
|
||||
<span class="visually-hidden">Row in file</span><span aria-hidden="true" class="table-field-invisible-error">${heading}</span>
|
||||
</th>`;
|
||||
} else {
|
||||
result += `<th scope="col" class="table-field-heading">
|
||||
${heading}
|
||||
</th>`;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const rowCells = (cells) => {
|
||||
let result = '';
|
||||
|
||||
Object.keys(cells).forEach((key, idx) => {
|
||||
if (idx === 0) {
|
||||
result += `<td class="table-field-index">
|
||||
<span class="table-field-error">
|
||||
${key}
|
||||
</span>
|
||||
</td>`;
|
||||
} else {
|
||||
result += `<td class="table-field-left-aligned ">
|
||||
<div class="table-field-status-default">
|
||||
${key}
|
||||
</div>
|
||||
</td>`;
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
const tableRows = () => {
|
||||
let result = '';
|
||||
|
||||
const rows = [
|
||||
['John Logie Baird', 'johnlbaird@gmail.com', '37', '22', 'Frith Street', 'Soho, London', 'W1D 4RF'],
|
||||
['Guglielmo Marconi', 'gmarconi@hotmail.com', '21', 'Pontecchio Marconi', 'Via Celestini 1', 'Bologna', ''],
|
||||
['Louis Braille', 'louisbraille@yahoo.co.uk', '', '56', 'Boulevard des Invalides', 'Paris', '75007'],
|
||||
['Ray Tomlinson', 'hedy.lamarr@msn.com', '25', '870', '870 Winter Street', 'Waltham', 'MA 02451']
|
||||
];
|
||||
|
||||
rows.forEach(row => {
|
||||
result += `<tr class="table-row">${rowCells(row)}</tr>`;
|
||||
});
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
// set up DOM
|
||||
document.body.innerHTML =
|
||||
`<main>
|
||||
<div class="fullscreen-content" data-module="fullscreen-table">
|
||||
<table class="table table-font-xsmall">
|
||||
<caption class="heading-medium table-heading visuallyhidden">
|
||||
people.csv
|
||||
</caption>
|
||||
<thead class="table-field-headings-visible">
|
||||
<tr>
|
||||
${tableHeadings()}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${tableRows()}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>`;
|
||||
|
||||
container = document.querySelector('.fullscreen-content');
|
||||
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
document.body.innerHTML = '';
|
||||
|
||||
});
|
||||
|
||||
describe("when it loads", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
// start module
|
||||
window.GOVUK.modules.start();
|
||||
|
||||
});
|
||||
|
||||
test("it fixes the number column for each row without changing the semantics", () => {
|
||||
|
||||
tableFrame = document.querySelector('.fullscreen-scrollable-table');
|
||||
numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
|
||||
|
||||
expect(tableFrame).not.toBeNull();
|
||||
expect(numberColumnFrame).not.toBeNull();
|
||||
expect(numberColumnFrame.getAttribute('role')).toEqual('presentation');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("the height of the table should fit the vertical space available to it", () => {
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
// set the height and offset of the window and table container from the top of the document
|
||||
// so just the top 268px of it appears on-screen
|
||||
setWindowHeightTo(768);
|
||||
setElementDimensionsAndOffset(container, { height: 1000, offset: { top: 500 } });
|
||||
|
||||
// start module
|
||||
window.GOVUK.modules.start();
|
||||
|
||||
tableFrame = document.querySelector('.fullscreen-scrollable-table');
|
||||
numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
|
||||
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
jest.clearAllMocks();
|
||||
resetWindowDimensions();
|
||||
scrollWindowBy(0);
|
||||
|
||||
});
|
||||
|
||||
test("when the page has loaded", () => {
|
||||
|
||||
// the frames should crop to the top 268px of the table that is visible
|
||||
expect(window.getComputedStyle(tableFrame)['height']).toEqual('268px');
|
||||
expect(window.getComputedStyle(numberColumnFrame)['height']).toEqual('268px');
|
||||
|
||||
});
|
||||
|
||||
test("when the page has scrolled", () => {
|
||||
|
||||
// scroll the window so the table fills the height of the window (768px)
|
||||
scrollWindowBy(500);
|
||||
|
||||
// the frames should crop to the window height
|
||||
expect(window.getComputedStyle(tableFrame)['height']).toEqual('768px');
|
||||
expect(window.getComputedStyle(numberColumnFrame)['height']).toEqual('768px');
|
||||
|
||||
});
|
||||
|
||||
test("when the page has resized", () => {
|
||||
|
||||
// resize the window by 232px (from 768px to 1000px)
|
||||
resizeWindowTo({ height: 1000, width: 1024 });
|
||||
|
||||
// the frames should crop to the top 500px of the table now visible
|
||||
expect(window.getComputedStyle(tableFrame)['height']).toEqual('500px');
|
||||
expect(window.getComputedStyle(numberColumnFrame)['height']).toEqual('500px');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("the width of the table should fit the horizontal space available to it", () => {
|
||||
let rowNumberColumnCell;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
rowNumberColumnCell = container.querySelector('.table-field-index');
|
||||
|
||||
// set main content column width (used as module as gauge for table width)
|
||||
setWindowWidthTo(1024);
|
||||
document.querySelector('main').setAttribute('style', 'width: 742px');
|
||||
|
||||
// set total width of column for row numbers in table to 40px
|
||||
rowNumberColumnCell.setAttribute('style', 'width: 40px');
|
||||
|
||||
// start module
|
||||
window.GOVUK.modules.start();
|
||||
|
||||
tableFrame = document.querySelector('.fullscreen-scrollable-table');
|
||||
numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
|
||||
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
|
||||
jest.clearAllMocks();
|
||||
resetWindowDimensions();
|
||||
scrollWindowBy(0);
|
||||
|
||||
});
|
||||
|
||||
test("when the page has loaded", () => {
|
||||
|
||||
// table should set its width to be that of `<main>`, minus margin-left for the row numbers column
|
||||
expect(window.getComputedStyle(tableFrame)['width']).toEqual('702px'); // width of content column - numbers column
|
||||
expect(window.getComputedStyle(tableFrame)['margin-left']).toEqual('40px'); // width of numbers column
|
||||
|
||||
// table for number column has 4px extra to allow space for drop shadow
|
||||
expect(window.getComputedStyle(numberColumnFrame)['width']).toEqual('44px');
|
||||
|
||||
});
|
||||
|
||||
test("when the page has resized", () => {
|
||||
|
||||
// resize window and content column
|
||||
document.querySelector('main').setAttribute('style', 'width: 720px');
|
||||
resizeWindowTo({ height: 768, width: 960 });
|
||||
|
||||
// table should set its width to be that of `<main>`, minus margin-left for the row numbers column
|
||||
expect(window.getComputedStyle(tableFrame)['width']).toEqual('680px'); // width of content column - numbers column
|
||||
expect(window.getComputedStyle(tableFrame)['margin-left']).toEqual('40px'); // width of numbers column
|
||||
|
||||
// table for number column has 4px extra to allow space for drop shadow
|
||||
expect(window.getComputedStyle(numberColumnFrame)['width']).toEqual('44px');
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("when the table scrolls horizontally", () => {
|
||||
let rightEdgeShadow;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
// start module
|
||||
window.GOVUK.modules.start();
|
||||
|
||||
tableFrame = document.querySelector('.fullscreen-scrollable-table');
|
||||
table = tableFrame.querySelector('table');
|
||||
numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
|
||||
rightEdgeShadow = container.querySelector('.fullscreen-right-shadow');
|
||||
|
||||
tableFrame.setAttribute('style', 'width: 742px');
|
||||
table.setAttribute('style', 'width: 1000px');
|
||||
|
||||
});
|
||||
|
||||
test("the right edge of the table scroll area should have a drop-shadow if it isn't scrolled", () => {
|
||||
|
||||
tableFrame.scrollLeft = 0;
|
||||
helpers.triggerEvent(tableFrame, 'scroll');
|
||||
|
||||
expect(numberColumnFrame.classList.contains('fullscreen-scrolled-table')).toBe(false);
|
||||
expect(rightEdgeShadow.classList.contains('visible')).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
test("the left edge of the table scroll area should have a drop-shadow if the table is scrolled to 100%", () => {
|
||||
|
||||
// scroll to end of table
|
||||
tableFrame.scrollLeft = 258;
|
||||
helpers.triggerEvent(tableFrame, 'scroll');
|
||||
|
||||
expect(numberColumnFrame.classList.contains('fullscreen-scrolled-table')).toBe(true);
|
||||
expect(rightEdgeShadow.classList.contains('visible')).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
test("both edges of the table scroll area should have a drop-shadow if the table is scrolled between 0% and 100%", () => {
|
||||
|
||||
// scroll to middle of table
|
||||
tableFrame.scrollLeft = 129;
|
||||
helpers.triggerEvent(tableFrame, 'scroll');
|
||||
|
||||
expect(numberColumnFrame.classList.contains('fullscreen-scrolled-table')).toBe(true);
|
||||
expect(rightEdgeShadow.classList.contains('visible')).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user