多显示器测试
🌐 Multi-Monitor Testing
virtualDisplay 插件利用 macOS 的 CoreGraphics API 创建虚拟显示器,让你可以编写和运行多屏测试,而不需要实际的显示器。由于 macOS CoreGraphics 的一些特殊情况,建议在写测试之前先完整阅读一遍指南。
🌐 The virtualDisplay addon leverages macOS CoreGraphics APIs to create virtual displays, allowing you to write and run multi-monitor tests without the need for physical monitors. Due to macOS CoreGraphics quirks, reading the entire guide once before writing tests is recommended.
方法
🌐 Methods
virtualDisplay.create([options])
创建一个虚拟显示器并返回显示器 ID。
🌐 Creates a virtual display and returns a display ID.
const virtualDisplay = require('@electron-ci/virtual-display')
// Default: 1920×1080 at origin (0, 0)
const displayId = virtualDisplay.create()
const virtualDisplay = require('@electron-ci/virtual-display')
// Custom options (all parameters optional and have default values)
const displayId = virtualDisplay.create({
width: 2560, // Display width in pixels
height: 1440, // Display height in pixels
x: 1920, // X position (top-left corner)
y: 0 // Y position (top-left corner)
})
返回值: number - 用于识别显示器的唯一显示ID。创建显示器失败时返回 0。
建议在每次测试前调用 virtualDisplay.forceCleanup(),以防那个测试里显示创建失败。macOS 的 CoreGraphics 有一个内部显示 ID 分配池,如果在测试中虚拟显示被快速创建和销毁,这个池可能会损坏。如果没有妥善清理,后续的显示创建可能会因为显示 ID 不一致而失败,导致测试不稳定。
virtualDisplay.forceCleanup()
完全清理所有虚拟显示器并重置 macOS CoreGraphics 显示系统。
🌐 Performs a complete cleanup of all virtual displays and resets the macOS CoreGraphics display system.
beforeEach(() => {
virtualDisplay.forceCleanup()
})
virtualDisplay.destroy(displayId)
移除虚拟显示器。
🌐 Removes the virtual display.
virtualDisplay.destroy(displayId)
使用完虚拟显示器后一定要销毁它,以防破坏 macOS CoreGraphics 显示池并影响后续测试。
推荐使用方式
🌐 Recommended usage pattern
describe('multi-monitor tests', () => {
const virtualDisplay = require('@electron-ci/virtual-display')
beforeEach(() => {
virtualDisplay.forceCleanup()
})
it('should handle multiple displays', () => {
const display1 = virtualDisplay.create({ width: 1920, height: 1080, x: 0, y: 0 })
const display2 = virtualDisplay.create({ width: 2560, height: 1440, x: 1920, y: 0 })
// Your test logic here
virtualDisplay.destroy(display1)
virtualDisplay.destroy(display2)
})
})
显示限制
🌐 Display Constraints
尺寸限制
🌐 Size Limits
虚拟显示屏的分辨率最低限制为720×720像素,最高限制为8192×8192像素。实际限制可能会因你的Mac显卡性能而有所不同,所以超出这个范围的尺寸(比如9000×6000)在某些系统上可能无法使用。
🌐 Virtual displays are constrained to 720×720 pixels minimum and 8192×8192 pixels maximum. Actual limits may vary depending on your Mac's graphics capabilities, so sizes outside this range (like 9000×6000) may fail on some systems.
// Safe sizes for testing
virtualDisplay.create({ width: 1920, height: 1080 }) // Full HD
virtualDisplay.create({ width: 3840, height: 2160 }) // 4K
定位行为
🌐 Positioning Behavior
macOS 会通过自动调整显示器位置来保持连续的桌面空间,如果有重叠或间隙的话。如果出现重叠或间隙,新起点的位置会尽量靠近你想放的位置,同时不会重叠也不会留空隙。
🌐 macOS maintains a contiguous desktop space by automatically adjusting display positions if there are any overlaps or gaps. In case of either, the placement of the new origin is as close as possible to the requested location, without overlapping or leaving a gap between displays.
重叠:
// Requested positions
const display1 = virtualDisplay.create({ x: 0, y: 0, width: 1920, height: 1080 })
const display2 = virtualDisplay.create({ x: 500, y: 0, width: 1920, height: 1080 })
// macOS automatically repositions display2 to x: 1920 to prevent overlap
const actualBounds = screen.getAllDisplays().map(d => d.bounds)
// Result: [{ x: 0, y: 0, width: 1920, height: 1080 }, { x: 1920, y: 0, width: 1920, height: 1080 }]
差距:
// Requested: gap between displays
const display1 = virtualDisplay.create({ width: 1920, height: 1080, x: 0, y: 0 })
const display2 = virtualDisplay.create({ width: 1920, height: 1080, x: 2000, y: 0 })
// macOS snaps display2 to x: 1920 (eliminates 80px gap)
创建后务必用 screen.getAllDisplays() 核实实际位置,因为 macOS 可能会调整设置的坐标。