···2373237323742374 // Set up modal behavior if requested
23752375 // Delay blur handler attachment to avoid race condition where focus events
23762376- // are still settling after window creation (can cause immediate close)
23772377- if (options.modal === true) {
23762376+ // are still settling after window creation (can cause immediate close).
23772377+ //
23782378+ // In test profiles, skip the close-on-blur handler entirely. Under
23792379+ // parallel Playwright workers (fullyParallel + workers > 1), focus
23802380+ // events flicker between windows in ways they don't in real user
23812381+ // sessions, causing modal cmd panels to close mid-test with
23822382+ // "Target page, context or browser has been closed" errors on any
23832383+ // subsequent .press() / .evaluate() call. OS-integration behavior
23842384+ // for close-on-blur should be covered by a dedicated serial suite,
23852385+ // not smoke.
23862386+ if (options.modal === true && !isTestProfile()) {
23782387 setTimeout(() => {
23792388 if (!win.isDestroyed()) {
23802389 win.on('blur', () => {
+9-2
backend/electron/tile-ipc.ts
···3333} from './tile-launcher.js';
3434import { parseManifestFile } from './tile-manifest.js';
3535import { publish, subscribe, unsubscribe, scopes, type Scope } from './pubsub.js';
3636-import { DEBUG, TILE_STRICT } from './config.js';
3636+import { DEBUG, TILE_STRICT, isHeadless } from './config.js';
3737import { publishCapabilityViolation } from './tile-violations.js';
3838import { getFeatureRegistry } from './feature-startup.js';
3939import { getAtprotoSource } from './feature-startup.js';
···27402740 if (!win || win.isDestroyed()) {
27412741 return { success: false, error: 'Tile window not found' };
27422742 }
27432743- win.show();
27432743+ // In headless test runs, keep the window hidden. Otherwise it pops
27442744+ // foreground and steals OS focus from other Electron instances in
27452745+ // parallel Playwright workers, which triggers blur on modal cmd panels
27462746+ // and breaks unrelated tests. The tests that assert showSelf's effect
27472747+ // check state via pubsub / evaluate, not visual presence.
27482748+ if (!isHeadless()) {
27492749+ win.show();
27502750+ }
27442751 return { success: true };
27452752 } catch (err) {
27462753 const message = err instanceof Error ? err.message : String(err);