detect-tab
Version:
A comprehensive tab detection and management library for web applications
158 lines (125 loc) • 4.21 kB
text/typescript
/**
* @jest-environment jsdom
*/
import { DetectTab } from './DetectTab';
import { TabState, TabEvent } from './types';
describe('DetectTab', () => {
let detectTab: DetectTab;
beforeEach(() => {
// Reset DOM state
Object.defineProperty(document, 'visibilityState', {
value: 'visible',
writable: true
});
Object.defineProperty(document, 'hidden', {
value: false,
writable: true
});
// Mock hasFocus
document.hasFocus = jest.fn(() => true);
});
afterEach(() => {
if (detectTab) {
detectTab.destroy();
}
jest.clearAllMocks();
});
describe('Constructor', () => {
it('should initialize with default options', () => {
detectTab = new DetectTab();
const info = detectTab.getTabInfo();
expect(info.state).toBe(TabState.VISIBLE);
expect(info.focused).toBe(true);
expect(info.visible).toBe(true);
expect(info.visibilityChanges).toBe(0);
});
it('should initialize with custom options', () => {
detectTab = new DetectTab({
autoStart: false,
debug: true,
debounceTime: 200
});
expect(detectTab).toBeDefined();
});
});
describe('State Management', () => {
beforeEach(() => {
detectTab = new DetectTab({ autoStart: false });
});
it('should detect visible state', () => {
expect(detectTab.isVisible()).toBe(true);
expect(detectTab.getState()).toBe(TabState.VISIBLE);
});
it('should track focus state', () => {
expect(detectTab.isFocused()).toBe(true);
});
});
describe('Event Listeners', () => {
beforeEach(() => {
detectTab = new DetectTab({ autoStart: false });
});
it('should add and remove event listeners', () => {
const callback = jest.fn();
detectTab.on(TabEvent.VISIBILITY_CHANGE, callback);
detectTab.off(TabEvent.VISIBILITY_CHANGE, callback);
expect(callback).not.toHaveBeenCalled();
});
it('should add state change listeners', () => {
const callback = jest.fn();
detectTab.onStateChange(callback);
detectTab.offStateChange(callback);
expect(callback).not.toHaveBeenCalled();
});
it('should add focus change listeners', () => {
const callback = jest.fn();
detectTab.onFocusChange(callback);
detectTab.offFocusChange(callback);
expect(callback).not.toHaveBeenCalled();
});
});
describe('Time Tracking', () => {
beforeEach(() => {
detectTab = new DetectTab({ autoStart: false });
});
it('should track time statistics', () => {
const info = detectTab.getTabInfo();
expect(info.timeInState).toBeGreaterThanOrEqual(0);
expect(info.totalVisibleTime).toBeGreaterThanOrEqual(0);
expect(info.totalHiddenTime).toBeGreaterThanOrEqual(0);
});
it('should format time statistics', () => {
const stats = detectTab.getTimeStats();
expect(stats.totalVisibleTime).toBeDefined();
expect(stats.totalHiddenTime).toBeDefined();
expect(stats.timeInCurrentState).toBeDefined();
});
});
describe('Utility Methods', () => {
beforeEach(() => {
detectTab = new DetectTab({ autoStart: false });
});
it('should reset statistics', () => {
detectTab.reset();
const info = detectTab.getTabInfo();
expect(info.totalVisibleTime).toBe(0);
expect(info.totalHiddenTime).toBe(0);
expect(info.visibilityChanges).toBe(0);
});
it('should start and stop detection', () => {
detectTab.start();
detectTab.stop();
expect(detectTab).toBeDefined();
});
it('should handle multiple start calls gracefully', () => {
detectTab.start();
detectTab.start();
expect(detectTab).toBeDefined();
});
it('should handle multiple stop calls gracefully', () => {
detectTab.start();
detectTab.stop();
detectTab.stop();
expect(detectTab).toBeDefined();
});
});
});