@@ -13,8 +13,6 @@ import Title from "../../src/Title.js";
1313import Slider from "../../src/Slider.js" ;
1414import Button from "../../src/Button.js" ;
1515
16- // Porting Table.spec.js (wdio tests) to cypress tests
17- const ROLE_COLUMN_HEADER = "columnheader" ;
1816
1917describe ( "Table - Rendering" , ( ) => {
2018 function checkWidth ( id : string , expectedWidth : number ) {
@@ -302,7 +300,7 @@ describe("Table - Popin Mode", () => {
302300 const roleCondition = shouldBePoppedIn || shouldBeHidden ? "not.have.attr" : "have.attr" ;
303301
304302 cy . wrap ( $cell )
305- . should ( roleCondition , "role" , ROLE_COLUMN_HEADER ) ;
303+ . should ( roleCondition , "role" , "columnheader" ) ;
306304 cy . get ( "ui5-table-header-row" )
307305 . shadow ( )
308306 . find ( `slot[name=default-${ index + 1 } ]` )
@@ -1083,3 +1081,122 @@ describe("Table - HeaderCell", () => {
10831081 cy . get ( "@actionBclickTarget" ) . should ( "have.attr" , "tooltip" , "Generated by AI" ) ;
10841082 } ) ;
10851083} ) ;
1084+
1085+ describe ( "Table - Cell Merging" , ( ) => {
1086+ function mountMergedTable ( overflowMode : "Scroll" | "Popin" = "Scroll" ) {
1087+ cy . mount (
1088+ < Table id = "table" overflowMode = { overflowMode } >
1089+ < TableSelectionMulti id = "selection" slot = "features" > </ TableSelectionMulti >
1090+ < TableHeaderRow slot = "headerRow" >
1091+ < TableHeaderCell id = "colA" minWidth = "200px" > Column A</ TableHeaderCell >
1092+ < TableHeaderCell id = "colB" minWidth = "200px" > Column B</ TableHeaderCell >
1093+ < TableHeaderCell id = "colC" minWidth = "150px" > Column C</ TableHeaderCell >
1094+ </ TableHeaderRow >
1095+ < TableRow id = "row1" >
1096+ < TableCell id = "r1cA" > < Label > SAP</ Label > </ TableCell >
1097+ < TableCell id = "r1cB" > < Label > 100</ Label > </ TableCell >
1098+ < TableCell id = "r1cC" > < Label > X</ Label > </ TableCell >
1099+ </ TableRow >
1100+ < TableRow id = "row2" >
1101+ < TableCell id = "r2cA" merged > < Label > SAP</ Label > </ TableCell >
1102+ < TableCell id = "r2cB" > < Label > 200</ Label > </ TableCell >
1103+ < TableCell id = "r2cC" merged > < Label > X</ Label > </ TableCell >
1104+ </ TableRow >
1105+ < TableRow id = "row3" >
1106+ < TableCell id = "r3cA" merged > < Label > SAP</ Label > </ TableCell >
1107+ < TableCell id = "r3cB" > < Label > 300</ Label > </ TableCell >
1108+ < TableCell id = "r3cC" > < Label > Y</ Label > </ TableCell >
1109+ </ TableRow >
1110+ </ Table >
1111+ ) ;
1112+ }
1113+
1114+ it ( "should have transparent border on merged cells and selection cell" , ( ) => {
1115+ mountMergedTable ( ) ;
1116+
1117+ // Merged cell should have transparent top border
1118+ cy . get ( "#r2cA" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1119+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1120+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "pointer-events" , "none" ) ;
1121+
1122+ // Non-merged cell should not have transparent border
1123+ cy . get ( "#r2cB" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1124+ cy . get ( "#r2cB" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "1" ) ;
1125+
1126+ // Selection cell should have transparent border when first cell is merged
1127+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "have.attr" , "data-border-merged" ) ;
1128+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1129+
1130+ // Selection cell should NOT have transparent border when first cell is not merged
1131+ cy . get ( "#row1" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "not.have.attr" , "data-border-merged" ) ;
1132+ cy . get ( "#row1" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1133+ } ) ;
1134+
1135+ it ( "should disable merged styles when row has popin" , ( ) => {
1136+ mountMergedTable ( "Popin" ) ;
1137+
1138+ // At full width, merged styles should be active
1139+ cy . get ( "ui5-table" ) . invoke ( "css" , "width" , "600px" ) ;
1140+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1141+ cy . get ( "#r2cA" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1142+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1143+
1144+ // Shrink table to trigger popin
1145+ cy . get ( "ui5-table" ) . invoke ( "css" , "width" , "250px" ) ;
1146+ cy . wait ( 50 ) ;
1147+
1148+ // Merged cell border should fall back to normal border color (not transparent)
1149+ cy . get ( "#row2" ) . should ( "have.attr" , "_haspopin" ) ;
1150+ cy . get ( "#r2cA" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1151+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1152+
1153+ // Merged cell content should be fully visible (opacity back to 1)
1154+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "1" ) ;
1155+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "pointer-events" , "auto" ) ;
1156+
1157+ // Expand table again, merged styles should re-activate
1158+ cy . get ( "ui5-table" ) . invoke ( "css" , "width" , "600px" ) ;
1159+ cy . wait ( 50 ) ;
1160+
1161+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1162+ cy . get ( "#r2cA" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1163+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1164+ } ) ;
1165+
1166+ it ( "should toggle merged styles at runtime" , ( ) => {
1167+ mountMergedTable ( ) ;
1168+
1169+ // Initially merged
1170+ cy . get ( "#r3cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1171+
1172+ // Remove merged attribute
1173+ cy . get ( "#r3cA" ) . invoke ( "removeAttr" , "merged" ) ;
1174+ cy . get ( "#r3cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "1" ) ;
1175+ cy . get ( "#r3cA" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1176+
1177+ // Re-add merged attribute
1178+ cy . get ( "#r3cA" ) . invoke ( "prop" , "merged" , true ) ;
1179+ cy . get ( "#r3cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1180+ cy . get ( "#r3cA" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1181+ } ) ;
1182+
1183+ it ( "should disable merged styles on hover and focus" , ( ) => {
1184+ mountMergedTable ( ) ;
1185+
1186+ // Before hover: merged styles active
1187+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "have.css" , "opacity" , "0" ) ;
1188+ cy . get ( "#r2cA" ) . should ( "have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1189+
1190+ // On hover: merged cell content should become visible and border should restore
1191+ cy . get ( "#row2" ) . realHover ( ) ;
1192+ cy . get ( "#r2cA" ) . find ( "ui5-label" ) . should ( "not.have.css" , "opacity" , "0" ) ;
1193+ cy . get ( "#r2cA" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1194+ cy . get ( "#row2" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1195+
1196+ // On focus: merged cell content should become visible and border should restore
1197+ cy . get ( "#row3" ) . realClick ( ) ;
1198+ cy . get ( "#r3cA" ) . find ( "ui5-label" ) . should ( "not.have.css" , "opacity" , "0" ) ;
1199+ cy . get ( "#r3cA" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1200+ cy . get ( "#row3" ) . shadow ( ) . find ( "#selection-cell" ) . should ( "not.have.css" , "border-top-color" , "rgba(0, 0, 0, 0)" ) ;
1201+ } ) ;
1202+ } ) ;
0 commit comments