@@ -155,6 +155,21 @@ describeWithMockConnection('ConsoleView', () => {
155155 target . model ( SDK . RuntimeModel . RuntimeModel ) , Protocol . Log . LogEntrySource . Javascript , level , message , { type} ) ;
156156 }
157157
158+ let globalMessageTimestamp = 0 ;
159+
160+ function addMessage (
161+ consoleModel : SDK . ConsoleModel . ConsoleModel ,
162+ target : SDK . Target . Target ,
163+ message : string ,
164+ type : SDK . ConsoleModel . MessageType ,
165+ level : Protocol . Log . LogEntryLevel ,
166+ timestamp ?: number ,
167+ ) {
168+ const consoleMessage = createConsoleMessage ( target , message , type , level ) ;
169+ consoleMessage . timestamp = timestamp ?? ++ globalMessageTimestamp ;
170+ consoleModel . addMessage ( consoleMessage ) ;
171+ }
172+
158173 it ( 'can save to file' , async ( ) => {
159174 const tabTarget = createTarget ( { type : SDK . Target . Type . TAB } ) ;
160175 createTarget ( { parentTarget : tabTarget , subtype : 'prerender' } ) ;
@@ -526,13 +541,6 @@ describeWithMockConnection('ConsoleView', () => {
526541 }
527542 } ) ;
528543
529- function addMessage (
530- message : string , type : Protocol . Runtime . ConsoleAPICalledEventType , level : Protocol . Log . LogEntryLevel ) {
531- const consoleMessage = createConsoleMessage ( target , message , type , level ) ;
532- consoleMessage . timestamp = ++ messageTimestamp ;
533- consoleModel ! . addMessage ( consoleMessage ) ;
534- }
535-
536544 for ( const level
537545 of [ Protocol . Log . LogEntryLevel . Error ,
538546 Protocol . Log . LogEntryLevel . Warning ,
@@ -548,9 +556,14 @@ describeWithMockConnection('ConsoleView', () => {
548556 renderElementIntoDOM ( consoleView ) ;
549557
550558 addMessage (
551- 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed , Protocol . Log . LogEntryLevel . Info ) ;
552- addMessage ( 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log , level ) ;
553- addMessage ( '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup , Protocol . Log . LogEntryLevel . Info ) ;
559+ consoleModel ! , target , 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
560+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
561+ addMessage (
562+ consoleModel ! , target , 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log , level ,
563+ ++ messageTimestamp ) ;
564+ addMessage (
565+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
566+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
554567
555568 const messages = await getConsoleMessages ( ) ;
556569 assert . include ( messages , 'group' ) ;
@@ -565,9 +578,15 @@ describeWithMockConnection('ConsoleView', () => {
565578 consoleView . markAsRoot ( ) ;
566579 renderElementIntoDOM ( consoleView ) ;
567580
568- addMessage ( 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup , Protocol . Log . LogEntryLevel . Info ) ;
569- addMessage ( 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log , level ) ;
570- addMessage ( '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup , Protocol . Log . LogEntryLevel . Info ) ;
581+ addMessage (
582+ consoleModel ! , target , 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
583+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
584+ addMessage (
585+ consoleModel ! , target , 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log , level ,
586+ ++ messageTimestamp ) ;
587+ addMessage (
588+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
589+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
571590
572591 const messages = await getConsoleMessages ( ) ;
573592 assert . include ( messages , 'group' ) ;
@@ -583,9 +602,15 @@ describeWithMockConnection('ConsoleView', () => {
583602 consoleView . markAsRoot ( ) ;
584603 renderElementIntoDOM ( consoleView ) ;
585604
586- addMessage ( 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup , Protocol . Log . LogEntryLevel . Info ) ;
587- addMessage ( 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log , Protocol . Log . LogEntryLevel . Error ) ;
588- addMessage ( '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup , Protocol . Log . LogEntryLevel . Info ) ;
605+ addMessage (
606+ consoleModel ! , target , 'group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
607+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
608+ addMessage (
609+ consoleModel ! , target , 'message' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
610+ Protocol . Log . LogEntryLevel . Error , ++ messageTimestamp ) ;
611+ addMessage (
612+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
613+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
589614
590615 const messages = await getConsoleMessages ( ) ;
591616 assert . notInclude ( messages , 'group' ) ;
@@ -603,11 +628,21 @@ describeWithMockConnection('ConsoleView', () => {
603628 console.groupEnd() // B
604629 console.groupEnd() // A
605630 */
606- addMessage ( 'A' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup , Protocol . Log . LogEntryLevel . Info ) ;
607- addMessage ( 'B' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup , Protocol . Log . LogEntryLevel . Info ) ;
608- addMessage ( 'C' , Protocol . Runtime . ConsoleAPICalledEventType . Log , Protocol . Log . LogEntryLevel . Info ) ;
609- addMessage ( '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup , Protocol . Log . LogEntryLevel . Info ) ;
610- addMessage ( '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup , Protocol . Log . LogEntryLevel . Info ) ;
631+ addMessage (
632+ consoleModel ! , target , 'A' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
633+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
634+ addMessage (
635+ consoleModel ! , target , 'B' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
636+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
637+ addMessage (
638+ consoleModel ! , target , 'C' , Protocol . Runtime . ConsoleAPICalledEventType . Log , Protocol . Log . LogEntryLevel . Info ,
639+ ++ messageTimestamp ) ;
640+ addMessage (
641+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
642+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
643+ addMessage (
644+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
645+ Protocol . Log . LogEntryLevel . Info , ++ messageTimestamp ) ;
611646
612647 let messages = await getConsoleMessages ( ) ;
613648 assert . include ( messages , 'A' , 'A should be visible' ) ;
@@ -625,4 +660,163 @@ describeWithMockConnection('ConsoleView', () => {
625660 assert . notInclude ( messages , 'C' , 'C should be hidden after collapsing parent A' ) ;
626661 } ) ;
627662 } ) ;
663+
664+ describe ( 'collapse all and expand all' , ( ) => {
665+ let target : ReturnType < typeof createTarget > ;
666+ let consoleModel : SDK . ConsoleModel . ConsoleModel | null ;
667+
668+ beforeEach ( ( ) => {
669+ target = createTarget ( ) ;
670+ SDK . TargetManager . TargetManager . instance ( ) . setScopeTarget ( target ) ;
671+ consoleModel = target . model ( SDK . ConsoleModel . ConsoleModel ) ;
672+ assert . exists ( consoleModel ) ;
673+ consoleView . markAsRoot ( ) ;
674+ renderElementIntoDOM ( consoleView ) ;
675+ } ) ;
676+
677+ it ( 'collapseAll collapses expanded groups' , async ( ) => {
678+ addMessage (
679+ consoleModel ! , target , 'group 1' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
680+ Protocol . Log . LogEntryLevel . Info ) ;
681+ addMessage (
682+ consoleModel ! , target , 'inner message 1' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
683+ Protocol . Log . LogEntryLevel . Info ) ;
684+ addMessage (
685+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
686+ Protocol . Log . LogEntryLevel . Info ) ;
687+ addMessage (
688+ consoleModel ! , target , 'group 2' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
689+ Protocol . Log . LogEntryLevel . Info ) ;
690+ addMessage (
691+ consoleModel ! , target , 'inner message 2' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
692+ Protocol . Log . LogEntryLevel . Info ) ;
693+ addMessage (
694+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
695+ Protocol . Log . LogEntryLevel . Info ) ;
696+ await consoleView . getScheduledRefreshPromiseForTest ( ) ;
697+
698+ // Both groups are expanded by default, so all group headers and messages are visible.
699+ assert . strictEqual ( consoleView . itemCount ( ) , 4 ) ;
700+
701+ consoleView . collapseAll ( ) ;
702+
703+ // After collapsing, only the two group headers should be visible.
704+ assert . strictEqual ( consoleView . itemCount ( ) , 2 ) ;
705+ } ) ;
706+
707+ it ( 'expandAll expands collapsed groups' , async ( ) => {
708+ addMessage (
709+ consoleModel ! , target , 'group 1' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
710+ Protocol . Log . LogEntryLevel . Info ) ;
711+ addMessage (
712+ consoleModel ! , target , 'inner message 1' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
713+ Protocol . Log . LogEntryLevel . Info ) ;
714+ addMessage (
715+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
716+ Protocol . Log . LogEntryLevel . Info ) ;
717+ addMessage (
718+ consoleModel ! , target , 'group 2' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
719+ Protocol . Log . LogEntryLevel . Info ) ;
720+ addMessage (
721+ consoleModel ! , target , 'inner message 2' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
722+ Protocol . Log . LogEntryLevel . Info ) ;
723+ addMessage (
724+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
725+ Protocol . Log . LogEntryLevel . Info ) ;
726+ await consoleView . getScheduledRefreshPromiseForTest ( ) ;
727+
728+ // Both groups are collapsed by default, so only group headers are visible.
729+ assert . strictEqual ( consoleView . itemCount ( ) , 2 ) ;
730+
731+ consoleView . expandAll ( ) ;
732+
733+ // After expanding, all group headers and messages are visible.
734+ assert . strictEqual ( consoleView . itemCount ( ) , 4 ) ;
735+ } ) ;
736+
737+ it ( 'collapseAll then expandAll round-trips groups correctly' , async ( ) => {
738+ addMessage (
739+ consoleModel ! , target , 'expanded group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
740+ Protocol . Log . LogEntryLevel . Info ) ;
741+ addMessage (
742+ consoleModel ! , target , 'expanded message' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
743+ Protocol . Log . LogEntryLevel . Info ) ;
744+ addMessage (
745+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
746+ Protocol . Log . LogEntryLevel . Info ) ;
747+ addMessage (
748+ consoleModel ! , target , 'collapsed group' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
749+ Protocol . Log . LogEntryLevel . Info ) ;
750+ addMessage (
751+ consoleModel ! , target , 'collapsed message' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
752+ Protocol . Log . LogEntryLevel . Info ) ;
753+ addMessage (
754+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
755+ Protocol . Log . LogEntryLevel . Info ) ;
756+ await consoleView . getScheduledRefreshPromiseForTest ( ) ;
757+
758+ // Mixed state: one expanded group and one collapsed group.
759+ assert . strictEqual ( consoleView . itemCount ( ) , 3 ) ;
760+
761+ consoleView . collapseAll ( ) ;
762+ assert . strictEqual ( consoleView . itemCount ( ) , 2 ) ;
763+
764+ consoleView . expandAll ( ) ;
765+ assert . strictEqual ( consoleView . itemCount ( ) , 4 ) ;
766+ } ) ;
767+
768+ it ( 'collapseAll collapses nested groups' , async ( ) => {
769+ addMessage (
770+ consoleModel ! , target , 'outer' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
771+ Protocol . Log . LogEntryLevel . Info ) ;
772+ addMessage (
773+ consoleModel ! , target , 'inner' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroup ,
774+ Protocol . Log . LogEntryLevel . Info ) ;
775+ addMessage (
776+ consoleModel ! , target , 'deep message' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
777+ Protocol . Log . LogEntryLevel . Info ) ;
778+ addMessage (
779+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
780+ Protocol . Log . LogEntryLevel . Info ) ;
781+ addMessage (
782+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
783+ Protocol . Log . LogEntryLevel . Info ) ;
784+ await consoleView . getScheduledRefreshPromiseForTest ( ) ;
785+
786+ // All three are visible: outer, inner, deep message.
787+ assert . strictEqual ( consoleView . itemCount ( ) , 3 ) ;
788+
789+ consoleView . collapseAll ( ) ;
790+
791+ // After collapse, only outer is visible.
792+ assert . strictEqual ( consoleView . itemCount ( ) , 1 ) ;
793+ } ) ;
794+
795+ it ( 'expandAll expands nested groups' , async ( ) => {
796+ addMessage (
797+ consoleModel ! , target , 'outer' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
798+ Protocol . Log . LogEntryLevel . Info ) ;
799+ addMessage (
800+ consoleModel ! , target , 'inner' , Protocol . Runtime . ConsoleAPICalledEventType . StartGroupCollapsed ,
801+ Protocol . Log . LogEntryLevel . Info ) ;
802+ addMessage (
803+ consoleModel ! , target , 'deep message' , Protocol . Runtime . ConsoleAPICalledEventType . Log ,
804+ Protocol . Log . LogEntryLevel . Info ) ;
805+ addMessage (
806+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
807+ Protocol . Log . LogEntryLevel . Info ) ;
808+ addMessage (
809+ consoleModel ! , target , '' , Protocol . Runtime . ConsoleAPICalledEventType . EndGroup ,
810+ Protocol . Log . LogEntryLevel . Info ) ;
811+ await consoleView . getScheduledRefreshPromiseForTest ( ) ;
812+
813+ // All collapsed, only outer visible.
814+ assert . strictEqual ( consoleView . itemCount ( ) , 1 ) ;
815+
816+ consoleView . expandAll ( ) ;
817+
818+ // After expanding, all three are visible.
819+ assert . strictEqual ( consoleView . itemCount ( ) , 3 ) ;
820+ } ) ;
821+ } ) ;
628822} ) ;
0 commit comments