Skip to content

Commit 4423cc9

Browse files
fix(test): Fix flaky ResultsSearchQueryBuilder spec
Stabilize two flaky tests: 1. "does not show function tags in has: dropdown" — timed out at 5000ms because userEvent.type started typing before async API responses (feature flags, recent searches) had settled, causing re-renders mid-typing that slowed each keystroke. Split into click + findByRole (listbox) + keyboard to let initial renders complete before typing. 2. "shows normal tags in the dropdown" — act() warning from SearchQueryBuilderCombobox because pending state updates from API responses fired after test assertions completed. Add waitFor at end to flush pending React state updates before teardown. Also add MockApiClient.clearMockResponses() in beforeEach to prevent mock leakage between tests. Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com> Made-with: Cursor
1 parent d7f2bcd commit 4423cc9

File tree

1 file changed

+25
-11
lines changed

1 file changed

+25
-11
lines changed

static/app/views/discover/results/resultsSearchQueryBuilder.spec.tsx

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import {OrganizationFixture} from 'sentry-fixture/organization';
22

3-
import {render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
3+
import {
4+
render,
5+
screen,
6+
userEvent,
7+
waitFor,
8+
within,
9+
} from 'sentry-test/reactTestingLibrary';
410

511
import {SavedSearchType} from 'sentry/types/group';
612
import type {Organization} from 'sentry/types/organization';
@@ -11,6 +17,8 @@ import {ResultsSearchQueryBuilder} from './resultsSearchQueryBuilder';
1117
describe('ResultsSearchQueryBuilder', () => {
1218
let organization: Organization;
1319
beforeEach(() => {
20+
MockApiClient.clearMockResponses();
21+
1422
organization = OrganizationFixture();
1523
MockApiClient.addMockResponse({
1624
url: `/organizations/org-slug/recent-searches/`,
@@ -41,22 +49,24 @@ describe('ResultsSearchQueryBuilder', () => {
4149
user: {key: 'user', name: 'user', kind: FieldKind.FIELD},
4250
}}
4351
recentSearches={SavedSearchType.EVENT}
44-
// This fields definition is what caused p50 to appear as a function tag
4552
fields={[{field: 'p50(transaction.duration)'}]}
4653
/>,
4754
{
4855
organization,
4956
}
5057
);
5158

52-
// Focus the input and type "has:p" to simulate a search for p50
5359
const input = await screen.findByRole('combobox');
54-
await userEvent.type(input, 'has:p');
60+
await userEvent.click(input);
61+
await screen.findByRole('listbox');
62+
await userEvent.keyboard('has:p');
5563

56-
// Check that "p50" (a function tag) is NOT in the dropdown
57-
expect(
58-
within(screen.getByRole('listbox')).queryByText('p50')
59-
).not.toBeInTheDocument();
64+
const listbox = await screen.findByRole('listbox');
65+
expect(within(listbox).queryByText('p50')).not.toBeInTheDocument();
66+
67+
await waitFor(() => {
68+
expect(screen.getByRole('combobox')).toBeInTheDocument();
69+
});
6070
});
6171

6272
it.knownFlake('shows normal tags, e.g. transaction, in the dropdown', async () => {
@@ -73,22 +83,26 @@ describe('ResultsSearchQueryBuilder', () => {
7383
user: {key: 'user', name: 'user', kind: FieldKind.FIELD},
7484
}}
7585
recentSearches={SavedSearchType.EVENT}
76-
// This fields definition is what caused p50 to appear as a function tag
7786
fields={[{field: 'p50(transaction.duration)'}]}
7887
/>,
7988
{
8089
organization,
8190
}
8291
);
8392

84-
// Check that a normal tag (e.g. "transaction") IS in the dropdown
8593
const input = await screen.findByRole('combobox');
86-
await userEvent.type(input, 'transact');
94+
await userEvent.click(input);
95+
await screen.findByRole('listbox');
96+
await userEvent.keyboard('transact');
8797

8898
expect(
8999
await within(screen.getByRole('listbox')).findByRole('option', {
90100
name: 'transaction',
91101
})
92102
).toBeInTheDocument();
103+
104+
await waitFor(() => {
105+
expect(screen.getByRole('combobox')).toBeInTheDocument();
106+
});
93107
});
94108
});

0 commit comments

Comments
 (0)