As part of transition to Vue 3.0 and Vite (#230), this commit facilitates the shift towards building rest of the application using Vite. By doing so, it eliminates reliance on outdated Electron building system that offered limited control, blocking desktop builds (#233). Changes include: - Introduce Vite with Vue 2.0 plugin for test execution. - Remove `mocha`, `chai` and other related dependencies. - Adjust test to Vitest syntax. - Revise and update `tests.md` to document the changes. - Add `@modyfi/vite-plugin-yaml` plugin to be able to use yaml file depended logic on test files, replacing previous webpack behavior. - Fix failing tests that are revealed by Vitest due to unhandled errors and lack of assertments. - Remove the test that depends on Vue CLI populating `process.env`. - Use `jsdom` for unit test environment, adding it to dependency to `package.json` as project now depends on it and it was not specified even though `package-lock.json` included it.
164 lines
4.4 KiB
TypeScript
164 lines
4.4 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { ref, nextTick } from 'vue';
|
|
import { useCurrentFocusToggle } from '@/presentation/components/Shared/Modal/Hooks/UseCurrentFocusToggle';
|
|
|
|
describe('useCurrentFocusToggle', () => {
|
|
describe('initialization', () => {
|
|
it('blurs active element when initialized with disabled focus', async () => {
|
|
// arrange
|
|
const shouldDisableFocus = ref(true);
|
|
const testElement = createElementInBody('input');
|
|
testElement.focus();
|
|
|
|
// act
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(testElement));
|
|
});
|
|
it('doesn\'t blur active element when initialized with enabled focus', async () => {
|
|
// arrange
|
|
const isCurrentFocusDisabled = ref(false);
|
|
const testElement = createElementInBody('input');
|
|
|
|
// act
|
|
testElement.focus();
|
|
useCurrentFocusToggle(isCurrentFocusDisabled);
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(isFocused(testElement));
|
|
});
|
|
});
|
|
|
|
describe('focus toggling', () => {
|
|
it('blurs when focus disabled programmatically', async () => {
|
|
// arrange
|
|
const shouldDisableFocus = ref(false);
|
|
const testElement = createElementInBody('input');
|
|
testElement.focus();
|
|
|
|
// act
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(testElement));
|
|
});
|
|
|
|
it('restores focus when re-enabled', async () => {
|
|
// arrange
|
|
const isCurrentFocusDisabled = ref(true);
|
|
const testElement = createElementInBody('input');
|
|
|
|
// act
|
|
useCurrentFocusToggle(isCurrentFocusDisabled);
|
|
testElement.focus();
|
|
isCurrentFocusDisabled.value = true;
|
|
await nextTick();
|
|
isCurrentFocusDisabled.value = false;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(isFocused(testElement));
|
|
});
|
|
|
|
it('maintains focus if not disabled', async () => {
|
|
// arrange
|
|
const isCurrentFocusDisabled = ref(false);
|
|
const testElement = createElementInBody('input');
|
|
|
|
// act
|
|
testElement.focus();
|
|
useCurrentFocusToggle(isCurrentFocusDisabled);
|
|
isCurrentFocusDisabled.value = false;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(isFocused(testElement));
|
|
});
|
|
|
|
it('handles multiple toggles correctly', async () => {
|
|
// arrange
|
|
const shouldDisableFocus = ref(false);
|
|
const testElement = createElementInBody('input');
|
|
testElement.focus();
|
|
|
|
// act
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
shouldDisableFocus.value = false;
|
|
await nextTick();
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(testElement));
|
|
});
|
|
});
|
|
|
|
describe('document.body handling', () => {
|
|
it('blurs body when focus is disabled while body is active', async () => {
|
|
// arrange
|
|
document.body.focus();
|
|
|
|
const shouldDisableFocus = ref(false);
|
|
|
|
// act
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(document.body));
|
|
});
|
|
|
|
it('doesn\'t restore focus to document body once focus is re-enabled', async () => {
|
|
// arrange
|
|
document.body.focus();
|
|
|
|
const shouldDisableFocus = ref(false);
|
|
|
|
// act
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
shouldDisableFocus.value = false;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(document.body));
|
|
});
|
|
});
|
|
|
|
it('handles removal of a previously focused element gracefully', async () => {
|
|
// arrange
|
|
const shouldDisableFocus = ref(true);
|
|
const testElement = createElementInBody('input');
|
|
testElement.focus();
|
|
|
|
useCurrentFocusToggle(shouldDisableFocus);
|
|
shouldDisableFocus.value = true;
|
|
await nextTick();
|
|
testElement.remove();
|
|
shouldDisableFocus.value = false;
|
|
await nextTick();
|
|
|
|
// assert
|
|
expect(!isFocused(testElement));
|
|
});
|
|
|
|
function createElementInBody(tagName: keyof HTMLElementTagNameMap): HTMLElement {
|
|
const element = document.createElement(tagName);
|
|
document.body.appendChild(element);
|
|
return element;
|
|
}
|
|
});
|
|
|
|
function isFocused(element: HTMLElement): boolean {
|
|
return document.activeElement === element;
|
|
}
|