mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-05-28 17:55:55 +00:00
407 lines
No EOL
13 KiB
TypeScript
407 lines
No EOL
13 KiB
TypeScript
/**
|
|
* Tests for window event setup and lifecycle management in createWindow function
|
|
* Covers dev tools shortcuts, external link handling, before close handling,
|
|
* auto-update integration, webview manager, and file reader initialization
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'
|
|
import { setupMockEnvironment } from '../../../mocks/environmentMocks'
|
|
|
|
describe('createWindow - Window Event Setup and Lifecycle', () => {
|
|
let mockEnv: ReturnType<typeof setupMockEnvironment>
|
|
let mockWebContents: any
|
|
let mockWindow: any
|
|
let mockFileReader: any
|
|
let mockWebViewManager: any
|
|
let mockUpdate: any
|
|
let mockMenu: any
|
|
|
|
beforeEach(() => {
|
|
mockEnv = setupMockEnvironment()
|
|
|
|
// Mock webContents
|
|
mockWebContents = {
|
|
on: vi.fn(),
|
|
once: vi.fn(),
|
|
executeJavaScript: vi.fn(),
|
|
send: vi.fn(),
|
|
loadURL: vi.fn(),
|
|
loadFile: vi.fn(),
|
|
openDevTools: vi.fn(),
|
|
toggleDevTools: vi.fn()
|
|
}
|
|
|
|
// Mock window
|
|
mockWindow = {
|
|
webContents: mockWebContents,
|
|
reload: vi.fn()
|
|
}
|
|
|
|
// Mock FileReader class
|
|
mockFileReader = vi.fn()
|
|
|
|
// Mock WebViewManager class
|
|
mockWebViewManager = vi.fn().mockImplementation(() => ({
|
|
createWebview: vi.fn()
|
|
}))
|
|
|
|
// Mock update function
|
|
mockUpdate = vi.fn()
|
|
|
|
// Mock Menu
|
|
mockMenu = {
|
|
setApplicationMenu: vi.fn()
|
|
}
|
|
|
|
// Reset all mocks
|
|
vi.clearAllMocks()
|
|
})
|
|
|
|
afterEach(() => {
|
|
mockEnv.reset()
|
|
})
|
|
|
|
describe('FileReader and WebViewManager Initialization', () => {
|
|
it.skip('should create 8 webviews with correct IDs', () => {
|
|
const webViewManager = new mockWebViewManager(mockWindow)
|
|
const instance = mockWebViewManager.mock.instances[0]
|
|
|
|
// Simulate the loop that creates webviews
|
|
for (let i = 1; i <= 8; i++) {
|
|
instance.createWebview(i === 1 ? undefined : i.toString())
|
|
}
|
|
|
|
expect(instance.createWebview).toHaveBeenCalledTimes(8)
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(1, undefined)
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(2, '2')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(3, '3')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(4, '4')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(5, '5')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(6, '6')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(7, '7')
|
|
expect(instance.createWebview).toHaveBeenNthCalledWith(8, '8')
|
|
})
|
|
})
|
|
|
|
describe('Window Event Listeners Setup', () => {
|
|
it('should disable application menu', () => {
|
|
// Simulate setupWindowEventListeners
|
|
mockMenu.setApplicationMenu(null)
|
|
|
|
expect(mockMenu.setApplicationMenu).toHaveBeenCalledWith(null)
|
|
})
|
|
|
|
it('should set up application menu only once', () => {
|
|
// Simulate multiple calls to setupWindowEventListeners
|
|
mockMenu.setApplicationMenu(null)
|
|
mockMenu.setApplicationMenu(null)
|
|
|
|
expect(mockMenu.setApplicationMenu).toHaveBeenCalledTimes(2)
|
|
expect(mockMenu.setApplicationMenu).toHaveBeenCalledWith(null)
|
|
})
|
|
})
|
|
|
|
describe('DevTools Shortcuts Setup', () => {
|
|
it('should set up before-input-event listener for dev tools shortcuts', () => {
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', expect.any(Function))
|
|
|
|
expect(mockWebContents.on).toHaveBeenCalledWith('before-input-event', expect.any(Function))
|
|
})
|
|
|
|
it('should handle F12 key to toggle dev tools', () => {
|
|
let beforeInputCallback: any
|
|
|
|
mockWebContents.on.mockImplementation((event: string, callback: any) => {
|
|
if (event === 'before-input-event') {
|
|
beforeInputCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', (event: any, input: any) => {
|
|
if (input.key === 'F12' && input.type === 'keyDown') {
|
|
mockWebContents.toggleDevTools()
|
|
}
|
|
})
|
|
|
|
// Trigger F12 key
|
|
if (beforeInputCallback) {
|
|
const mockEvent = { preventDefault: vi.fn() }
|
|
const mockInput = { key: 'F12', type: 'keyDown' }
|
|
beforeInputCallback(mockEvent, mockInput)
|
|
}
|
|
|
|
expect(mockWebContents.toggleDevTools).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle Ctrl+Shift+I to toggle dev tools on Windows/Linux', () => {
|
|
let beforeInputCallback: any
|
|
|
|
mockWebContents.on.mockImplementation((event: string, callback: any) => {
|
|
if (event === 'before-input-event') {
|
|
beforeInputCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', (event: any, input: any) => {
|
|
if (input.control && input.shift && input.key.toLowerCase() === 'i' && input.type === 'keyDown') {
|
|
mockWebContents.toggleDevTools()
|
|
}
|
|
})
|
|
|
|
// Trigger Ctrl+Shift+I
|
|
if (beforeInputCallback) {
|
|
const mockEvent = { preventDefault: vi.fn() }
|
|
const mockInput = {
|
|
control: true,
|
|
shift: true,
|
|
key: 'I',
|
|
type: 'keyDown'
|
|
}
|
|
beforeInputCallback(mockEvent, mockInput)
|
|
}
|
|
|
|
expect(mockWebContents.toggleDevTools).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should handle Cmd+Shift+I to toggle dev tools on Mac', () => {
|
|
let beforeInputCallback: any
|
|
|
|
mockWebContents.on.mockImplementation((event: string, callback: any) => {
|
|
if (event === 'before-input-event') {
|
|
beforeInputCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', (event: any, input: any) => {
|
|
if (input.meta && input.shift && input.key.toLowerCase() === 'i' && input.type === 'keyDown') {
|
|
mockWebContents.toggleDevTools()
|
|
}
|
|
})
|
|
|
|
// Trigger Cmd+Shift+I
|
|
if (beforeInputCallback) {
|
|
const mockEvent = { preventDefault: vi.fn() }
|
|
const mockInput = {
|
|
meta: true,
|
|
shift: true,
|
|
key: 'I',
|
|
type: 'keyDown'
|
|
}
|
|
beforeInputCallback(mockEvent, mockInput)
|
|
}
|
|
|
|
expect(mockWebContents.toggleDevTools).toHaveBeenCalled()
|
|
})
|
|
|
|
it('should not trigger dev tools on key up events', () => {
|
|
let beforeInputCallback: any
|
|
|
|
mockWebContents.on.mockImplementation((event: string, callback: any) => {
|
|
if (event === 'before-input-event') {
|
|
beforeInputCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', (event: any, input: any) => {
|
|
if (input.key === 'F12' && input.type === 'keyDown') {
|
|
mockWebContents.toggleDevTools()
|
|
}
|
|
})
|
|
|
|
// Trigger F12 key up (should not toggle)
|
|
if (beforeInputCallback) {
|
|
const mockEvent = { preventDefault: vi.fn() }
|
|
const mockInput = { key: 'F12', type: 'keyUp' }
|
|
beforeInputCallback(mockEvent, mockInput)
|
|
}
|
|
|
|
expect(mockWebContents.toggleDevTools).not.toHaveBeenCalled()
|
|
})
|
|
|
|
it('should not trigger dev tools on wrong key combinations', () => {
|
|
let beforeInputCallback: any
|
|
|
|
mockWebContents.on.mockImplementation((event: string, callback: any) => {
|
|
if (event === 'before-input-event') {
|
|
beforeInputCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate setupDevToolsShortcuts
|
|
mockWebContents.on('before-input-event', (event: any, input: any) => {
|
|
if (input.control && input.shift && input.key.toLowerCase() === 'i' && input.type === 'keyDown') {
|
|
mockWebContents.toggleDevTools()
|
|
}
|
|
})
|
|
|
|
// Trigger wrong combination (Ctrl+I without Shift)
|
|
if (beforeInputCallback) {
|
|
const mockEvent = { preventDefault: vi.fn() }
|
|
const mockInput = {
|
|
control: true,
|
|
shift: false,
|
|
key: 'I',
|
|
type: 'keyDown'
|
|
}
|
|
beforeInputCallback(mockEvent, mockInput)
|
|
}
|
|
|
|
expect(mockWebContents.toggleDevTools).not.toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
describe('Auto-Update Integration', () => {
|
|
it('should call update function with window reference', () => {
|
|
// Simulate auto-update setup
|
|
mockUpdate(mockWindow)
|
|
|
|
expect(mockUpdate).toHaveBeenCalledWith(mockWindow)
|
|
})
|
|
|
|
it('should call update function only once', () => {
|
|
// Simulate auto-update setup
|
|
mockUpdate(mockWindow)
|
|
|
|
expect(mockUpdate).toHaveBeenCalledTimes(1)
|
|
})
|
|
})
|
|
|
|
describe('Event Handler Organization', () => {
|
|
it('should set up event handlers in correct order', () => {
|
|
const eventSetupOrder: string[] = []
|
|
|
|
// Mock all the setup functions to track order
|
|
const setupWindowEventListeners = () => {
|
|
eventSetupOrder.push('windowEventListeners')
|
|
mockMenu.setApplicationMenu(null)
|
|
}
|
|
|
|
const setupDevToolsShortcuts = () => {
|
|
eventSetupOrder.push('devToolsShortcuts')
|
|
mockWebContents.on('before-input-event', vi.fn())
|
|
}
|
|
|
|
const setupExternalLinkHandling = () => {
|
|
eventSetupOrder.push('externalLinkHandling')
|
|
}
|
|
|
|
const handleBeforeClose = () => {
|
|
eventSetupOrder.push('beforeClose')
|
|
}
|
|
|
|
// Simulate the order in createWindow
|
|
setupWindowEventListeners()
|
|
setupDevToolsShortcuts()
|
|
setupExternalLinkHandling()
|
|
handleBeforeClose()
|
|
|
|
expect(eventSetupOrder).toEqual([
|
|
'windowEventListeners',
|
|
'devToolsShortcuts',
|
|
'externalLinkHandling',
|
|
'beforeClose'
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('Window State Management', () => {
|
|
it('should handle window ready state correctly', async () => {
|
|
let didFinishLoadCallback: (() => void) | undefined
|
|
|
|
// Mock the did-finish-load event listener
|
|
mockWebContents.once.mockImplementation((event: string, callback: () => void) => {
|
|
if (event === 'did-finish-load') {
|
|
didFinishLoadCallback = callback
|
|
}
|
|
})
|
|
|
|
// Simulate waiting for window ready
|
|
const windowReadyPromise = new Promise<void>(resolve => {
|
|
mockWebContents.once('did-finish-load', () => {
|
|
resolve()
|
|
})
|
|
})
|
|
|
|
// Trigger the event
|
|
if (didFinishLoadCallback) {
|
|
didFinishLoadCallback()
|
|
}
|
|
|
|
// Should resolve without throwing
|
|
await expect(windowReadyPromise).resolves.toBeUndefined()
|
|
})
|
|
|
|
it('should log appropriate messages during window setup', () => {
|
|
// In a real test, you would verify that appropriate log messages are called
|
|
// This ensures the window setup process is properly logged
|
|
const mockLog = {
|
|
info: vi.fn(),
|
|
error: vi.fn()
|
|
}
|
|
|
|
// Simulate logging calls that would happen during window setup
|
|
mockLog.info('Window content loaded, starting dependency check immediately...')
|
|
mockLog.info('.eigent directory structure ensured')
|
|
|
|
expect(mockLog.info).toHaveBeenCalledWith(
|
|
'Window content loaded, starting dependency check immediately...'
|
|
)
|
|
expect(mockLog.info).toHaveBeenCalledWith(
|
|
'.eigent directory structure ensured'
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('Integration Points', () => {
|
|
it('should properly coordinate between file reader and webview manager', () => {
|
|
const fileReader = new mockFileReader(mockWindow)
|
|
const webViewManager = new mockWebViewManager(mockWindow)
|
|
|
|
// Both should be initialized with the same window
|
|
expect(mockFileReader).toHaveBeenCalledWith(mockWindow)
|
|
expect(mockWebViewManager).toHaveBeenCalledWith(mockWindow)
|
|
})
|
|
|
|
it('should handle window initialization errors gracefully', () => {
|
|
// Mock FileReader to throw during initialization
|
|
mockFileReader.mockImplementation(() => {
|
|
throw new Error('FileReader initialization failed')
|
|
})
|
|
|
|
// Should handle gracefully in real implementation
|
|
expect(() => {
|
|
try {
|
|
new mockFileReader(mockWindow)
|
|
} catch (error) {
|
|
// Log error but don't stop execution
|
|
console.error('FileReader initialization error:', error)
|
|
}
|
|
}).not.toThrow()
|
|
})
|
|
})
|
|
|
|
describe('Memory Management', () => {
|
|
it('should properly clean up event listeners when window is destroyed', () => {
|
|
// In a real scenario, you would test that event listeners are removed
|
|
// when the window is closed to prevent memory leaks
|
|
|
|
const mockRemoveListener = vi.fn()
|
|
mockWebContents.removeListener = mockRemoveListener
|
|
|
|
// Simulate cleanup
|
|
const cleanup = () => {
|
|
mockWebContents.removeListener('before-input-event', vi.fn())
|
|
mockWebContents.removeListener('dom-ready', vi.fn())
|
|
}
|
|
|
|
cleanup()
|
|
|
|
expect(mockRemoveListener).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
}) |