fix(playwright): drop dead bulkSelectColumnConfig that duplicated data-test

Round-2 commit f14f393d1a wrapped antd's rowSelection checkboxes with
data-test="header-toggle-all" / "row-select-checkbox", but the older
bulkSelectColumnConfig in ListView.tsx was still being prepended as a
column. antd's Table consumed its Header function via mapColumns and
rendered the Checkbox inside <tbody> as a ghost row, producing a second
element with data-test="header-toggle-all" and breaking all bulk-select
Playwright tests with a strict-mode "resolved to 2 elements" error.

antd's rowSelection owns checkbox rendering; react-table's useRowSelect
tracks selection state via toggleRowSelected / toggleAllRowsSelected
without needing a dedicated column. Remove bulkSelectColumnConfig and
its plumbing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joe Li
2026-05-20 16:48:35 -07:00
parent f14f393d1a
commit d2b850d615
3 changed files with 7 additions and 41 deletions

View File

@@ -198,9 +198,7 @@ function TableCollection<T extends object>({
// antd Table's `rowSelection` API renders its own checkbox column;
// wrap the header and per-row checkboxes with stable `data-test`
// attributes so Playwright selectors (which previously targeted
// `bulkSelectColumnConfig` in ListView — a column that no longer
// reaches the rendered DOM) can resolve them.
// attributes so Playwright selectors can resolve them.
return {
selectedRowKeys,
onSelect: (record, selected) => {

View File

@@ -33,7 +33,6 @@ import BulkTagModal from 'src/features/tags/BulkTagModal';
import {
Button,
Tooltip,
Checkbox,
Icons,
EmptyState,
Loading,
@@ -149,25 +148,6 @@ const BulkSelectWrapper = styled(Alert)`
`}
`;
const bulkSelectColumnConfig = {
Cell: ({ row }: any) => (
<Checkbox
{...row.getToggleRowSelectedProps()}
id={row.id}
data-test="row-select-checkbox"
/>
),
Header: ({ getToggleAllRowsSelectedProps }: any) => (
<Checkbox
{...getToggleAllRowsSelectedProps()}
id="header-toggle-all"
data-test="header-toggle-all"
/>
),
id: 'selection',
size: 'sm',
};
const ViewModeContainer = styled.div`
${({ theme }) => `
padding-right: ${theme.sizeUnit * 4}px;
@@ -327,8 +307,6 @@ export function ListView<T extends object = any>({
state: { pageIndex, pageSize, internalFilters, sortBy, viewMode },
query,
} = useListViewState({
bulkSelectColumnConfig,
bulkSelectMode: bulkSelectEnabled && Boolean(bulkActions.length),
columns,
count,
data,

View File

@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import { useEffect, useMemo, useState, ReactNode } from 'react';
import { useEffect, useMemo, useState } from 'react';
import {
useFilters,
usePagination,
@@ -192,13 +192,7 @@ interface UseListViewConfig {
count: number;
initialPageSize: number;
initialSort?: SortColumn[];
bulkSelectMode?: boolean;
initialFilters?: Filter[];
bulkSelectColumnConfig?: {
id: string;
Header: (conf: any) => ReactNode;
Cell: (conf: any) => ReactNode;
};
renderCard?: boolean;
defaultViewMode?: ViewModeType;
}
@@ -211,8 +205,6 @@ export function useListViewState({
initialPageSize,
initialFilters = [],
initialSort = [],
bulkSelectMode = false,
bulkSelectColumnConfig,
renderCard = false,
defaultViewMode = 'card',
}: UseListViewConfig) {
@@ -246,13 +238,11 @@ export function useListViewState({
(renderCard ? defaultViewMode : 'table'),
);
const columnsWithSelect = useMemo(() => {
const columnsWithFilter = useMemo(
// add exact filter type so filters with falsy values are not filtered out
const columnsWithFilter = columns.map(f => ({ ...f, filter: 'exact' }));
return bulkSelectMode
? [bulkSelectColumnConfig, ...columnsWithFilter]
: columnsWithFilter;
}, [bulkSelectMode, columns]);
() => columns.map(f => ({ ...f, filter: 'exact' })),
[columns],
);
const {
getTableProps,
@@ -271,7 +261,7 @@ export function useListViewState({
state: { pageIndex, pageSize, sortBy, filters },
} = useTable(
{
columns: columnsWithSelect,
columns: columnsWithFilter,
data,
disableFilters: true,
disableSortRemove: true,