1313
1414import { strictEqual , ok , deepStrictEqual } from 'node:assert' ;
1515import { delay } from '../../testUtils/delay.js' ;
16- import { editedMockedLayout } from '../../setup/seeders/layout-show/json-file-mock.js' ;
16+ import {
17+ editedManyObjectsMockedLayout ,
18+ editedMockedLayout ,
19+ } from '../../setup/seeders/layout-show/json-file-mock.js' ;
1720import { getElementCenter } from '../../testUtils/dragAndDrop.js' ;
1821
1922/**
@@ -187,7 +190,7 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
187190 const leftStyle = await page . evaluate ( ( ) => document . querySelector ( '#subcanvas .dropdown-menu' ) . style . left ) ;
188191
189192 strictEqual ( leftStyle , '0.1em' ) ;
190- }
193+ } ,
191194 ) ;
192195
193196 await testParent . test ( 'should have second tab to be empty (according to demo data)' , { timeout } , async ( ) => {
@@ -349,7 +352,7 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
349352 elements . map ( ( element ) => element . textContent . trim ( ) ) ) ;
350353
351354 strictEqual ( tabNames [ 1 ] , originalTabNames [ 0 ] ) ;
352- }
355+ } ,
353356 ) ;
354357
355358 await testParent . test (
@@ -446,9 +449,69 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
446449 } ,
447450 ) ;
448451
452+ await testParent . test (
453+ 'should display all objects even when the JSON has out of bound entries' ,
454+ { timeout : 15000 } ,
455+ async ( ) => {
456+ const EXPECTED_LAYOUT_OBJECT_COUNT = editedManyObjectsMockedLayout . tabs [ 0 ] . objects . length ;
457+
458+ /**
459+ * Counts the number of visible child elements within #subcanvas.
460+ * Visibility is defined as being within the viewport.
461+ * @returns {number } The amount of visible rendered objects
462+ */
463+ const getVisibleObjectCount = async ( ) =>
464+ await page . evaluate ( ( ) => {
465+ const container = document . querySelector ( '#subcanvas' ) ;
466+ if ( ! container ) {
467+ return 0 ;
468+ }
469+
470+ // Count elements that intersect with the viewport
471+ return Array . from ( container . children ) . filter ( ( child ) => {
472+ const rect = child . getBoundingClientRect ( ) ;
473+ return rect . bottom >= 0 && rect . top >= 0 && rect . left >= 0 && rect . right <= window . innerWidth ;
474+ } ) . length ;
475+ } ) ;
476+
477+ // Ensure we are on the main tab
478+ await page . locator ( '#tab-0' ) . click ( ) ;
479+ await delay ( 100 ) ;
480+
481+ const pencilButtonPath = '.btn-group > div > button' ;
482+ await page . locator ( pencilButtonPath ) . click ( ) ;
483+
484+ const editViaJSONButtonPath = '#editByJson' ;
485+ await page . locator ( editViaJSONButtonPath ) . click ( ) ;
486+
487+ const textareaPath = '#layout-json-editor' ;
488+ const mockedJSON = JSON . stringify ( editedManyObjectsMockedLayout ) ;
489+ await page . locator ( textareaPath ) . fill ( mockedJSON ) ;
490+
491+ const updateButtonPath = '#updateLayoutButton' ;
492+ await page . locator ( updateButtonPath ) . click ( ) ;
493+ await delay ( 100 ) ;
494+
495+ strictEqual (
496+ await getVisibleObjectCount ( ) ,
497+ EXPECTED_LAYOUT_OBJECT_COUNT ,
498+ `Expected ${ EXPECTED_LAYOUT_OBJECT_COUNT } rendered objects after JSON update` ,
499+ ) ;
500+
501+ await page . reload ( { waitUntil : 'networkidle0' } ) ;
502+ await delay ( 100 ) ;
503+
504+ strictEqual (
505+ await getVisibleObjectCount ( ) ,
506+ EXPECTED_LAYOUT_OBJECT_COUNT ,
507+ `Expected ${ EXPECTED_LAYOUT_OBJECT_COUNT } rendered objects after page reload` ,
508+ ) ;
509+ } ,
510+ ) ;
511+
449512 await testParent . test (
450513 'should update layout when clicking "Update layout"' ,
451- { timeout } ,
514+ { timeout : 10000 } ,
452515 async ( ) => {
453516 const pencilButtonPath = '.btn-group > div > button' ;
454517 await page . locator ( pencilButtonPath ) . click ( ) ;
@@ -474,16 +537,20 @@ export const layoutShowTests = async (url, page, timeout = 5000, testParent) =>
474537 ) ;
475538
476539 await testParent . test ( 'should change tab after set tabInterval' , { timeout : 15000 } , async ( ) => {
540+ // Ensure we are on the 'a' tab
541+ await page . locator ( '#tab-1' ) . click ( ) ;
542+ await delay ( 100 ) ;
543+
477544 const location = await page . evaluate ( ( ) => window . location ) ;
478545 strictEqual ( location . search , `?page=layoutShow&layoutId=${ LAYOUT_ID } &tab=a` ) ;
479- await delay ( 11000 ) ;
546+ await delay ( 11111 ) ;
480547 const location2 = await page . evaluate ( ( ) => window . location ) ;
481548 strictEqual ( location2 . search , `?page=layoutShow&layoutId=${ LAYOUT_ID } &tab=test` ) ;
482549 } ) ;
483550
484551 await testParent . test (
485552 'should update layout name in sidebar when name is changed and saved via JSON editor' ,
486- { timeout } ,
553+ { timeout : 10000 } ,
487554 async ( ) => {
488555 const originalSidebarName = await page . evaluate ( ( ) => {
489556 const sidebarLayoutLink = document . querySelector ( 'nav a.menu-item.w-wrapped.selected span:nth-child(2)' ) ;
0 commit comments