@@ -238,5 +238,144 @@ public async Task Represented_filename_and_edited_flags()
238238
239239 win . SetDocumentEdited ( false ) ;
240240 }
241+
242+ // --- Added window state tests ---
243+
244+ [ Fact ( Timeout = 20000 ) ]
245+ public async Task Fullscreen_toggle_and_query ( )
246+ {
247+ var win = this . fx . MainWindow ;
248+ win . Show ( ) ;
249+ await Task . Delay ( 300 ) ;
250+ ( await win . IsVisibleAsync ( ) ) . Should ( ) . BeTrue ( ) ;
251+
252+ // Ensure window is fullscreenable
253+ win . SetFullScreenable ( true ) ;
254+ await Task . Delay ( 200 ) ;
255+
256+ // Poll for fullscreen state instead of fixed waits (Electron can be slow)
257+ win . SetFullScreen ( true ) ;
258+ var entered = await WaitUntil ( async ( ) => await win . IsFullScreenAsync ( ) , 3000 ) ;
259+ entered . Should ( ) . BeTrue ( "Window should enter fullscreen within timeout" ) ;
260+
261+ win . SetFullScreen ( false ) ;
262+ var left = await WaitUntil ( async ( ) => ! ( await win . IsFullScreenAsync ( ) ) , 3000 ) ;
263+ left . Should ( ) . BeTrue ( "Window should exit fullscreen within timeout" ) ;
264+ }
265+
266+ [ Fact ( Timeout = 20000 ) ]
267+ public async Task Maximize_unmaximize_roundtrip ( )
268+ {
269+ var win = this . fx . MainWindow ;
270+ win . Unmaximize ( ) ; // ensure not maximized
271+ await Task . Delay ( 500 ) ;
272+ ( await win . IsMaximizedAsync ( ) ) . Should ( ) . BeFalse ( ) ;
273+ win . Maximize ( ) ;
274+ await Task . Delay ( 800 ) ;
275+ ( await win . IsMaximizedAsync ( ) ) . Should ( ) . BeTrue ( ) ;
276+ win . Unmaximize ( ) ;
277+ await Task . Delay ( 1500 ) ;
278+ ( await win . IsMaximizedAsync ( ) ) . Should ( ) . BeFalse ( ) ;
279+ }
280+
281+ [ Fact ( Timeout = 20000 ) ]
282+ public async Task Minimize_restore_roundtrip ( )
283+ {
284+ var win = this . fx . MainWindow ;
285+ win . Restore ( ) ; // ensure not minimized
286+ await Task . Delay ( 500 ) ;
287+ ( await win . IsMinimizedAsync ( ) ) . Should ( ) . BeFalse ( ) ;
288+ win . Minimize ( ) ;
289+ await Task . Delay ( 1500 ) ;
290+ ( await win . IsMinimizedAsync ( ) ) . Should ( ) . BeTrue ( ) ;
291+ win . Restore ( ) ;
292+ await Task . Delay ( 1500 ) ;
293+ ( await win . IsMinimizedAsync ( ) ) . Should ( ) . BeFalse ( ) ;
294+ }
295+
296+ [ Fact ( Timeout = 20000 ) ]
297+ public async Task Fullscreen_events_fire_on_toggle ( )
298+ {
299+ var window = await Electron . WindowManager . CreateWindowAsync ( new BrowserWindowOptions { Show = true , Fullscreenable = true } , "about:blank" ) ;
300+ try
301+ {
302+ bool entered = false , left = false ;
303+ window . OnEnterFullScreen += ( ) => entered = true ;
304+ window . OnLeaveFullScreen += ( ) => left = true ;
305+ await Task . Delay ( 400 ) ;
306+
307+ window . SetFullScreen ( true ) ;
308+ await WaitUntil ( ( ) => Task . FromResult ( entered ) , 4000 ) ;
309+ entered . Should ( ) . BeTrue ( ) ;
310+
311+ window . SetFullScreen ( false ) ;
312+ await WaitUntil ( ( ) => Task . FromResult ( left ) , 4000 ) ;
313+ left . Should ( ) . BeTrue ( ) ;
314+ }
315+ finally
316+ {
317+ window . Destroy ( ) ;
318+ }
319+ }
320+
321+ [ Fact ( Timeout = 20000 ) ]
322+ public async Task Maximize_and_unmaximize_events_fire ( )
323+ {
324+ var window = await Electron . WindowManager . CreateWindowAsync ( new BrowserWindowOptions { Show = true } , "about:blank" ) ;
325+ try
326+ {
327+ bool maximized = false , unmaximized = false ;
328+ window . OnMaximize += ( ) => maximized = true ;
329+ window . OnUnmaximize += ( ) => unmaximized = true ;
330+ await Task . Delay ( 500 ) ;
331+ window . Maximize ( ) ;
332+ await Task . Delay ( 1500 ) ;
333+ maximized . Should ( ) . BeTrue ( ) ;
334+ window . Unmaximize ( ) ;
335+ await Task . Delay ( 1500 ) ;
336+ unmaximized . Should ( ) . BeTrue ( ) ;
337+ }
338+ finally
339+ {
340+ window . Destroy ( ) ;
341+ }
342+ }
343+
344+ [ Fact ( Timeout = 20000 ) ]
345+ public async Task Minimize_and_restore_events_fire ( )
346+ {
347+ var window = await Electron . WindowManager . CreateWindowAsync ( new BrowserWindowOptions { Show = true } , "about:blank" ) ;
348+ try
349+ {
350+ bool minimized = false , restored = false ;
351+ window . OnMinimize += ( ) => minimized = true ;
352+ window . OnRestore += ( ) => restored = true ;
353+ await Task . Delay ( 500 ) ;
354+ window . Minimize ( ) ;
355+ await Task . Delay ( 1500 ) ; // minimize may take longer
356+ minimized . Should ( ) . BeTrue ( ) ;
357+ window . Restore ( ) ;
358+ await Task . Delay ( 1500 ) ;
359+ restored . Should ( ) . BeTrue ( ) ;
360+ }
361+ finally
362+ {
363+ window . Destroy ( ) ;
364+ }
365+ }
366+
367+ private static async Task < bool > WaitUntil ( Func < Task < bool > > predicate , int timeoutMs , int pollIntervalMs = 100 )
368+ {
369+ var start = DateTime . UtcNow ;
370+ while ( ( DateTime . UtcNow - start ) . TotalMilliseconds < timeoutMs )
371+ {
372+ if ( await predicate ( ) . ConfigureAwait ( false ) )
373+ {
374+ return true ;
375+ }
376+ await Task . Delay ( pollIntervalMs ) . ConfigureAwait ( false ) ;
377+ }
378+ return await predicate ( ) . ConfigureAwait ( false ) ;
379+ }
241380 }
242381}
0 commit comments