/* global jest, global */
// Custom visibility check for the tests because the of because the elements do
// not have offsetWidth or offsetHeight during the tests which are checked
// against to see whether the element is visible or not. This is also how jQuery
// behaves internally.
const isElementVisible = (element) => {
const display = global.window.getComputedStyle(element).display;
return ["inline", "block", "inline-block"].includes(display);
}
// Mock jQuery because the visibility indicator works differently within jest.
// This fixes jQuery reporting $(".element").is(":visible") correctly during the
// tests and within foundation, too.
jest.mock("jquery", () => {
const jq = jest.requireActual("jquery");
jq.expr.pseudos.visible = isElementVisible;
return jq;
});
import $ from "jquery"; // eslint-disable-line id-length
import "foundation-sites";
import FocusGuard from "./focus_guard.js";
import dialogMode from "./dialog_mode.js";
describe("dialogMode", () => {
const content = `
Testing modal
Here is some content within the modal.
Other testing modal
Here is some content within the other modal.
`;
window.focusGuard = new FocusGuard(document.body);
// Mock the isVisible element because the default visibility check does not
// work during the tests.
jest.spyOn(window.focusGuard, "isVisible").mockImplementation(isElementVisible);
beforeEach(() => {
$("body").html(content);
$(document).foundation();
// Make sure all reveals are hidden by default so that their visibility is
// correctly reported always.
$(".reveal").css("display", "none");
$(document).on("open.zf.reveal", (ev) => {
dialogMode($(ev.target));
});
});
it("focuses the title", () => {
$("#test-modal").foundation("open");
const $focused = $(document.activeElement);
expect($focused.is($("#test-modal-label"))).toBe(true);
});
it("adds the tab guads on both sides of the document", () => {
$("#test-modal").foundation("open");
const $first = $("body *:first");
const $last = $("body *:last");
expect($first[0].outerHTML).toEqual(
''
);
expect($last[0].outerHTML).toEqual(
''
);
});
it("removes the tab guards when the modal is closed", () => {
const $modal = $("#test-modal");
$modal.foundation("open");
$modal.foundation("close");
expect($(".focusguard").length).toEqual(0);
});
it("focuses the first focusable element when the start tab guard gets focus", () => {
const $modal = $("#test-modal");
$modal.foundation("open");
$(".focusguard[data-position='start']").trigger("focus");
const $focused = $(document.activeElement);
expect($focused.is($("#test-modal .close-button"))).toBe(true);
});
it("focuses the last focusable element when the end tab guard gets focus", () => {
const $modal = $("#test-modal");
$modal.foundation("open");
$(".focusguard[data-position='end']").trigger("focus");
const $focused = $(document.activeElement);
expect($focused.is($("#test-modal-button"))).toBe(true);
});
describe("when multiple modals are opened", () => {
it("adds the tab guads only once", () => {
$("#test-modal").foundation("open");
$("#test-modal-2").foundation("open");
expect($(".focusguard[data-position='start']").length).toEqual(1);
expect($(".focusguard[data-position='end']").length).toEqual(1);
});
it("does not remove the tab guards when modal is closed but there is still another modal open", () => {
$("#test-modal").foundation("open");
$("#test-modal-2").foundation("open");
$("#test-modal-2").foundation("close");
expect($(".focusguard[data-position='start']").length).toEqual(1);
expect($(".focusguard[data-position='end']").length).toEqual(1);
});
it("removes the tab guards when the last modal is closed", () => {
$("#test-modal").foundation("open");
$("#test-modal-2").foundation("open");
$("#test-modal-2").foundation("close");
$("#test-modal").foundation("close");
expect($(".focusguard").length).toEqual(0);
});
describe("within the active modal", () => {
beforeEach(() => {
$("#test-modal").foundation("open");
$("#test-modal-2").foundation("open");
});
it("focuses the first focusable element when the start tab guard gets focus", () => {
$(".focusguard[data-position='start']").trigger("focus");
const $focused = $(document.activeElement);
expect($focused.is($("#test-modal-2 .close-button"))).toBe(true);
});
it("focuses the last focusable element when the end tab guard gets focus", () => {
$(".focusguard[data-position='end']").trigger("focus");
const $focused = $(document.activeElement);
expect($focused.is($("#test-modal-2-button"))).toBe(true);
});
});
});
});