@@ -1197,8 +1197,8 @@ def test_filter_empty_state_and_recovery(page_at_app: Page):
11971197 assert recovered_rows .count () > 0
11981198
11991199
1200- def test_child_toggle_disabled_when_parent_collapsed (page_at_app : Page ):
1201- """Collapsing Region disables the Category toggle (no role=button, shows tooltip) ."""
1200+ def test_child_toggle_reflects_parent_collapsed_state (page_at_app : Page ):
1201+ """Collapsing Region keeps Category toggle interactive but shows collapsed state ."""
12021202 page = page_at_app
12031203 container = get_pivot (page , "test_pivot_dim_toggle" )
12041204 expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
@@ -1207,13 +1207,220 @@ def test_child_toggle_disabled_when_parent_collapsed(page_at_app: Page):
12071207 category_toggle = container .get_by_test_id ("pivot-dim-toggle-row-1-category" )
12081208
12091209 expect (category_toggle ).to_have_attribute ("role" , "button" )
1210+ expect (category_toggle ).to_have_attribute ("aria-expanded" , "true" )
12101211
12111212 region_toggle .click ()
12121213 page .wait_for_timeout (1500 )
12131214 expect (region_toggle ).to_have_attribute ("aria-expanded" , "false" )
12141215
1215- expect (category_toggle ).not_to_have_attribute ("role" , "button" , timeout = 5000 )
1216- expect (category_toggle ).to_have_attribute ("title" , "Expand Region first" )
1216+ expect (category_toggle ).to_have_attribute ("role" , "button" , timeout = 5000 )
1217+ expect (category_toggle ).to_have_attribute ("aria-expanded" , "false" )
1218+
1219+
1220+ # ---------------------------------------------------------------------------
1221+ # Hierarchy Layout
1222+ # ---------------------------------------------------------------------------
1223+
1224+
1225+ def test_hierarchy_layout_renders_breadcrumbs_and_subtotals (page_at_app : Page ):
1226+ """Hierarchy layout renders a single row-header column with breadcrumbs and subtotal rows."""
1227+ page = page_at_app
1228+ container = get_pivot (page , "test_pivot_hierarchy" )
1229+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1230+
1231+ breadcrumbs = container .locator ("[data-testid^='pivot-row-dim-breadcrumb-']" )
1232+ expect (breadcrumbs .first ).to_be_visible ()
1233+
1234+ subtotals = container .get_by_test_id ("pivot-subtotal-row" )
1235+ expect (subtotals .first ).to_be_visible ()
1236+
1237+ data_rows = container .get_by_test_id ("pivot-data-row" )
1238+ expect (data_rows .first ).to_be_visible ()
1239+ first_row_headers = data_rows .first .locator ("th" )
1240+ expect (first_row_headers ).to_have_count (1 )
1241+
1242+
1243+ def test_hierarchy_layout_breadcrumb_collapse (page_at_app : Page ):
1244+ """Clicking a hierarchy breadcrumb toggle collapses groups at that level."""
1245+ page = page_at_app
1246+ container = get_pivot (page , "test_pivot_hierarchy" )
1247+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1248+
1249+ data_rows_before = container .get_by_test_id ("pivot-data-row" ).count ()
1250+
1251+ region_toggle = container .get_by_test_id ("pivot-dim-toggle-row-0-region" )
1252+ expect (region_toggle ).to_have_attribute ("aria-expanded" , "true" )
1253+ region_toggle .click ()
1254+ page .wait_for_timeout (1500 )
1255+
1256+ expect (region_toggle ).to_have_attribute ("aria-expanded" , "false" )
1257+ data_rows_after = container .get_by_test_id ("pivot-data-row" ).count ()
1258+ assert data_rows_after < data_rows_before
1259+
1260+
1261+ def test_hierarchy_layout_subtotal_group_collapse (page_at_app : Page ):
1262+ """Collapsing a group via its subtotal-row toggle hides child data rows."""
1263+ page = page_at_app
1264+ container = get_pivot (page , "test_pivot_hierarchy" )
1265+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1266+
1267+ rows_before = container .get_by_test_id ("pivot-data-row" ).count ()
1268+
1269+ toggle = container .locator (
1270+ "[data-testid^='pivot-group-toggle-']"
1271+ ":not([data-testid$='-expand-all'])"
1272+ ":not([data-testid$='-collapse-all'])"
1273+ ).first
1274+ expect (toggle ).to_have_attribute ("aria-expanded" , "true" )
1275+ toggle .click ()
1276+ expect (toggle ).to_have_attribute ("aria-expanded" , "false" , timeout = 10000 )
1277+
1278+ rows_after = container .get_by_test_id ("pivot-data-row" ).count ()
1279+ assert rows_after < rows_before
1280+ expect (container .get_by_test_id ("pivot-subtotal-row" ).first ).to_be_visible ()
1281+
1282+
1283+ def test_hierarchy_layout_expand_collapse_all (page_at_app : Page ):
1284+ """Collapse All hides child rows; Expand All restores them in hierarchy mode."""
1285+ page = page_at_app
1286+ container = get_pivot (page , "test_pivot_hierarchy" )
1287+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1288+
1289+ expand_all = container .get_by_test_id ("pivot-group-toggle-expand-all" )
1290+ expand_all .scroll_into_view_if_needed ()
1291+ expand_all .evaluate ("el => el.click()" )
1292+
1293+ data_rows = container .get_by_test_id ("pivot-data-row" )
1294+ rows_expanded = data_rows .count ()
1295+ assert rows_expanded > 0
1296+
1297+ collapse_all = container .get_by_test_id ("pivot-group-toggle-collapse-all" )
1298+ collapse_all .scroll_into_view_if_needed ()
1299+ collapse_all .evaluate ("el => el.click()" )
1300+
1301+ expect (data_rows ).not_to_have_count (rows_expanded , timeout = 10000 )
1302+ rows_collapsed = data_rows .count ()
1303+ assert rows_collapsed < rows_expanded
1304+
1305+ expand_all .scroll_into_view_if_needed ()
1306+ expand_all .evaluate ("el => el.click()" )
1307+ expect (data_rows ).not_to_have_count (rows_collapsed , timeout = 10000 )
1308+
1309+
1310+ def test_hierarchy_layout_indented_row_headers (page_at_app : Page ):
1311+ """Data rows in hierarchy mode have a single row header with depth-based indentation."""
1312+ page = page_at_app
1313+ container = get_pivot (page , "test_pivot_hierarchy" )
1314+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1315+
1316+ data_rows = container .get_by_test_id ("pivot-data-row" )
1317+ expect (data_rows .first ).to_be_visible (timeout = 5000 )
1318+
1319+ for row in data_rows .all ()[:4 ]:
1320+ headers = row .locator ("th" )
1321+ expect (headers ).to_have_count (1 )
1322+
1323+ first_header = data_rows .first .locator ("th" )
1324+ padding = first_header .evaluate (
1325+ "el => parseInt(window.getComputedStyle(el.querySelector('span, div') || el).paddingLeft || '0')"
1326+ )
1327+ assert padding >= 0
1328+
1329+
1330+ def test_hierarchy_header_menu_no_subtotal_toggle (page_at_app : Page ):
1331+ """In hierarchy mode, the row-dimension header menu omits the subtotal toggle."""
1332+ page = page_at_app
1333+ container = get_pivot (page , "test_pivot_hierarchy" )
1334+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1335+
1336+ trigger = container .locator ("[data-testid^='header-menu-trigger-region']" ).first
1337+ expect (trigger ).to_be_visible (timeout = 5000 )
1338+
1339+ menu = open_header_menu (page , trigger , "header-menu-Region" )
1340+ expect (menu .get_by_test_id ("header-menu-sort" )).to_be_visible ()
1341+ expect (menu .get_by_test_id ("header-menu-subtotals" )).to_have_count (0 )
1342+
1343+ close_header_menu (page , "header-menu-Region" )
1344+
1345+
1346+ def test_hierarchy_per_measure_row_totals_excluded_shows_dash (page_at_app : Page ):
1347+ """In hierarchy mode, excluded measures in row totals show a dash placeholder."""
1348+ page = page_at_app
1349+ container = get_pivot (page , "test_pivot_hierarchy_totals" )
1350+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1351+
1352+ excluded = container .locator ('[data-testid="pivot-excluded-total"]' )
1353+ expect (excluded .first ).to_be_visible ()
1354+ expect (excluded .first ).to_have_text ("–" )
1355+
1356+ corner = container .get_by_test_id ("pivot-row-dim-label-hierarchy" )
1357+ expect (corner ).to_be_visible ()
1358+
1359+
1360+ def test_settings_switch_table_to_hierarchy_layout (page_at_app : Page ):
1361+ """Switching row layout from Table to Hierarchy via settings panel applies correctly."""
1362+ page = page_at_app
1363+ container = get_pivot (page , "test_pivot_subtotals" )
1364+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1365+
1366+ expect (container .get_by_test_id ("pivot-row-dim-label-hierarchy" )).to_have_count (0 )
1367+
1368+ panel = open_settings_panel (page , container )
1369+ hierarchy_btn = panel .get_by_test_id ("settings-row-layout-hierarchy" )
1370+ expect (hierarchy_btn ).to_be_visible ()
1371+ hierarchy_btn .click ()
1372+
1373+ panel .get_by_test_id ("settings-apply" ).click ()
1374+
1375+ expect (container .get_by_test_id ("pivot-row-dim-label-hierarchy" )).to_be_visible (
1376+ timeout = 10000
1377+ )
1378+
1379+ breadcrumbs = container .locator ("[data-testid^='pivot-row-dim-breadcrumb-']" )
1380+ expect (breadcrumbs .first ).to_be_visible (timeout = 5000 )
1381+
1382+
1383+ def test_settings_hierarchy_forces_subtotals_and_disables_repeat_labels (
1384+ page_at_app : Page ,
1385+ ):
1386+ """In hierarchy mode, subtotals checkbox is forced on and repeat labels is disabled."""
1387+ page = page_at_app
1388+ container = get_pivot (page , "test_pivot_subtotals" )
1389+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1390+
1391+ panel = open_settings_panel (page , container )
1392+ hierarchy_btn = panel .get_by_test_id ("settings-row-layout-hierarchy" )
1393+ hierarchy_btn .click ()
1394+
1395+ subtotals_input = panel .get_by_test_id ("settings-subtotals" ).locator ("input" )
1396+ expect (subtotals_input ).to_be_checked ()
1397+ expect (subtotals_input ).to_be_disabled ()
1398+
1399+ repeat_input = panel .get_by_test_id ("settings-repeat-labels" ).locator ("input" )
1400+ expect (repeat_input ).to_be_disabled ()
1401+
1402+ panel .get_by_test_id ("settings-cancel" ).click ()
1403+
1404+
1405+ def test_hierarchy_locked_mode_status_strings (page_at_app : Page ):
1406+ """Locked hierarchy pivot shows correct status labels in the settings panel."""
1407+ page = page_at_app
1408+ container = get_pivot (page , "test_pivot_hierarchy_locked" )
1409+ expect (container .get_by_test_id ("pivot-table" )).to_be_visible (timeout = 15000 )
1410+
1411+ panel = open_settings_panel (page , container )
1412+
1413+ expect (panel .get_by_test_id ("settings-subtotals-status" )).to_contain_text (
1414+ "Always On in Hierarchy"
1415+ )
1416+ expect (panel .get_by_test_id ("settings-row-layout-status" )).to_contain_text (
1417+ "Hierarchy"
1418+ )
1419+ expect (panel .get_by_test_id ("settings-repeat-labels-status" )).to_contain_text (
1420+ "N/A in Hierarchy"
1421+ )
1422+
1423+ panel .press ("Escape" )
12171424
12181425
12191426# ---------------------------------------------------------------------------
0 commit comments