@@ -828,5 +828,161 @@ define(function (require, exports, module) {
828828 expect ( toolbar ) . toBeGreaterThanOrEqual ( minToolbar ) ;
829829 } ) ;
830830 } ) ;
831+
832+ describe ( "11. Cycle stability" , function ( ) {
833+
834+ beforeEach ( async function ( ) {
835+ SidebarView . resize ( 200 ) ;
836+ await awaitsFor ( function ( ) { return _$ ( "#sidebar" ) [ 0 ] . offsetWidth === 200 ; } ,
837+ "sidebar to settle at baseline 200px" , 2000 ) ;
838+ } ) ;
839+
840+ it ( "should keep CCB, sidebar, and main-toolbar aligned through enter→drag→exit→re-enter" , async function ( ) {
841+ await openLivePreview ( ) ;
842+
843+ // Cycle 1: enter design, drag sidebar wider, exit, re-enter.
844+ await enterDesignMode ( ) ;
845+
846+ const $resizer = _$ ( "#sidebar > .horz-resizer" ) ;
847+ let rect = $resizer [ 0 ] . getBoundingClientRect ( ) ;
848+ let handleY = rect . top + rect . height / 2 ;
849+ await DragTestUtils . dragFromElement ( $resizer [ 0 ] ,
850+ rect . left + 200 , handleY , testWindow ) ;
851+
852+ await exitDesignMode ( ) ;
853+ await enterDesignMode ( ) ;
854+
855+ // After the full cycle, CCB sits flush right of the sidebar and
856+ // main-toolbar sits flush right of the CCB.
857+ const sidebarRect = _$ ( "#sidebar" ) [ 0 ] . getBoundingClientRect ( ) ;
858+ const ccbRect = _$ ( "#centralControlBar" ) [ 0 ] . getBoundingClientRect ( ) ;
859+ const mtRect = _$ ( "#main-toolbar" ) [ 0 ] . getBoundingClientRect ( ) ;
860+
861+ expect ( Math . abs ( ccbRect . left - sidebarRect . right ) ) . toBeLessThan ( 2 ) ;
862+ expect ( Math . abs ( mtRect . left - ( sidebarRect . right + CCB_WIDTH ) ) ) . toBeLessThan ( 2 ) ;
863+ } ) ;
864+
865+ it ( "should leave Live Preview open after a full design-mode cycle with the toolbar at a usable width" , async function ( ) {
866+ await openLivePreview ( ) ;
867+ const iconsW = _$ ( "#plugin-icons-bar" ) . outerWidth ( ) ;
868+ const lp = livePanel ( ) ;
869+ const minToolbar = ( lp && lp . minWidth ? lp . minWidth : 0 ) + iconsW ;
870+
871+ await enterDesignMode ( ) ;
872+ await exitDesignMode ( ) ;
873+ await enterDesignMode ( ) ;
874+ await exitDesignMode ( ) ;
875+
876+ expect ( livePanel ( ) . isVisible ( ) ) . toBe ( true ) ;
877+ const toolbar = _$ ( "#main-toolbar" ) . outerWidth ( ) ;
878+ expect ( toolbar ) . toBeGreaterThanOrEqual ( minToolbar ) ;
879+ // And the overall layout still fits the window.
880+ const sidebar = _$ ( "#sidebar" ) [ 0 ] . offsetWidth ;
881+ expect ( sidebar + CCB_WIDTH + toolbar ) . toBeLessThanOrEqual ( testWindow . innerWidth ) ;
882+ } ) ;
883+ } ) ;
884+
885+ describe ( "11b. Auto-exit design mode from conflicting surfaces" , function ( ) {
886+
887+ function toolsPanel ( ) {
888+ return WorkspaceManager . getPanelForID ( WorkspaceManager . DEFAULT_PANEL_ID ) ;
889+ }
890+
891+ async function hideToolsPanelIfVisible ( ) {
892+ const p = toolsPanel ( ) ;
893+ if ( p && p . isVisible ( ) ) {
894+ p . hide ( ) ;
895+ await awaitsFor ( function ( ) { return ! p . isVisible ( ) ; } ,
896+ "tools panel to hide" , 2000 ) ;
897+ }
898+ }
899+
900+ afterEach ( async function ( ) {
901+ await hideToolsPanelIfVisible ( ) ;
902+ // Close any modal find/quick-open bars left open.
903+ if ( _$ ( "#find-what" ) . length ) {
904+ _$ ( testWindow . document ) . trigger (
905+ _$ . Event ( "keydown" , { keyCode : 27 /* Esc */ } )
906+ ) ;
907+ }
908+ if ( _$ ( "input#quickOpenSearch" ) . length ) {
909+ _$ ( testWindow . document ) . trigger (
910+ _$ . Event ( "keydown" , { keyCode : 27 } )
911+ ) ;
912+ }
913+ await awaits ( 0 ) ;
914+ } ) ;
915+
916+ it ( "should exit design mode and open the tools bottom panel when #app-drawer-button is clicked in design mode" , async function ( ) {
917+ await enterDesignMode ( ) ;
918+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( true ) ;
919+
920+ _$ ( "#app-drawer-button" ) . trigger ( "click" ) ;
921+
922+ await awaitsFor ( function ( ) { return ! WorkspaceManager . isInDesignMode ( ) ; } ,
923+ "design mode to deactivate on app-drawer click" , 5000 ) ;
924+ await awaitsFor ( function ( ) { return toolsPanel ( ) . isVisible ( ) ; } ,
925+ "tools bottom panel to become visible" , 3000 ) ;
926+ } ) ;
927+
928+ it ( "should leave design mode untouched when #app-drawer-button is clicked in normal mode and toggle the tools panel" , async function ( ) {
929+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( false ) ;
930+
931+ _$ ( "#app-drawer-button" ) . trigger ( "click" ) ;
932+
933+ await awaitsFor ( function ( ) { return toolsPanel ( ) . isVisible ( ) ; } ,
934+ "tools bottom panel to become visible" , 3000 ) ;
935+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( false ) ;
936+ } ) ;
937+
938+ it ( "should exit design mode before mounting Find in Files bar" , async function ( ) {
939+ await enterDesignMode ( ) ;
940+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( true ) ;
941+
942+ CommandManager . execute ( Commands . CMD_FIND_IN_FILES ) ;
943+
944+ await awaitsFor ( function ( ) { return ! WorkspaceManager . isInDesignMode ( ) ; } ,
945+ "design mode to deactivate before Find-in-Files mounts" , 5000 ) ;
946+ await awaitsFor ( function ( ) { return _$ ( "#find-what" ) . length > 0 ; } ,
947+ "find-in-files bar to mount" , 3000 ) ;
948+ } ) ;
949+
950+ it ( "should stay in design mode and show a floating Quick Open bar when invoked in design mode" , async function ( ) {
951+ await enterDesignMode ( ) ;
952+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( true ) ;
953+
954+ CommandManager . execute ( Commands . NAVIGATE_QUICK_OPEN ) ;
955+
956+ // Quick Open uses a Spotlight-style floating bar in design mode
957+ // (rather than exiting) — users see the picker on top of the live
958+ // preview without losing design mode.
959+ await awaitsFor ( function ( ) {
960+ return _$ ( ".quick-open-floating-bar" ) . length > 0 ;
961+ } , "floating Quick Open bar to appear" , 3000 ) ;
962+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( true ) ;
963+
964+ // Close the picker.
965+ const doc = testWindow . document ;
966+ doc . dispatchEvent ( new testWindow . KeyboardEvent ( "keydown" , { keyCode : 27 , bubbles : true } ) ) ;
967+ await awaitsFor ( function ( ) {
968+ return _$ ( ".quick-open-floating-bar" ) . length === 0 ;
969+ } , "floating Quick Open bar to close" , 3000 ) ;
970+ } ) ;
971+
972+ it ( "should exit design mode when the git toolbar icon is clicked in design mode" , async function ( ) {
973+ const $gitIcon = _$ ( "#git-toolbar-icon" ) ;
974+ if ( ! $gitIcon . length || $gitIcon . hasClass ( "forced-hidden" ) ) {
975+ // Git isn't available in this test environment — skip.
976+ return ;
977+ }
978+ await enterDesignMode ( ) ;
979+ expect ( WorkspaceManager . isInDesignMode ( ) ) . toBe ( true ) ;
980+
981+ $gitIcon . trigger ( "click" ) ;
982+
983+ await awaitsFor ( function ( ) { return ! WorkspaceManager . isInDesignMode ( ) ; } ,
984+ "design mode to deactivate on git-icon click" , 5000 ) ;
985+ } ) ;
986+ } ) ;
831987 } ) ;
832988} ) ;
0 commit comments