Skip to content

Commit b89369b

Browse files
committed
change escalation chains searching to allow for partial searching
1 parent 046d1dc commit b89369b

File tree

8 files changed

+45
-7
lines changed

8 files changed

+45
-7
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Updated wording throughout plugin to use 'Alert Group' instead of 'Incident' ([1565](https://github.com/grafana/oncall/pull/1565),
1818
[1576](https://github.com/grafana/oncall/pull/1576))
1919
- Filtering for Editors/Admins was added to rotation form. It is not allowed to assign Viewer to rotation ([1124](https://github.com/grafana/oncall/issues/1124))
20+
- Modified search behaviour on the Escalation Chains page to allow for "partial searching" ([1578](https://github.com/grafana/oncall/pull/1578))
2021

2122
### Fixed
2223

engine/apps/api/views/escalation_chain.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class EscalationChainViewSet(
4646
}
4747

4848
filter_backends = [SearchFilter]
49-
search_fields = ("^name",)
49+
search_fields = ("name",)
5050

5151
serializer_class = EscalationChainSerializer
5252
list_serializer_class = EscalationChainListSerializer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { test, expect, Page } from '@playwright/test';
2+
import { configureOnCallPlugin } from '../utils/configurePlugin';
3+
import { generateRandomValue } from '../utils/forms';
4+
import { createEscalationChain } from '../utils/escalationChain';
5+
6+
test.beforeEach(async ({ page }) => {
7+
await configureOnCallPlugin(page);
8+
});
9+
10+
const assertEscalationChainSearchWorks = async (
11+
page: Page,
12+
searchTerm: string,
13+
escalationChainFullName: string
14+
): Promise<void> => {
15+
await page.getByTestId('escalation-chain-search-input').fill(searchTerm);
16+
17+
// wait for the API call(s) to finish
18+
await page.waitForLoadState('networkidle');
19+
20+
await expect(page.getByTestId('escalation-chains-list')).toHaveText(escalationChainFullName);
21+
};
22+
23+
test('searching allows case-insensitive partial matches', async ({ page }) => {
24+
const escalationChainName = `${generateRandomValue()} ${generateRandomValue()}`;
25+
const [firstHalf, secondHalf] = escalationChainName.split(' ');
26+
27+
await createEscalationChain(page, escalationChainName);
28+
29+
await assertEscalationChainSearchWorks(page, firstHalf, escalationChainName);
30+
await assertEscalationChainSearchWorks(page, firstHalf.toUpperCase(), escalationChainName);
31+
await assertEscalationChainSearchWorks(page, firstHalf.toLowerCase(), escalationChainName);
32+
33+
await assertEscalationChainSearchWorks(page, secondHalf, escalationChainName);
34+
await assertEscalationChainSearchWorks(page, secondHalf.toUpperCase(), escalationChainName);
35+
await assertEscalationChainSearchWorks(page, secondHalf.toLowerCase(), escalationChainName);
36+
});

grafana-plugin/integration-tests/utils/alertGroup.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const incidentTimelineContainsStep = async (page: Page, triggeredStepText: strin
1515
return Promise.resolve(false);
1616
}
1717

18-
if (!page.locator('div[data-testid="incident-timeline-list"]').getByText(triggeredStepText)) {
18+
if (!page.getByTestId('incident-timeline-list').getByText(triggeredStepText)) {
1919
await page.reload({ waitUntil: 'networkidle' });
2020
return incidentTimelineContainsStep(page, triggeredStepText, (retryNum += 1));
2121
}

grafana-plugin/integration-tests/utils/escalationChain.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ const escalationStepValuePlaceholder: Record<EscalationStep, string> = {
1616
export const createEscalationChain = async (
1717
page: Page,
1818
escalationChainName: string,
19-
escalationStep: EscalationStep | null,
20-
escalationStepValue: string | null
19+
escalationStep?: EscalationStep,
20+
escalationStepValue?: string
2121
): Promise<void> => {
2222
// go to the escalation chains page
2323
await goToOnCallPage(page, 'escalations');
@@ -32,7 +32,7 @@ export const createEscalationChain = async (
3232
await clickButton({ page, buttonText: 'Create' });
3333
await page.waitForSelector(`text=${escalationChainName}`);
3434

35-
if (!escalationStep) {
35+
if (!escalationStep || !escalationStepValue) {
3636
return;
3737
}
3838

grafana-plugin/integration-tests/utils/integrations.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export const createIntegrationAndSendDemoAlert = async (
2424
await fillInInput(page, 'div[data-testid="edit-integration-name-modal"] >> input', integrationName);
2525
await clickButton({ page, buttonText: 'Update' });
2626

27-
const integrationSettingsElement = page.locator('div[data-testid="integration-settings"]');
27+
const integrationSettingsElement = page.getByTestId('integration-settings');
2828

2929
// assign the escalation chain to the integration
3030
await selectDropdownValue({

grafana-plugin/src/components/EscalationsFilters/EscalationsFilters.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const EscalationsFilters: FC<EscalationsFiltersProps> = (props) => {
3939
<div className={cx('root')}>
4040
<Input
4141
autoFocus
42+
data-testid="escalation-chain-search-input"
4243
className={cx('search')}
4344
prefix={<Icon name="search" />}
4445
placeholder="Search escalations..."

grafana-plugin/src/pages/escalation-chains/EscalationChains.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class EscalationChainsPage extends React.Component<EscalationChainsPageProps, Es
175175
</Button>
176176
</WithPermissionControlTooltip>
177177
)}
178-
<div className={cx('escalations-list')}>
178+
<div className={cx('escalations-list')} data-testid="escalation-chains-list">
179179
{searchResult ? (
180180
<GList
181181
autoScroll

0 commit comments

Comments
 (0)