@@ -11,6 +11,10 @@ import TimingParentLight from 'timing/parentLight';
1111import ReorderingList from 'reordering/list' ;
1212import ReorderingListLight from 'reordering/listLight' ;
1313import Details from 'x/details' ;
14+ import MutationsParent from 'mutations/parent' ;
15+ import MutationsParentLight from 'mutations/parentLight' ;
16+
17+ import { extractDataIds } from 'test-utils' ;
1418
1519function resetTimingBuffer ( ) {
1620 window . timingBuffer = [ ] ;
@@ -319,11 +323,18 @@ describe('connectedCallback/renderedCallback timing when reconnected', () => {
319323 resetTimingBuffer ( ) ;
320324
321325 document . body . appendChild ( elm ) ;
322- expect ( window . timingBuffer ) . toEqual (
323- ! lwcRuntimeFlags . DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE
324- ? [ 'parent:connectedCallback' , 'child:connectedCallback' ]
325- : [ 'parent:connectedCallback' ]
326- ) ;
326+
327+ const expected = [ 'parent:connectedCallback' ] ;
328+
329+ if ( lwcRuntimeFlags . DISABLE_DETACHED_REHYDRATION ) {
330+ expected . push ( 'parent:renderedCallback' ) ;
331+ }
332+
333+ if ( ! lwcRuntimeFlags . DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE ) {
334+ expected . push ( 'child:connectedCallback' ) ;
335+ }
336+
337+ expect ( window . timingBuffer ) . toEqual ( expected ) ;
327338 } ) ;
328339 } ) ;
329340 } ) ;
@@ -436,3 +447,118 @@ describe('attributeChangedCallback', () => {
436447 expect ( details . getAttribute ( 'open' ) ) . toBeNull ( ) ;
437448 } ) ;
438449} ) ;
450+
451+ describe ( 'child mutations - scheduled rehydration' , ( ) => {
452+ const scenarios = [
453+ {
454+ testName : 'shadow' ,
455+ tagName : 'mutations-parent' ,
456+ Ctor : MutationsParent ,
457+ } ,
458+ {
459+ testName : 'light' ,
460+ tagName : 'mutations-parent-light' ,
461+ Ctor : MutationsParentLight ,
462+ } ,
463+ ] ;
464+
465+ scenarios . forEach ( ( { testName, tagName, Ctor } ) => {
466+ describe ( testName , ( ) => {
467+ it ( 'connect' , async ( ) => {
468+ const elm = createElement ( tagName , { is : Ctor } ) ;
469+ document . body . appendChild ( elm ) ;
470+
471+ expect ( window . timingBuffer ) . toEqual ( [
472+ 'parent:connectedCallback' ,
473+ 'child1:connectedCallback' ,
474+ 'grand:child1:connectedCallback' ,
475+ 'grand:child1:renderedCallback' ,
476+ 'child1:renderedCallback' ,
477+ 'parent:renderedCallback' ,
478+ ] ) ;
479+ } ) ;
480+
481+ it ( 'connect/mutate-child' , async ( ) => {
482+ const elm = createElement ( tagName , { is : Ctor } ) ;
483+ document . body . appendChild ( elm ) ;
484+ resetTimingBuffer ( ) ;
485+
486+ const ids = extractDataIds ( elm ) ;
487+ ids . child1 . addChild ( ) ;
488+
489+ await Promise . resolve ( ) ;
490+
491+ expect ( window . timingBuffer ) . toEqual ( [
492+ 'grand:child2:connectedCallback' ,
493+ 'grand:child2:renderedCallback' ,
494+ 'child1:renderedCallback' ,
495+ ] ) ;
496+ } ) ;
497+
498+ it ( 'connect/mutate-child/disconnect-child' , async ( ) => {
499+ const elm = createElement ( tagName , { is : Ctor } ) ;
500+ document . body . appendChild ( elm ) ;
501+ resetTimingBuffer ( ) ;
502+
503+ const ids = extractDataIds ( elm ) ;
504+ // Mutate child - grand child 2
505+ ids . child1 . addChild ( ) ;
506+ // Disconnect the child that was just mutated
507+ elm . disconnectLastChild ( ) ;
508+
509+ await Promise . resolve ( ) ;
510+
511+ const expected = [
512+ 'child1:disconnectedCallback' ,
513+ 'grand:child1:disconnectedCallback' ,
514+ 'parent:renderedCallback' ,
515+ ] ;
516+
517+ if (
518+ lwcRuntimeFlags . DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE &&
519+ ! lwcRuntimeFlags . DISABLE_DETACHED_REHYDRATION
520+ ) {
521+ // These are fired in the children of the disconnected child
522+ expected . push (
523+ 'grand:child2:connectedCallback' ,
524+ 'grand:child2:renderedCallback'
525+ ) ;
526+ }
527+
528+ expect ( window . timingBuffer ) . toEqual ( expected ) ;
529+ } ) ;
530+
531+ it ( 'connect/disconnect-child/mutate-child' , async ( ) => {
532+ const elm = createElement ( tagName , { is : Ctor } ) ;
533+ document . body . appendChild ( elm ) ;
534+ resetTimingBuffer ( ) ;
535+
536+ const ids = extractDataIds ( elm ) ;
537+ elm . disconnectLastChild ( ) ;
538+ // Mutate child that was just disconnected
539+ ids . child1 . addChild ( ) ;
540+
541+ await Promise . resolve ( ) ;
542+
543+ const expected = [
544+ 'child1:disconnectedCallback' ,
545+ 'grand:child1:disconnectedCallback' ,
546+ 'parent:renderedCallback' ,
547+ ] ;
548+
549+ if (
550+ lwcRuntimeFlags . DISABLE_NATIVE_CUSTOM_ELEMENT_LIFECYCLE &&
551+ ! lwcRuntimeFlags . DISABLE_DETACHED_REHYDRATION
552+ ) {
553+ // These are fired in the children of the disconnected child
554+ expected . push (
555+ 'grand:child2:connectedCallback' ,
556+ 'grand:child2:renderedCallback'
557+ ) ;
558+ }
559+
560+ expect ( window . timingBuffer ) . toEqual ( expected ) ;
561+ } ) ;
562+ } ) ;
563+ } ) ;
564+ } ) ;
0 commit comments