* feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: support for multimonitor tests (#47911) * test: support for multimonitor tests * fix: update yarn.lock file * test: support any resolution for new displays * test: support display positioning * docs: multi-monitor tests * test: remove dummy test * feat: enforce unique window names across BaseWindow and BrowserWindow (#47764) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: enforce unique window names across BaseWindow and BrowserWindow * docs: update docs for name property * fix: linter issue with symbol --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: clear and restore window state (#47781) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: restore window state * feat: flush display modes on show * refactor: move utility functions to common area * feat: clear window state * fix: wait for the prefs to update * test: clearWindowState extra test * test: refine clear window state tests * test: single monitor restore window tests chore: rebase on gsoc-2025 * refactor: refine clearWindowState test * fix: revert default_app back to original * docs: add comment linking AdjustBoundsToBeVisibleOnDisplay to Chromium code * fix: add correct permalink * refactor: ci friendly * fix: disable windowStatePersistence when no display * refactor: use reference instead pointer * fix: skip window state persistence for invalid/fake displays * refactor: better flag placement * test: add test to verify window state is not saved when no display * fix: restore display mode inside show() * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: clear sharedUserPath before and test * refactor: hasInvalidDisplay function * debug: add display info logging for CI * fix: do not save/restore when window is 0x0 * test: support for multimonitor tests (#47911) * test: support for multimonitor tests * fix: update yarn.lock file * test: support any resolution for new displays * test: support display positioning * docs: multi-monitor tests * test: remove dummy test * feat: enforce unique window names across BaseWindow and BrowserWindow (#47764) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: enforce unique window names across BaseWindow and BrowserWindow * docs: update docs for name property * fix: linter issue with symbol --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: remove invalid display test --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Keeley Hammond <vertedinde@electronjs.org> * test: multi monitor tests for save/restore window state (#48048) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: restore window state * feat: flush display modes on show * refactor: move utility functions to common area * feat: clear window state * fix: wait for the prefs to update * test: clearWindowState extra test * test: refine clear window state tests * test: single monitor restore window tests chore: rebase on gsoc-2025 * refactor: refine clearWindowState test * fix: revert default_app back to original * docs: add comment linking AdjustBoundsToBeVisibleOnDisplay to Chromium code * fix: add correct permalink * refactor: ci friendly * fix: disable windowStatePersistence when no display * refactor: use reference instead pointer * fix: skip window state persistence for invalid/fake displays * refactor: better flag placement * test: add test to verify window state is not saved when no display * fix: restore display mode inside show() * feat: support for multimonitor tests * fix: update yarn.lock file * feat: support any resolution for new displays * feat: support display positioning * docs: multi-monitor tests * test: remove dummy test * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: clear sharedUserPath before and test * refactor: hasInvalidDisplay function * debug: add display info logging for CI * fix: do not save/restore when window is 0x0 * test: support for multimonitor tests (#47911) * test: support for multimonitor tests * fix: update yarn.lock file * test: support any resolution for new displays * test: support display positioning * docs: multi-monitor tests * test: remove dummy test * fix: native-addon forceCleanup * docs: add forceCleanup description * test: add two basic multi-monitor tests * fix: find the closest display for non-overlapping saved bounds * test: windowStatePersistence multi-monitor tests * docs: add note on display APIs in CI * fix: remove duplicate destroy registration * feat: enforce unique window names across BaseWindow and BrowserWindow (#47764) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: enforce unique window names across BaseWindow and BrowserWindow * docs: update docs for name property * fix: linter issue with symbol --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * docs: remove inaccurate comment * fix: move expect blocks outside beforeEach * test: exclude macOS-x64 for now * test: remove invalid display test * test: remove invalid display test * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: support for multimonitor tests (#47911) * test: support for multimonitor tests * fix: update yarn.lock file * test: support any resolution for new displays * test: support display positioning * docs: multi-monitor tests * test: remove dummy test * feat: enforce unique window names across BaseWindow and BrowserWindow (#47764) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: enforce unique window names across BaseWindow and BrowserWindow * docs: update docs for name property * fix: linter issue with symbol --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: clear and restore window state (#47781) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: restore window state * feat: flush display modes on show * refactor: move utility functions to common area * feat: clear window state * fix: wait for the prefs to update * test: clearWindowState extra test * test: refine clear window state tests * test: single monitor restore window tests chore: rebase on gsoc-2025 * refactor: refine clearWindowState test * fix: revert default_app back to original * docs: add comment linking AdjustBoundsToBeVisibleOnDisplay to Chromium code * fix: add correct permalink * refactor: ci friendly * fix: disable windowStatePersistence when no display * refactor: use reference instead pointer * fix: skip window state persistence for invalid/fake displays * refactor: better flag placement * test: add test to verify window state is not saved when no display * fix: restore display mode inside show() * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: clear sharedUserPath before and test * refactor: hasInvalidDisplay function * debug: add display info logging for CI * fix: do not save/restore when window is 0x0 * test: support for multimonitor tests (#47911) * test: support for multimonitor tests * fix: update yarn.lock file * test: support any resolution for new displays * test: support display positioning * docs: multi-monitor tests * test: remove dummy test * feat: enforce unique window names across BaseWindow and BrowserWindow (#47764) * feat: save window state (#47425) * feat: save/restore window state * cleanup * remove constructor option * refactor: apply suggestions from code review Co-authored-by: Charles Kerr <charles@charleskerr.com> * refactor: forward declare prefservice * refactor: remove constructor option * refactor: save window state on move/resize instead of moved/resized * feat: resave window state after construction * test: add basic window save tests * test: add work area tests * test: asynchronous batching behavior * docs: add windowStateRestoreOptions to BaseWindowConstructorOptions * chore: move includes to main block * Update spec/api-browser-window-spec.ts Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * docs: update docs/api/structures/base-window-options.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: preserve original bounds during window state save in special modes * feat: save kiosk state in window preferences * chore: remove ts-expect-error * test: check hasCapturableScreen before running tests * test: remove multimonitor tests * test: add missing hasCapturableScreen checks before tests * docs: add blurb on saving mechanism * feat: add debounce window of 200ms to saveWindowState * docs: remove blurb until finalized * style: convert constants from snake_case to camelCase * refactor: initialize prefs_ only if window state is configured to be saved/restored * refactor: rename window states key * refactor: store in application-level Local State instead of browser context * refactor: switch to more accurate function names * fix: add dcheck for browser_process * fix: flush window state to avoid race condition * refactor: change stateId to name * refactor: change windowStateRestoreOptions to windowStatePersistence * Update docs/api/structures/base-window-options.md Co-authored-by: David Sanders <dsanders11@ucsbalum.com> * fix: add warning when window state persistence enabled without window name * docs: lowercase capital B for consistency --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * feat: enforce unique window names across BaseWindow and BrowserWindow * docs: update docs for name property * fix: linter issue with symbol --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> * test: remove invalid display test --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Keeley Hammond <vertedinde@electronjs.org> --------- Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Keeley Hammond <vertedinde@electronjs.org> * feat: add 'restored-persisted-state' event to BaseWindow (#50516) * docs: add note on display APIs in CI * docs: remove inaccurate comment * test: set show to true * docs: restored-window-state event * feat: add 'restored-window-state' event to BaseWindow * test: add tests for 'restored-window-state' event emission * test: move createWindowAndSave * docs: differentiate between name and title * test: add checks for virtual display creation * docs: tutorial for windowStatePersistence * fix: ensure only single display before multi monitor tests * docs: better docs for virtual display addon * docs: better docs for virtual display addon * refactor: rename event restored-window-state to restored-persisted-state * refactor: rename BaseWindow.clearWindowState to clearPersistedState * docs: improve docs for name property and fix typos * build: run yarn install * fix: update base::Value::Dict -> base::DictValue * fix: add install script to virtual-display native addon The virtual-display fixture was missing an "install" script, so node-gyp never compiled it during `yarn install`. This caused "Cannot find module '../build/Release/virtual_display.node'" in CI. Also removed unused dependencies (bindings, @types/jest, node-gyp) to match the pattern of other native addon fixtures. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com> --------- Co-authored-by: Nilay Arya <nilay2014@gmail.com> Co-authored-by: Claude <svc-devxp-claude@slack-corp.com> * chore: fixup yarn.lock, lint * chore: fix build errors after rebase onto main Remove stale `#include "shell/browser/native_window_features.h"` (header was deleted in #51160) and add the required `animate` parameter to the `SetBounds` call in `RestoreBounds` (signature changed on main). * fix: rewrite virtual-display addon in Objective-C, removing Swift dependency The CI runner's Xcode 16.4 has a broken Swift toolchain where swift-frontend cannot load lib_CompilerSwiftIDEUtils.dylib. Since the addon only uses CoreGraphics private C/ObjC APIs (CGVirtualDisplay, CGVirtualDisplayDescriptor, etc.), rewrite the implementation entirely in Objective-C to eliminate the Swift compilation step. Co-Authored-By: Claude <svc-devxp-claude@slack-corp.com> * chore: remove nut-js dependent tests * test: fix macos display tests * Update docs/api/base-window.md Co-authored-by: Sam Maddock <samuelmaddock@electronjs.org> * Update docs/tutorial/window-state-persistence.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * Update docs/tutorial/window-state-persistence.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: defer is_being_restored reset and persisted-state-restored to display-mode callback Resetting is_being_restored_ synchronously at the end of RestoreWindowState let the deferred display-mode callback (kiosk/fullscreen/maximize) fire from Show() with the flag already false, so the resize/move events it produced scheduled DebouncedSaveWindowState and persisted transitional bounds over the user's saved bounds. Also rename the BaseWindow event to persisted-state-restored consistently across the C++ emit, tutorial, and spec, and move the 25s busy-loop spec into a spawned Electron fixture so the spec runner main thread isn't blocked. * test: bump main-thread-busy spec timeout to 60s Spawned Electron fixture sleeps 25s plus startup, exceeding mocha's 30s default. * fix: emit persisted-state-restored synchronously, not in deferred callback The previous fix moved NotifyWindowStateRestored() into the deferred display-mode callback to keep it ordered after the kiosk/fullscreen/ maximize change. But that callback only fires from Show() via FlushPendingDisplayMode(), so windows constructed with show: false (and restore_display_mode_ true, which is the default) never emitted the event - including the spec coverage. Restore the synchronous emit and keep the is_being_restored_ deferral, since only the flag reset needs to straddle the deferred resize/move events that schedule DebouncedSaveWindowState. * fix: tie window-state restore guard to display-mode transition lifecycle The is_being_restored_ guard was reset on the deferred display-mode callback invocation rather than the actual restoration lifecycle, which caused three defects: 1. A window created with show:false and destroyed before show() left the guard stuck true, so the close-time FlushWindowState save no-op'd and state changes made while hidden were dropped. 2. showInactive() never flushed the deferred display mode, so a persisted hidden window shown inactive did not re-apply saved fullscreen/ maximize/kiosk and left the guard stuck true. 3. On macOS the guard was reset synchronously after the async SetFullScreen/Maximize/SetKiosk calls, so a flush during the transition persisted transitional bounds over the saved state. Reset the guard from the NotifyWindowEnterFullScreen/NotifyWindowMaximize observers once the transition completes, drain a never-run callback in FlushWindowState, flush the pending display mode from ShowInactive on both backends, and skip saves while a fullscreen transition is in flight. --------- Co-authored-by: Nilay Arya <84241885+nilayarya@users.noreply.github.com> Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: David Sanders <dsanders11@ucsbalum.com> Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Nilay Arya <nilay2014@gmail.com> Co-authored-by: Claude <svc-devxp-claude@slack-corp.com> Co-authored-by: George Xu <33054982+georgexu99@users.noreply.github.com> Co-authored-by: Sam Maddock <samuelmaddock@electronjs.org> Co-authored-by: George Xu <george.xu@slack-corp.com>
3.9 KiB
Testing
We aim to keep the code coverage of Electron high. We ask that all pull request not only pass all existing tests, but ideally also add new tests to cover changed code and new scenarios. Ensuring that we capture as many code paths and use cases of Electron as possible ensures that we all ship apps with fewer bugs.
This repository comes with linting rules for both JavaScript and C++ – as well as unit and integration tests. To learn more about Electron's coding style, please see the coding-style document.
Linting
To ensure that your changes are in compliance with the Electron coding
style, run npm run lint, which will run a variety of linting checks
against your changes depending on which areas of the code they touch.
Many of these checks are included as precommit hooks, so it's likely your error would be caught at commit time.
Unit Tests
If you are not using build-tools,
ensure that the name you have configured for your
local build of Electron is one of Testing, Release, Default, or
you have set process.env.ELECTRON_OUT_DIR. Without these set, Electron will fail
to perform some pre-testing steps.
To run all unit tests, run npm run test. The unit tests are an Electron
app (surprise!) that can be found in the spec folder. Note that it has
its own package.json and that its dependencies are therefore not defined
in the top-level package.json.
To run only specific tests matching a pattern, run npm run test -- -g=PATTERN, replacing the PATTERN with a regex that matches the tests
you would like to run. As an example: If you want to run only IPC tests, you
would run npm run test -- -g ipc.
Node.js Smoke Tests
If you've made changes that might affect the way Node.js is embedded into Electron, we have a test runner that runs all of the tests from Node.js, using Electron's custom fork of Node.js.
To run all of the Node.js tests:
$ node script/node-spec-runner.js
To run a single Node.js test:
$ node script/node-spec-runner.js parallel/test-crypto-keygen
where the argument passed to the runner is the path to the test in the Node.js source tree.
Testing on Windows 10 devices
Extra steps to run the unit test:
-
Visual Studio 2019 must be installed.
-
Node headers have to be compiled for your configuration.
ninja -C out\Testing electron:node_headers -
The electron.lib has to be copied as node.lib.
cd out\Testing mkdir gen\node_headers\Release copy electron.lib gen\node_headers\Release\node.lib
Missing fonts
Some Windows 10 devices do not ship with the Meiryo font installed, which may cause a font fallback test to fail. To install Meiryo:
- Push the Windows key and search for Manage optional features.
- Click Add a feature.
- Select Japanese Supplemental Fonts and click Install.
Pixel measurements
Some tests which rely on precise pixel measurements may not work correctly on devices with Hi-DPI screen settings due to floating point precision errors. To run these tests correctly, make sure the device is set to 100% scaling.
To configure display scaling:
- Push the Windows key and search for Display settings.
- Under Scale and layout, make sure that the device is set to 100%.
Multi-Monitor Tests
Some Electron APIs require testing across multiple displays, such as screen detection, window positioning, and display-related events. For contributors working on these features, the virtualDisplay native addon enables you to create and position virtual displays programmatically, making it possible to test multi-monitor scenarios without any physical hardware.
For detailed information on using virtual displays in your tests, see Multi-Monitor Testing.
Platform support: macOS only