-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Watcher] Retain search and pagination values when watch list refreshes #82651
[Watcher] Retain search and pagination values when watch list refreshes #82651
Conversation
})} | ||
data-test-subj="watchesTable" | ||
/> | ||
<div data-test-subj="watchesTableContainer"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The search box in the table doesn't appear to be able to accept a data-test-subj
prop, so we have to access it via a CSS selector in the tests. In order to use a CSS selector, you need to first target the closest test subject.
Pinging @elastic/es-ui (Team:Elasticsearch UI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested locally, code LGTM! Just had a few suggestions.
server.restore(); | ||
}); | ||
|
||
describe('on component mount', () => { | ||
beforeEach(async () => { | ||
testBed = await setup(); | ||
await act(async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like each of these tests calls setup
on its own, so I think we can remove this entire beforeEach
.
// Enter the name of "watch1" in the search box | ||
// @ts-ignore | ||
searchInput.instance().value = watch1.name; | ||
searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor DX suggestion. How about abstracting this behind a helper function in watch_list.helpers.ts
?
const searchWatches = (term) => {
const { find, component } = testBed;
const searchInput = find('watchesTableContainer').find('.euiFieldSearch');
// Enter input into the search box
// @ts-ignore
searchInput.instance().value = term;
searchInput.simulate('keyup', { key: 'Enter', keyCode: 13, which: 13 });
component.update();
};
return {
...testBed,
actions: {
selectWatchAt,
clickWatchAt,
clickWatchActionAt,
searchWatches,
},
};
Then here we can call it like this:
test('should retain the search query', async () => {
const { find, component, table, actions: { searchWatches } } = testBed;
searchWatches(watch1.name);
const { tableCellsValues } = table.getMetaData('watchesTable');
expect(row).toEqual([ | ||
'', | ||
id, | ||
getExpectedValue(name), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it really difficult to understand why we call getExpectedValue
in these assertions, and difficult to understand what we expect the value to be. After reading the fixture call site code, the fixture module code, and the getExpectedValue
code, I understand that on this line the name will include a random value so we can't hardcode a string here. But why would it ever be undefined
? And for the watchStatus
properties, it looks like the shape is always { state: 'OK', isActive: true }
, so why do we check if those two properties are undefined
? Similarly, the other properties are always undefined
so I'm confused about why we check this.
It smells a bit like we're testing implementation if getExpectedValue
mirrors the implementation of how the table renders undefined
values as empty spaces, but without understanding the intention here it's difficult for me to say. My initial reaction based on what I see here would be to suggest we remove the random values from the mocked data and assert against explicit values. If we find it unclear about what's being shown in the table, we can add comments.
expect(row).toEqual([
'', // checkbox
'a-id', // ID
'a-name', // name
'OK', // status
'', // comment
'', // lastMetCondition
'', // lastChecked
'', // actions
]);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. I think I may have copied this from elsewhere. I agree it's not very clear. I updated the assertion to your suggestion.
|
||
await act(async () => { | ||
await nextTick(); | ||
testBed.component.update(); | ||
// Advance timers to simulate another request |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar DX suggestion here about a helper function. We can add this to watch_list.helpers.ts
:
const advanceTimeToTableRefresh = async () => {
const { component } = testBed;
await act(async () => {
// Advance timers to simulate another request
jest.advanceTimersByTime(REFRESH_INTERVALS.WATCH_LIST);
});
component.update();
};
return {
...testBed,
actions: {
selectWatchAt,
clickWatchAt,
clickWatchActionAt,
advanceTimeToTableRefresh,
},
};
And use it here:
await advanceTimeToTableRefresh();
}); | ||
|
||
component.update(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this one needed? I was able to remove it and the test passed.
Thanks for the review @cjcenizal! I updated the tests with your suggestions. |
💚 Build SucceededMetrics [docs]async chunks size
History
To update your PR or re-run it, just comment with: |
(Belated) thank you for fixing this! Genuinely annoying enough to make me want to upgrade... ;-) |
Fixes #69606
How to test
Release note
This fixes a bug in the Watcher UI where the search input cleared after 1 minute of inactivity, causing a user to lose the filtered results. It also fixes a similar issue where if the user changed pages or the default page size and was inactive.