@@ -30,6 +30,9 @@ export default class TableWrapper extends ComponentWrapper {
3030 return this . findByClassName ( styles [ 'thead-active' ] ) ! ;
3131 }
3232
33+ /**
34+ * Returns the header slot of the table.
35+ */
3336 findHeaderSlot ( ) : ElementWrapper | null {
3437 return this . findByClassName ( styles [ 'header-controls' ] ) ;
3538 }
@@ -42,70 +45,68 @@ export default class TableWrapper extends ComponentWrapper {
4245 return this . findHeaderSlot ( ) ;
4346 }
4447
48+ /**
49+ * Returns the footer slot of the table.
50+ */
4551 findFooterSlot ( ) : ElementWrapper | null {
4652 return this . containerWrapper . findFooter ( ) ;
4753 }
4854
4955 /**
50- * Returns all column header cells in the last header row (leaf columns).
51- * For tables without column grouping this is equivalent to querying `tr > *`.
56+ * Returns column header cells from the table's header region.
57+ *
58+ * By default, returns all cells in the last header row (leaf columns).
59+ * For tables without column grouping this is equivalent to querying all `<th>` elements.
5260 * For tables with column grouping this returns only the leaf-level column headers,
5361 * not the group header cells above them.
5462 *
55- * Pass `{ level }` to target a specific header row (1-based). Level 1 is the
56- * topmost row (group headers); the last level is always the leaf-column row.
57- *
58- * Pass `{ groupId }` to return only the leaf column headers that are direct
59- * children of the specified group. This uses the `data-column-group-id` attribute
60- * set on each leaf `<th>` by the renderer.
63+ * Both `level` and `groupId` can be combined to narrow the result set.
6164 *
62- * @param option.level 1-based index of the header row to query. Defaults to the last row.
65+ * @param option.level 1-based index of the header row to query. Level 1 is the topmost row
66+ * (group headers); the last level is always the leaf-column row. Defaults to the last row.
6367 * @param option.groupId ID of the parent group whose direct child columns to return.
68+ * Uses the `data-column-group-id` attribute set on each leaf `<th>` by the renderer.
6469 */
6570 findColumnHeaders (
6671 option : {
6772 groupId ?: string ;
6873 level ?: number ;
6974 } = { }
7075 ) : Array < ElementWrapper > {
71- if ( option . groupId !== undefined ) {
72- return this . findActiveTHead ( ) . findAll ( `tr:last-child > th[data-column-group-id="${ option . groupId } "]` ) ;
76+ const { groupId, level } = option ;
77+ const parts : string [ ] = [ ] ;
78+
79+ // Row selector
80+ if ( level !== undefined ) {
81+ parts . push ( `tr:nth-child(${ level } ) > ` ) ;
82+ } else if ( groupId === undefined ) {
83+ parts . push ( 'tr:last-child > ' ) ;
7384 }
74- if ( option . level !== undefined ) {
75- return this . findActiveTHead ( ) . findAll ( `tr:nth-child(${ option . level } ) > *` ) ;
85+
86+ // Element selector
87+ if ( groupId !== undefined ) {
88+ parts . push ( `th[data-column-group-id="${ groupId } "]` ) ;
89+ } else {
90+ parts . push ( '*' ) ;
7691 }
77- return this . findActiveTHead ( ) . findAll ( 'tr:last-child > *' ) ;
92+
93+ return this . findActiveTHead ( ) . findAll ( parts . join ( '' ) ) ;
7894 }
7995
8096 /**
81- * Returns the element the user clicks when resizing a column or group header.
82- * Targets the leaf-column header row by default.
97+ * Returns the element the user clicks when resizing a column.
8398 *
84- * Pass `{ level }` to target a specific header row (1-based).
99+ * Targets leaf-column headers (`scope="col"`), which reliably identifies
100+ * individual columns regardless of which `<tr>` they appear in. In grouped
101+ * tables, leaf columns may span multiple rows and sit in an earlier `<tr>`
102+ * rather than the last one.
85103 *
86- * Pass `{ groupId }` to return the resizer of the group header cell with that ID.
87- * When `groupId` is provided, `columnIndex` is ignored.
88- *
89- * @param columnIndex 1-based index of the column containing the resizer (ignored when groupId is set).
90- * @param option.level 1-based index of the header row to query. Defaults to the last row.
91- * @param option.groupId ID of the group header whose resizer to return.
104+ * @param columnIndex 1-based index of the leaf column containing the resizer.
92105 */
93- findColumnResizer (
94- columnIndex : number ,
95- option : {
96- groupId ?: string ;
97- level ?: number ;
98- } = { }
99- ) : ElementWrapper | null {
100- if ( option . groupId !== undefined ) {
101- // Use a CSS :has() selector to locate the colgroup <th> containing the group focus marker,
102- // then find the resizer inside it.
103- return this . findActiveTHead ( ) . find (
104- `th[scope="colgroup"]:has([data-focus-id="group-header-${ option . groupId } "]) .${ resizerStyles . resizer } `
105- ) ;
106- }
107- const rowSelector = option . level !== undefined ? `tr:nth-child(${ option . level } )` : 'tr:last-child' ;
108- return this . findActiveTHead ( ) . find ( `${ rowSelector } th:nth-child(${ columnIndex } ) .${ resizerStyles . resizer } ` ) ;
106+ findColumnResizer ( columnIndex : number ) : ElementWrapper | null {
107+ const leafHeaders = this . findActiveTHead ( ) . findAll ( 'th[scope="col"]' ) ;
108+ const header = leafHeaders [ columnIndex - 1 ] ;
109+ return header ?. find ( `.${ resizerStyles . resizer } ` ) ?? null ;
109110 }
110111
111112 /**
@@ -130,10 +131,16 @@ export default class TableWrapper extends ComponentWrapper {
130131 return this . findBodyCell ( rowIndex , columnIndex ) ?. find ( `.${ testUtilStyles [ 'body-cell-counter' ] } ` ) ?? null ;
131132 }
132133
134+ /**
135+ * Returns all table rows within the table body.
136+ */
133137 findRows ( ) : Array < ElementWrapper > {
134138 return this . findNativeTable ( ) . findAllByClassName ( styles . row ) ;
135139 }
136140
141+ /**
142+ * Returns all selected table rows.
143+ */
137144 findSelectedRows ( ) : Array < ElementWrapper > {
138145 return this . findAllByClassName ( styles [ 'row-selected' ] ) ;
139146 }
@@ -146,10 +153,16 @@ export default class TableWrapper extends ComponentWrapper {
146153 return this . findEmptySlot ( ) ;
147154 }
148155
156+ /**
157+ * Returns the empty state slot of the table.
158+ */
149159 findEmptySlot ( ) : ElementWrapper | null {
150160 return this . findByClassName ( styles . empty ) ;
151161 }
152162
163+ /**
164+ * Returns the loading text element of the table.
165+ */
153166 findLoadingText ( ) : ElementWrapper | null {
154167 return this . findByClassName ( styles . loading ) ;
155168 }
@@ -187,26 +200,44 @@ export default class TableWrapper extends ComponentWrapper {
187200 return this . findNativeTable ( ) . find ( `tbody tr:nth-child(${ rowIndex } ) .${ selectionStyles . root } ` ) ;
188201 }
189202
203+ /**
204+ * Returns the "select all" checkbox or radio button in the table header.
205+ */
190206 findSelectAllTrigger ( ) : ElementWrapper | null {
191207 return this . findActiveTHead ( ) . find ( `.${ selectionStyles . root } ` ) ;
192208 }
193209
210+ /**
211+ * Returns the text filter component used in the table.
212+ */
194213 findTextFilter ( ) : TextFilterWrapper | null {
195214 return this . findComponent ( `.${ styles [ 'tools-filtering' ] } ` , TextFilterWrapper ) ;
196215 }
197216
217+ /**
218+ * Returns the property filter component used in the table.
219+ */
198220 findPropertyFilter ( ) : PropertyFilterWrapper | null {
199221 return this . findComponent ( `.${ styles [ 'tools-filtering' ] } ` , PropertyFilterWrapper ) ;
200222 }
201223
224+ /**
225+ * Returns the filter slot of the table.
226+ */
202227 findFilterSlot ( ) : ElementWrapper | null {
203228 return this . findComponent ( `.${ styles [ 'tools-filtering' ] } ` , ElementWrapper ) ;
204229 }
205230
231+ /**
232+ * Returns the collection preferences component used in the table.
233+ */
206234 findCollectionPreferences ( ) : CollectionPreferencesWrapper | null {
207235 return this . findComponent ( `.${ styles [ 'tools-preferences' ] } ` , CollectionPreferencesWrapper ) ;
208236 }
209237
238+ /**
239+ * Returns the pagination component used in the table.
240+ */
210241 findPagination ( ) : PaginationWrapper | null {
211242 return this . findComponent ( `.${ styles [ 'tools-pagination' ] } ` , PaginationWrapper ) ;
212243 }
@@ -221,6 +252,9 @@ export default class TableWrapper extends ComponentWrapper {
221252 return this . findBodyCell ( rowIndex , columnIndex ) ?. findByClassName ( bodyCellStyles [ 'body-cell-editor' ] ) ?? null ;
222253 }
223254
255+ /**
256+ * Returns the currently active inline editing cell.
257+ */
224258 findEditingCell ( ) : ElementWrapper | null {
225259 return this . findNativeTable ( ) . findByClassName ( bodyCellStyles [ 'body-cell-edit-active' ] ) ;
226260 }
@@ -229,10 +263,16 @@ export default class TableWrapper extends ComponentWrapper {
229263 return this . findEditingCell ( ) ?. findByClassName ( bodyCellStyles [ 'body-cell-editor-controls' ] ) ?? null ;
230264 }
231265
266+ /**
267+ * Returns the save button of the currently active inline editing cell.
268+ */
232269 findEditingCellSaveButton ( ) : ElementWrapper | null {
233270 return this . _findEditingCellControls ( ) ?. find ( 'button[type="submit"]' ) ?? null ;
234271 }
235272
273+ /**
274+ * Returns the cancel button of the currently active inline editing cell.
275+ */
236276 findEditingCellCancelButton ( ) : ElementWrapper | null {
237277 return this . _findEditingCellControls ( ) ?. find ( 'button:first-child' ) ?? null ;
238278 }
0 commit comments