Skip to content
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

Filter test cases by annotation text in HTML report #30751

Merged
merged 4 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions packages/html-reporter/src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/

import type { TestCaseSummary } from './types';

export class Filter {
project: string[] = [];
status: string[] = [];
text: string[] = [];
labels: string[] = [];
annotations: string[] = [];

empty(): boolean {
return this.project.length + this.status.length + this.text.length === 0;
Expand All @@ -32,6 +32,7 @@ export class Filter {
const status = new Set<string>();
const text: string[] = [];
const labels = new Set<string>();
const annotations = new Set<string>();
for (const token of tokens) {
if (token.startsWith('p:')) {
project.add(token.slice(2));
Expand All @@ -45,6 +46,10 @@ export class Filter {
labels.add(token);
continue;
}
if (token.startsWith('annot:')) {
annotations.add(token.slice('annot:'.length));
continue;
}
text.push(token.toLowerCase());
}

Expand All @@ -53,6 +58,7 @@ export class Filter {
filter.project = [...project];
filter.status = [...status];
filter.labels = [...labels];
filter.annotations = [...annotations];
return filter;
}

Expand Down Expand Up @@ -127,7 +133,12 @@ export class Filter {
if (!matches)
return false;
}

if (this.annotations.length) {
const matches = this.annotations.every(annotation =>
searchValues.annotations.some(a => a.includes(annotation)));
if (!matches)
return false;
}
return true;
}
}
Expand All @@ -140,6 +151,7 @@ type SearchValues = {
line: string;
column: string;
labels: string[];
annotations: string[];
};

const searchValuesSymbol = Symbol('searchValues');
Expand All @@ -164,6 +176,7 @@ function cacheSearchValues(test: TestCaseSummary): SearchValues {
line: String(test.location.line),
column: String(test.location.column),
labels: test.tags.map(tag => tag.toLowerCase()),
annotations: test.annotations.map(a => a.type.toLowerCase() + '=' + a.description?.toLocaleLowerCase())
};
(test as any)[searchValuesSymbol] = searchValues;
return searchValues;
Expand Down
5 changes: 3 additions & 2 deletions packages/html-reporter/src/headerView.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ test('should render counters', async ({ mount }) => {
flaky: 17,
skipped: 10,
ok: false,
}} filterText='' setFilterText={() => {}}></HeaderView>);
}} filterText='' setFilterText={() => { }}></HeaderView>);
await expect(component.locator('a', { hasText: 'All' }).locator('.counter')).toHaveText('90');
await expect(component.locator('a', { hasText: 'Passed' }).locator('.counter')).toHaveText('42');
await expect(component.locator('a', { hasText: 'Failed' }).locator('.counter')).toHaveText('31');
Expand Down Expand Up @@ -59,5 +59,6 @@ test('should toggle filters', async ({ page, mount }) => {
await expect(page).toHaveURL(/#\?q=s:flaky/);
await component.locator('a', { hasText: 'Skipped' }).click();
await expect(page).toHaveURL(/#\?q=s:skipped/);
expect(filters).toEqual(['', 's:passed', 's:failed', 's:flaky', 's:skipped']);
await component.getByRole('searchbox').fill('annot:annotation type=annotation description');
expect(filters).toEqual(['', 's:passed', 's:failed', 's:flaky', 's:skipped', 'annot:annotation type=annotation description']);
});
33 changes: 28 additions & 5 deletions tests/playwright-test/reporter-html.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ for (const useIntermediateMergeReport of [false] as const) {
await showReport();

const searchInput = page.locator('.subnav-search-input');
const smokeLabelButton = page.locator('.test-file-test', { has: page.getByText('Error Pages › @smoke fails', { exact: true }) }).locator('.label', { hasText: 'smoke' });
const smokeLabelButton = page.locator('.test-file-test', { has: page.getByText('Error Pages › @smoke fails', { exact: true }) }).locator('.label', { hasText: 'smoke' });

await expect(smokeLabelButton).toBeVisible();
await smokeLabelButton.click();
Expand All @@ -1465,7 +1465,7 @@ for (const useIntermediateMergeReport of [false] as const) {
await expect(page.locator('.chip', { hasText: 'b.test.js' })).toHaveCount(1);
await expect(page.locator('.test-file-test .test-file-title')).toHaveText('Error Pages › @smoke fails');

const regressionLabelButton = page.locator('.test-file-test', { has: page.getByText('Error Pages › @regression passes', { exact: true }) }).locator('.label', { hasText: 'regression' });
const regressionLabelButton = page.locator('.test-file-test', { has: page.getByText('Error Pages › @regression passes', { exact: true }) }).locator('.label', { hasText: 'regression' });

await expect(regressionLabelButton).not.toBeVisible();

Expand Down Expand Up @@ -1577,15 +1577,15 @@ for (const useIntermediateMergeReport of [false] as const) {

const searchInput = page.locator('.subnav-search-input');

const smokeLabelButton = page.locator('.test-file-test', { has: page.getByText('@smoke fails', { exact: true }) }).locator('.label', { hasText: 'smoke' });
const smokeLabelButton = page.locator('.test-file-test', { has: page.getByText('@smoke fails', { exact: true }) }).locator('.label', { hasText: 'smoke' });
await smokeLabelButton.click();
await expect(page).toHaveURL(/@smoke/);
await searchInput.clear();
await page.keyboard.press('Enter');
await expect(searchInput).toHaveValue('');
await expect(page).not.toHaveURL(/@smoke/);

const regressionLabelButton = page.locator('.test-file-test', { has: page.getByText('@regression passes', { exact: true }) }).locator('.label', { hasText: 'regression' });
const regressionLabelButton = page.locator('.test-file-test', { has: page.getByText('@regression passes', { exact: true }) }).locator('.label', { hasText: 'regression' });
await regressionLabelButton.click();
await expect(page).toHaveURL(/@regression/);
await searchInput.clear();
Expand Down Expand Up @@ -1863,7 +1863,7 @@ for (const useIntermediateMergeReport of [false] as const) {
await expect(page.locator('.test-file-test .test-file-title', { hasText: '@company_information_widget fails' })).toHaveCount(1);
});

test('handling of meta or ctrl key', async ({ runInlineTest, showReport, page, }) => {
test('handling of meta or ctrl key', async ({ runInlineTest, showReport, page, }) => {
const result = await runInlineTest({
'a.test.js': `
const { expect, test } = require('@playwright/test');
Expand Down Expand Up @@ -2214,6 +2214,29 @@ for (const useIntermediateMergeReport of [false] as const) {
await expect(page.getByText('passes title')).toBeVisible();
});

test('tests should filter by annotation texts', async ({ runInlineTest, showReport, page }) => {
const result = await runInlineTest({
'a.test.js': `
const { test, expect } = require('@playwright/test');
test('annotated test',{ annotation :[{type:'key',description:'value'}]}, async ({}) => {expect(1).toBe(1);});
test('non-annotated test', async ({}) => {expect(1).toBe(2);});
`,
}, { reporter: 'dot,html' }, { PW_TEST_HTML_REPORT_OPEN: 'never' });

expect(result.exitCode).toBe(1);
expect(result.passed).toBe(1);
expect(result.failed).toBe(1);

await showReport();

const searchInput = page.locator('.subnav-search-input');

await searchInput.fill('annot:key=value');
await expect(page.getByText('a.test.js', { exact: true })).toBeVisible();
await expect(page.getByText('non-annotated test')).not.toBeVisible();
await expect(page.getByText('annotated test')).toBeVisible();
});

test('tests should filter by fileName:line/column', async ({ runInlineTest, showReport, page }) => {
const result = await runInlineTest({
'a.test.js': `
Expand Down
Loading