{% call(item, row_number) list_table(
example,
caption="Example",
diff --git a/tests/javascripts/fullscreenTable.test.js b/tests/javascripts/fullscreenTable.test.js
index c8d89d962..45b76d4ee 100644
--- a/tests/javascripts/fullscreenTable.test.js
+++ b/tests/javascripts/fullscreenTable.test.js
@@ -1,370 +1,88 @@
-const helpers = require('./support/helpers');
+require('../../app/assets/javascripts/fullscreenTable.js');
-beforeAll(() => {
- // TODO: remove this when tests for sticky JS are written
- require('../../app/assets/javascripts/stick-to-window-when-scrolling.js');
+describe('fullscreenTable', () => {
+ let wrapper, rightShadow;
- require('../../app/assets/javascripts/fullscreenTable.js');
-});
-
-afterAll(() => {
- require('./support/teardown.js');
-});
-
-describe('FullscreenTable', () => {
- let screenMock;
- let container;
- let tableFrame;
- let table;
- let numberColumnFrame;
-
- 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 += `
- Row in file${heading}
- | `;
- } else {
- result += `
- ${heading}
- | `;
- }
- });
-
- return result;
- }
-
- const rowCells = (cells) => {
- let result = '';
-
- Object.keys(cells).forEach((key, idx) => {
- if (idx === 0) {
- result += `
-
- ${key}
-
- | `;
- } else {
- result += `
-
- ${key}
-
- | `;
- }
- });
-
- 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 += `
${rowCells(row)}
`;
- });
-
- return result;
-
- }
-
- screenMock = new helpers.ScreenMock(jest);
- screenMock.setWindow({
- width: 1990,
- height: 940,
- scrollTop: 0
- });
-
- // set up DOM
- document.body.innerHTML =
- `
-
-
-
- people.csv
-
-
-
- ${tableHeadings()}
-
-
-
- ${tableRows()}
-
+ const setupDOM = (scrollLeft = 0, scrollWidth = 1000, clientWidth = 500) => {
+ document.body.innerHTML = `
+
+ `;
- container = document.querySelector('.fullscreen-content');
+ wrapper = document.querySelector('.table-wrapper');
+ rightShadow = document.querySelector('.fullscreen-right-shadow');
- });
+ // Mock scroll values
+ Object.defineProperty(wrapper, 'scrollLeft', {
+ get: () => scrollLeft,
+ configurable: true
+ });
+ Object.defineProperty(wrapper, 'scrollWidth', {
+ get: () => scrollWidth,
+ configurable: true
+ });
+ Object.defineProperty(wrapper, 'clientWidth', {
+ get: () => clientWidth,
+ configurable: true
+ });
+
+ // 👇 Now that DOM is ready, initialize the logic
+ window.initFullscreenTables();
+
+ // Force trigger scroll event if needed
+ wrapper.dispatchEvent(new Event('scroll'));
+ };
afterEach(() => {
-
document.body.innerHTML = '';
-
});
- describe("when it loads", () => {
-
- test("it fixes the number column for each row without changing the semantics", () => {
-
- // start module
- window.GOVUK.modules.start();
-
- tableFrame = document.querySelector('.fullscreen-scrollable-table');
- numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
-
- expect(tableFrame).not.toBeNull();
- expect(numberColumnFrame).not.toBeNull();
- expect(numberColumnFrame.getAttribute('aria-hidden')).toEqual('true');
-
- });
-
- test("it calls the sticky JS to update any cached dimensions", () => {
-
- const stickyJSSpy = jest.spyOn(window.GOVUK.stickAtBottomWhenScrolling, 'recalculate');
-
- // start module
- window.GOVUK.modules.start();
-
- expect(stickyJSSpy.mock.calls.length).toBe(1);
-
- stickyJSSpy.mockClear();
-
- });
-
- test("the scrolling section is focusable and has an accessible name matching the table caption", () => {
-
- // start module
- window.GOVUK.modules.start();
-
- tableFrame = document.querySelector('.fullscreen-scrollable-table');
- caption = tableFrame.querySelector('caption');
-
- expect(tableFrame.hasAttribute('role')).toBe(true);
- expect(tableFrame.getAttribute('role')).toEqual('region');
- expect(tableFrame.hasAttribute('aria-labelledby')).toBe(true);
- expect(tableFrame.getAttribute('aria-labelledby')).toEqual(caption.getAttribute('id'));
-
- });
-
- test("the section providing the fixed row headers is not focusable and is hidden from assistive tech'", () => {
-
- // start module
- window.GOVUK.modules.start();
-
- fixedRowHeaders = document.querySelector('.fullscreen-fixed-table');
-
- expect(fixedRowHeaders.hasAttribute('role')).toBe(false);
- expect(fixedRowHeaders.hasAttribute('aria-labelledby')).toBe(false);
- expect(fixedRowHeaders.hasAttribute('tabindex')).toBe(false);
- expect(fixedRowHeaders.hasAttribute('aria-hidden')).toBe(true);
- expect(fixedRowHeaders.getAttribute('aria-hidden')).toEqual('true');
-
- });
-
+ test('adds right shadow on initial load if scrollable', () => {
+ setupDOM(0, 1000, 500);
+ expect(wrapper.classList.contains('scrolled')).toBe(false);
+ expect(rightShadow.classList.contains('visible')).toBe(true);
});
- describe("the height of the table should fit the vertical space available to it", () => {
-
- let containerBoundingClientRectSpy;
- let containerClientRectsSpy;
-
- 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
- screenMock.window.setHeightTo(768);
- screenMock.mockPositionAndDimension('container', container, {
- 'offsetHeight': 1000,
- 'offsetWidth': 641,
- 'offsetTop': 500
- });
-
- // start module
- window.GOVUK.modules.start();
-
- tableFrame = document.querySelector('.fullscreen-scrollable-table');
- numberColumnFrame = document.querySelector('.fullscreen-fixed-table');
-
- });
-
- afterEach(() => {
-
- screenMock.reset();
-
- });
-
- 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)
- screenMock.window.scrollTo(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)
- screenMock.window.resizeTo({ 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');
-
- });
-
+ test('hides right shadow when scrolled to max', () => {
+ setupDOM(500, 1000, 500);
+ expect(wrapper.classList.contains('scrolled')).toBe(true);
+ expect(rightShadow.classList.contains('visible')).toBe(false);
});
- 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)
- screenMock.window.setWidthTo(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(() => {
-
- screenMock.reset();
-
- });
-
- test("when the page has loaded", () => {
-
- // table should set its width to be that of ``, 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');
- screenMock.window.resizeTo({ height: 768, width: 960 });
-
- // table should set its width to be that of ``, 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');
-
- });
-
+ test('handles mid-scroll: left + right shadows active', () => {
+ setupDOM(250, 1000, 500);
+ expect(wrapper.classList.contains('scrolled')).toBe(true);
+ expect(rightShadow.classList.contains('visible')).toBe(true);
});
- describe("when the table scrolls horizontally", () => {
- let rightEdgeShadow;
+ test('gracefully handles missing right shadow', () => {
+ document.body.innerHTML = `
+
+ `;
- beforeEach(() => {
+ wrapper = document.querySelector('.table-wrapper');
- // start module
- window.GOVUK.modules.start();
+ Object.defineProperty(wrapper, 'scrollLeft', { get: () => 100, configurable: true });
+ Object.defineProperty(wrapper, 'scrollWidth', { get: () => 500, configurable: true });
+ Object.defineProperty(wrapper, 'clientWidth', { get: () => 200, configurable: true });
- 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);
-
- });
+ // 👇 Call after building DOM
+ window.initFullscreenTables();
+ wrapper.dispatchEvent(new Event('scroll'));
+ expect(wrapper.classList.contains('scrolled')).toBe(true);
+ // No error thrown for missing .fullscreen-right-shadow
});
-
- describe("when the table is focused", () => {
-
- beforeEach(() => {
-
- // start module
- window.GOVUK.modules.start();
-
- tableFrame = document.querySelector('.fullscreen-scrollable-table');
- tableFrame.focus();
-
- });
-
- test("it should make the parent frame a focus style", () => {
-
- expect(container.classList.contains('js-focus-style')).toBe(true);
-
- });
-
- });
-
});