mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[TableListView] Fix regression when resetting search (#162034)
This commit is contained in:
parent
72907cfe1e
commit
c6deb252b2
8 changed files with 370 additions and 80 deletions
|
@ -47,23 +47,23 @@ export const TabbedTableListView = ({
|
|||
[activeTabId, tabs]
|
||||
);
|
||||
|
||||
const onFetchSuccess = useCallback(() => {
|
||||
setHasInitialFetchReturned(true);
|
||||
}, []);
|
||||
|
||||
const [tableList, setTableList] = useState<React.ReactNode>(null);
|
||||
|
||||
useEffect(() => {
|
||||
async function loadTableList() {
|
||||
const newTableList = await getActiveTab().getTableList({
|
||||
onFetchSuccess: () => {
|
||||
if (!hasInitialFetchReturned) {
|
||||
setHasInitialFetchReturned(true);
|
||||
}
|
||||
},
|
||||
onFetchSuccess,
|
||||
setPageDataTestSubject,
|
||||
});
|
||||
setTableList(newTableList);
|
||||
}
|
||||
|
||||
loadTableList();
|
||||
}, [hasInitialFetchReturned, activeTabId, tabs, getActiveTab]);
|
||||
}, [activeTabId, tabs, getActiveTab, onFetchSuccess]);
|
||||
|
||||
return (
|
||||
<KibanaPageTemplate panelled data-test-subj={pageDataTestSubject}>
|
||||
|
|
|
@ -82,10 +82,8 @@ export const TableListView = <T extends UserContentCommonSchema>({
|
|||
const [pageDataTestSubject, setPageDataTestSubject] = useState<string>();
|
||||
|
||||
const onFetchSuccess = useCallback(() => {
|
||||
if (!hasInitialFetchReturned) {
|
||||
setHasInitialFetchReturned(true);
|
||||
}
|
||||
}, [hasInitialFetchReturned]);
|
||||
setHasInitialFetchReturned(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<PageTemplate panelled data-test-subj={pageDataTestSubject}>
|
||||
|
|
|
@ -39,11 +39,21 @@ export function getReducer<T extends UserContentCommonSchema>() {
|
|||
}
|
||||
}
|
||||
|
||||
let hasNoItems = state.hasNoItems;
|
||||
|
||||
const hasQuery = state.searchQuery.text !== '';
|
||||
if (hasQuery) {
|
||||
hasNoItems = undefined;
|
||||
} else {
|
||||
hasNoItems = items.length === 0;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
hasInitialFetchReturned: true,
|
||||
isFetchingItems: false,
|
||||
items,
|
||||
hasNoItems,
|
||||
totalItems: action.data.response.total,
|
||||
hasUpdatedAtMetadata,
|
||||
tableSort: tableSort ?? state.tableSort,
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import type { TestBed } from '@kbn/test-jest-helpers';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
|
||||
export const getActions = ({ find, form, component }: TestBed) => {
|
||||
/** Open the sort select drop down menu */
|
||||
const openSortSelect = () => {
|
||||
find('tableSortSelectBtn').at(0).simulate('click');
|
||||
};
|
||||
|
||||
// --- Search Box ---
|
||||
|
||||
/** Set the search box value */
|
||||
const updateSearchText = async (value: string) => {
|
||||
await act(async () => {
|
||||
find('tableListSearchBox').simulate('keyup', {
|
||||
key: 'Enter',
|
||||
target: { value },
|
||||
});
|
||||
});
|
||||
component.update();
|
||||
};
|
||||
|
||||
/** Get the Search box value */
|
||||
const getSearchBoxValue = () => find('tableListSearchBox').props().defaultValue;
|
||||
|
||||
// --- Row Actions ---
|
||||
const selectRow = (rowId: string) => {
|
||||
act(() => {
|
||||
form.selectCheckBox(`checkboxSelectRow-${rowId}`);
|
||||
});
|
||||
component.update();
|
||||
};
|
||||
|
||||
const clickDeleteSelectedItemsButton = () => {
|
||||
act(() => {
|
||||
find('deleteSelectedItems').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
};
|
||||
|
||||
const clickConfirmModalButton = async () => {
|
||||
await act(async () => {
|
||||
find('confirmModalConfirmButton').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
};
|
||||
|
||||
return {
|
||||
openSortSelect,
|
||||
updateSearchText,
|
||||
getSearchBoxValue,
|
||||
selectRow,
|
||||
clickDeleteSelectedItemsButton,
|
||||
clickConfirmModalButton,
|
||||
};
|
||||
};
|
|
@ -22,6 +22,7 @@ import {
|
|||
type TableListViewTableProps,
|
||||
type UserContentCommonSchema,
|
||||
} from './table_list_view_table';
|
||||
import { getActions } from './table_list_view.test.helpers';
|
||||
|
||||
const mockUseEffect = useEffect;
|
||||
|
||||
|
@ -54,12 +55,6 @@ const twoDaysAgoToString = new Date(twoDaysAgo.getTime()).toDateString();
|
|||
const yesterday = new Date(new Date().setDate(new Date().getDate() - 1));
|
||||
const yesterdayToString = new Date(yesterday.getTime()).toDateString();
|
||||
|
||||
const getActions = (testBed: TestBed) => ({
|
||||
openSortSelect() {
|
||||
testBed.find('tableSortSelectBtn').at(0).simulate('click');
|
||||
},
|
||||
});
|
||||
|
||||
describe('TableListView', () => {
|
||||
const requiredProps: TableListViewTableProps = {
|
||||
entityName: 'test',
|
||||
|
@ -91,50 +86,102 @@ describe('TableListView', () => {
|
|||
}
|
||||
);
|
||||
|
||||
test('render default empty prompt', async () => {
|
||||
let testBed: TestBed;
|
||||
describe('empty prompt', () => {
|
||||
test('render default empty prompt', async () => {
|
||||
let testBed: TestBed;
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup();
|
||||
await act(async () => {
|
||||
testBed = await setup();
|
||||
});
|
||||
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
|
||||
expect(component.find(EuiEmptyPrompt).length).toBe(1);
|
||||
expect(exists('newItemButton')).toBe(false);
|
||||
});
|
||||
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
// avoid trapping users in empty prompt that can not create new items
|
||||
test('render default empty prompt with create action when createItem supplied', async () => {
|
||||
let testBed: TestBed;
|
||||
|
||||
expect(component.find(EuiEmptyPrompt).length).toBe(1);
|
||||
expect(exists('newItemButton')).toBe(false);
|
||||
});
|
||||
await act(async () => {
|
||||
testBed = await setup({ createItem: () => undefined });
|
||||
});
|
||||
|
||||
// avoid trapping users in empty prompt that can not create new items
|
||||
test('render default empty prompt with create action when createItem supplied', async () => {
|
||||
let testBed: TestBed;
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup({ createItem: () => undefined });
|
||||
expect(component.find(EuiEmptyPrompt).length).toBe(1);
|
||||
expect(exists('newItemButton')).toBe(true);
|
||||
});
|
||||
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
test('render custom empty prompt', async () => {
|
||||
let testBed: TestBed;
|
||||
|
||||
expect(component.find(EuiEmptyPrompt).length).toBe(1);
|
||||
expect(exists('newItemButton')).toBe(true);
|
||||
});
|
||||
const CustomEmptyPrompt = () => {
|
||||
return <EuiEmptyPrompt data-test-subj="custom-empty-prompt" title={<h1>Table empty</h1>} />;
|
||||
};
|
||||
|
||||
test('render custom empty prompt', async () => {
|
||||
let testBed: TestBed;
|
||||
await act(async () => {
|
||||
testBed = await setup({ emptyPrompt: <CustomEmptyPrompt /> });
|
||||
});
|
||||
|
||||
const CustomEmptyPrompt = () => {
|
||||
return <EuiEmptyPrompt data-test-subj="custom-empty-prompt" title={<h1>Table empty</h1>} />;
|
||||
};
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup({ emptyPrompt: <CustomEmptyPrompt /> });
|
||||
expect(exists('custom-empty-prompt')).toBe(true);
|
||||
});
|
||||
|
||||
const { component, exists } = testBed!;
|
||||
component.update();
|
||||
test('render empty prompt after deleting all items from table', async () => {
|
||||
// NOTE: this test is using helpers that are being tested in the
|
||||
// "should allow select items to be deleted" test below.
|
||||
// If this test fails, check that one first.
|
||||
|
||||
expect(exists('custom-empty-prompt')).toBe(true);
|
||||
const hits: UserContentCommonSchema[] = [
|
||||
{
|
||||
id: 'item-1',
|
||||
type: 'dashboard',
|
||||
updatedAt: '2020-01-01T00:00:00Z',
|
||||
attributes: {
|
||||
title: 'Item 1',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
];
|
||||
|
||||
const findItems = jest.fn().mockResolvedValue({ total: 1, hits });
|
||||
const deleteItems = jest.fn();
|
||||
|
||||
let testBed: TestBed;
|
||||
|
||||
const EmptyPrompt = () => {
|
||||
return <EuiEmptyPrompt data-test-subj="custom-empty-prompt" title={<h1>Table empty</h1>} />;
|
||||
};
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setup({ emptyPrompt: <EmptyPrompt />, findItems, deleteItems });
|
||||
});
|
||||
|
||||
const { component, exists, table } = testBed!;
|
||||
const { selectRow, clickConfirmModalButton, clickDeleteSelectedItemsButton } = getActions(
|
||||
testBed!
|
||||
);
|
||||
component.update();
|
||||
|
||||
expect(exists('custom-empty-prompt')).toBe(false);
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
const [row] = tableCellsValues;
|
||||
expect(row[1]).toBe('Item 1'); // Note: row[0] is the checkbox
|
||||
|
||||
// We delete the item in the table and expect the empty prompt to show
|
||||
findItems.mockResolvedValue({ total: 0, hits: [] });
|
||||
selectRow('item-1');
|
||||
clickDeleteSelectedItemsButton();
|
||||
await clickConfirmModalButton();
|
||||
|
||||
expect(exists('custom-empty-prompt')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('default columns', () => {
|
||||
|
@ -798,7 +845,20 @@ describe('TableListView', () => {
|
|||
let testBed: TestBed;
|
||||
|
||||
const initialFilter = 'tag:(tag-1)';
|
||||
const findItems = jest.fn().mockResolvedValue({ total: 0, hits: [] });
|
||||
const findItems = jest.fn().mockResolvedValue({
|
||||
total: 1,
|
||||
hits: [
|
||||
{
|
||||
id: 'item-1',
|
||||
type: 'dashboard',
|
||||
updatedAt: new Date('2023-07-15').toISOString(),
|
||||
attributes: {
|
||||
title: 'Item 1',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
testBed = await setupInitialFilter({
|
||||
|
@ -824,6 +884,173 @@ describe('TableListView', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('search', () => {
|
||||
const updatedAt = new Date('2023-07-15').toISOString();
|
||||
|
||||
const hits: UserContentCommonSchema[] = [
|
||||
{
|
||||
id: 'item-1',
|
||||
type: 'dashboard',
|
||||
updatedAt,
|
||||
attributes: {
|
||||
title: 'Item 1',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
{
|
||||
id: 'item-2',
|
||||
type: 'dashboard',
|
||||
updatedAt,
|
||||
attributes: {
|
||||
title: 'Item 2',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
];
|
||||
|
||||
const findItems = jest.fn();
|
||||
|
||||
const setupSearch = (...args: Parameters<ReturnType<typeof registerTestBed>>) => {
|
||||
const testBed = registerTestBed<string, TableListViewTableProps>(
|
||||
WithServices<TableListViewTableProps>(TableListViewTable),
|
||||
{
|
||||
defaultProps: {
|
||||
...requiredProps,
|
||||
findItems,
|
||||
urlStateEnabled: false,
|
||||
entityName: 'Foo',
|
||||
entityNamePlural: 'Foos',
|
||||
},
|
||||
memoryRouter: { wrapComponent: true },
|
||||
}
|
||||
)(...args);
|
||||
|
||||
const { updateSearchText, getSearchBoxValue } = getActions(testBed);
|
||||
|
||||
return {
|
||||
testBed,
|
||||
updateSearchText,
|
||||
getSearchBoxValue,
|
||||
getLastCallArgsFromFindItems: () => findItems.mock.calls[findItems.mock.calls.length - 1],
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
findItems.mockReset().mockResolvedValue({ total: hits.length, hits });
|
||||
});
|
||||
|
||||
test('should search the table items', async () => {
|
||||
let testBed: TestBed;
|
||||
let updateSearchText: (value: string) => Promise<void>;
|
||||
let getLastCallArgsFromFindItems: () => Parameters<typeof findItems>;
|
||||
let getSearchBoxValue: () => string;
|
||||
|
||||
await act(async () => {
|
||||
({ testBed, getLastCallArgsFromFindItems, getSearchBoxValue, updateSearchText } =
|
||||
await setupSearch());
|
||||
});
|
||||
|
||||
const { component, table } = testBed!;
|
||||
component.update();
|
||||
|
||||
let searchTerm = '';
|
||||
let expected = '';
|
||||
[searchTerm] = getLastCallArgsFromFindItems!();
|
||||
expect(getSearchBoxValue!()).toBe(expected);
|
||||
expect(searchTerm).toBe(expected);
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
expect(tableCellsValues).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Item 1",
|
||||
"Sat Jul 15 2023",
|
||||
],
|
||||
Array [
|
||||
"Item 2",
|
||||
"Sat Jul 15 2023",
|
||||
],
|
||||
]
|
||||
`);
|
||||
|
||||
findItems.mockResolvedValueOnce({
|
||||
total: 1,
|
||||
hits: [
|
||||
{
|
||||
id: 'item-from-search',
|
||||
type: 'dashboard',
|
||||
updatedAt: new Date('2023-07-01').toISOString(),
|
||||
attributes: {
|
||||
title: 'Item from search',
|
||||
},
|
||||
references: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expected = 'foo';
|
||||
await updateSearchText!(expected);
|
||||
[searchTerm] = getLastCallArgsFromFindItems!();
|
||||
expect(getSearchBoxValue!()).toBe(expected);
|
||||
expect(searchTerm).toBe(expected);
|
||||
|
||||
expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Item from search",
|
||||
"July 1, 2023",
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test('should search and render empty list if no result', async () => {
|
||||
let testBed: TestBed;
|
||||
let updateSearchText: (value: string) => Promise<void>;
|
||||
|
||||
await act(async () => {
|
||||
({ testBed, updateSearchText } = await setupSearch());
|
||||
});
|
||||
|
||||
const { component, table, find } = testBed!;
|
||||
component.update();
|
||||
|
||||
findItems.mockResolvedValueOnce({
|
||||
total: 0,
|
||||
hits: [],
|
||||
});
|
||||
|
||||
await updateSearchText!('unknown items');
|
||||
|
||||
expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"No Foos matched your search.",
|
||||
],
|
||||
]
|
||||
`);
|
||||
|
||||
await act(async () => {
|
||||
find('clearSearchButton').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
|
||||
// We should get back the initial 2 items (Item 1 and Item 2)
|
||||
expect(table.getMetaData('itemsInMemTable').tableCellsValues).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Array [
|
||||
"Item 1",
|
||||
"Sat Jul 15 2023",
|
||||
],
|
||||
Array [
|
||||
"Item 2",
|
||||
"Sat Jul 15 2023",
|
||||
],
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
describe('url state', () => {
|
||||
let router: Router | undefined;
|
||||
|
||||
|
@ -1153,10 +1380,11 @@ describe('TableListView', () => {
|
|||
};
|
||||
|
||||
test('should allow select items to be deleted', async () => {
|
||||
const {
|
||||
testBed: { table, find, exists, component, form },
|
||||
deleteItems,
|
||||
} = await setupTest();
|
||||
const { testBed, deleteItems } = await setupTest();
|
||||
|
||||
const { table, exists, component } = testBed;
|
||||
const { selectRow, clickDeleteSelectedItemsButton, clickConfirmModalButton } =
|
||||
getActions(testBed);
|
||||
|
||||
const { tableCellsValues } = table.getMetaData('itemsInMemTable');
|
||||
|
||||
|
@ -1165,28 +1393,21 @@ describe('TableListView', () => {
|
|||
['', 'Item 1Item 1 description', twoDaysAgoToString],
|
||||
]);
|
||||
|
||||
// Select the second item
|
||||
const selectedHit = hits[1];
|
||||
|
||||
expect(exists('deleteSelectedItems')).toBe(false);
|
||||
act(() => {
|
||||
// Select the second item
|
||||
form.selectCheckBox(`checkboxSelectRow-${selectedHit.id}`);
|
||||
});
|
||||
component.update();
|
||||
|
||||
selectRow(selectedHit.id);
|
||||
// Delete button is now visible
|
||||
expect(exists('deleteSelectedItems')).toBe(true);
|
||||
|
||||
// Click delete and validate that confirm modal opens
|
||||
expect(component.exists('.euiModal--confirmation')).toBe(false);
|
||||
act(() => {
|
||||
find('deleteSelectedItems').simulate('click');
|
||||
});
|
||||
component.update();
|
||||
clickDeleteSelectedItemsButton();
|
||||
expect(component.exists('.euiModal--confirmation')).toBe(true);
|
||||
|
||||
await act(async () => {
|
||||
find('confirmModalConfirmButton').simulate('click');
|
||||
});
|
||||
await clickConfirmModalButton();
|
||||
expect(deleteItems).toHaveBeenCalledWith([selectedHit]);
|
||||
});
|
||||
|
||||
|
|
|
@ -108,6 +108,7 @@ export interface TableListViewTableProps<
|
|||
contentEditor?: ContentEditorConfig;
|
||||
|
||||
tableCaption: string;
|
||||
/** Flag to force a new fetch of the table items. Whenever it changes, the `findItems()` will be called. */
|
||||
refreshListBouncer?: boolean;
|
||||
onFetchSuccess: () => void;
|
||||
setPageDataTestSubject: (subject: string) => void;
|
||||
|
@ -115,6 +116,12 @@ export interface TableListViewTableProps<
|
|||
|
||||
export interface State<T extends UserContentCommonSchema = UserContentCommonSchema> {
|
||||
items: T[];
|
||||
/**
|
||||
* Flag to indicate if there aren't any item when **no filteres are applied**.
|
||||
* When there are no item we render an empty prompt.
|
||||
* Default to `undefined` to indicate that we don't know yet if there are items or not.
|
||||
*/
|
||||
hasNoItems: boolean | undefined;
|
||||
hasInitialFetchReturned: boolean;
|
||||
isFetchingItems: boolean;
|
||||
isDeletingItems: boolean;
|
||||
|
@ -293,6 +300,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
|
|||
|
||||
const isMounted = useRef(false);
|
||||
const fetchIdx = useRef(0);
|
||||
|
||||
/**
|
||||
* The "onTableSearchChange()" handler has an async behavior. We want to be able to discard
|
||||
* previsous search changes and only handle the last one. For that we keep a counter of the changes.
|
||||
|
@ -335,9 +343,10 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
|
|||
const initialState = useMemo<State<T>>(
|
||||
() => ({
|
||||
items: [],
|
||||
hasNoItems: undefined,
|
||||
totalItems: 0,
|
||||
hasInitialFetchReturned: false,
|
||||
isFetchingItems: false,
|
||||
isFetchingItems: true,
|
||||
isDeletingItems: false,
|
||||
showDeleteModal: false,
|
||||
hasUpdatedAtMetadata: false,
|
||||
|
@ -364,6 +373,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
|
|||
hasInitialFetchReturned,
|
||||
isFetchingItems,
|
||||
items,
|
||||
hasNoItems,
|
||||
fetchError,
|
||||
showDeleteModal,
|
||||
isDeletingItems,
|
||||
|
@ -374,8 +384,6 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
|
|||
tableSort,
|
||||
} = state;
|
||||
|
||||
const hasQuery = searchQuery.text !== '';
|
||||
const hasNoItems = hasInitialFetchReturned && items.length === 0 && !hasQuery;
|
||||
const showFetchError = Boolean(fetchError);
|
||||
const showLimitError = !showFetchError && totalItems > listingLimit;
|
||||
|
||||
|
@ -857,17 +865,7 @@ function TableListViewTableComp<T extends UserContentCommonSchema>({
|
|||
// ------------
|
||||
// Effects
|
||||
// ------------
|
||||
useDebounce(
|
||||
() => {
|
||||
// Do not call fetchItems on dependency changes when initial fetch does not load any items
|
||||
// to avoid flashing between empty table and no items view
|
||||
if (!hasNoItems) {
|
||||
fetchItems();
|
||||
}
|
||||
},
|
||||
300,
|
||||
[fetchItems, refreshListBouncer]
|
||||
);
|
||||
useDebounce(fetchItems, 300, [fetchItems, refreshListBouncer]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!urlStateEnabled) {
|
||||
|
|
|
@ -77,8 +77,8 @@ export const EventAnnotationGroupTableList = ({
|
|||
const [refreshListBouncer, setRefreshListBouncer] = useState(false);
|
||||
|
||||
const refreshList = useCallback(() => {
|
||||
setRefreshListBouncer(!refreshListBouncer);
|
||||
}, [refreshListBouncer]);
|
||||
setRefreshListBouncer((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const fetchItems = useCallback(
|
||||
(
|
||||
|
|
|
@ -13,8 +13,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
|||
const PageObjects = getPageObjects(['common', 'filesManagement']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/160178
|
||||
describe.skip('Files management', () => {
|
||||
describe('Files management', () => {
|
||||
before(async () => {
|
||||
await PageObjects.filesManagement.navigateTo();
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue