JSDOM doesn't implement the submit method on form
elements. It does have a submit method but this
just fires a 'not implemented' error.
We need to spy on form submissions fired by
clicking on the submit button but can't because
this event calls the submit method internally so
spying on `form.submit` doesn't work.
This adds a helper which spies on the internal
method that is actually called. When JSDOM
implements the submit method properly this should
be removed.
If focus moves to a textarea, we care more about
the caret being overlapped than the textarea.
This adds tests for the caret being overlapped on
load and as a result of it moving underneath the
sticky element from a keyboard event.
If an element receives focus when underneath a
stick element, the window should scroll so the
focused element is revealed.
Includes some changes to the WindowMock API to
allow access to data from Jest spies.
A 'shim' element needs to be added to the page
when an element is made sticky to ensure the
vertical position of everything doesn't change.
When an element becomes sticky it is made
`position: fixed` which removes it from the layout
of the page. The 'shim' is an element added at the
same place in the page with the same dimensions,
so the layout isn't changed.
Errors fired from JSDOM showed it doesn't support
`window.scrollTo` (or `window.scroll` for that
matter).
This stubs it, to the extent that our use (jQuery
really) of it works.
'dialog' mode was introduced as part of this work:
https://github.com/alphagov/notifications-admin/pull/2682
It lets multiple elements sticky to the viewport
together so a set of UI can be present for a set
scrolling range. It's called a 'dialog' because
the behaviour is closest to that of a modal
dialog.
This includes the following fixes:
1. fix error in `WindowMock.setWidthTo`
It was returning height, not width.
2. Fix for `WindowMock.reset`
Changes to the scroll position need to go
through the `scrollTo` method.
It also includes the following changes
1. Improve mocking of window scrollTop
Increases the number of DOM API methods mocked
to return the intended scrollTop value.
2. Change WindowMock.scrollBy to
WindowMock.scrollTo
Because you're not scrolling by an amount,
you're scrolling to a position.
3. Give WindowMock getters for position/dimension
It's useful to be able to get the
position/dimension of the window in tests when
you're resizing and scrolling it as part of the
test.
4. Assign WindowMock spies on instantiation
Assigning them whenever a dimension is set doesn't
make sense. You're just setting a value, not
changing how that value is accessed.
The button shouldn't change its vertical position
when the state changes. The text confirming the
copy is just one line so setting height for both
based on the API key, which can run to 2 lines
makes sense.
Explained in this PR:
https://github.com/alphagov/notifications-admin/pull/2428
To add the text from an element to the clipboard
you need to:
1. get the current Selection
1. create a Range from the contents of the element
2. clear any existing Ranges from the Selection
and add the new Range to the selection
3. execute the 'copy' command
To track calls to all the DOM APIs involved in
this we need mocks for Range and Selection.
Range:
https://developer.mozilla.org/en-US/docs/Web/API/Range
Selection:
https://developer.mozilla.org/en-US/docs/Web/API/Selection
Also includes a base class to help building out
Web API interface mocks.
This module creates a clone of the existing table
as an extra layer which sits on top of it.
This allows the row headers to sit above the table
content when it scrolls.
We were setting `role=presentation` on the extra
table to hide it from assistive technologies.
It seems that this wasn't working. From the spec'
`role-presentation` should remove the semantics of
the table but leave the content.
Testing in Safari, with the OSX Accessibility
Inspector, this isn't happening and the table is
still being reported as a table by the
accessibility API.
This changes to the `aria-hidden` attribute, to
make sure the extra table is ignored.
Keyboard users select a time slot by moving to the
radio for that slot, using the arrow keys, and
selecting it by pressing 'space' or 'enter', like
a `<select>`.
We allow this by listening for 'keydown' events
from the 'enter' or 'space' keys on time slot
radios that are checked.
Browsers fire 'click' events alongside the
'keydown' event meaning it's possible for the
code that makes the selection to be run twice.
We currently guard against this by checking for
the `pageX` property of the event object,
reasoning that a click event fired by a key press
won't have a cursor position.
Most browsers we support set it to `0` but it
isn't always the case:
https://dom-event-test.glitch.me/results.html
For those browsers, the `!event.pageX` condition
resolves correctly so this works. Safari and
versions of Internet Explorer before 11 however,
set it to a positive number.
In those browsers, moving the selection between
radios using the arrow keys fired a 'click' event
which, in Safari and IE<11, was treated as a
mouse/touch event and so confirmed the selection.
This made it impossible to select a later time.
These changes replace the 'click' event on time
slots with an artifical one that tracks
mouse/trackpad clicks by listening for a
'mousedown' followed by a 'mouseup' on a time
slot. This doesn't fire on key presses so avoids
the problem.
Extends triggerEvent, allowing the creation of
different types of event, and to change the data
on its object. Also fakes the positional data
browsers add to the event object.
Also adds helpers for simulating:
- all the events for a mouse click
- the events invovled in moving the selection in a radio group