Skip to content
Open
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
5 changes: 1 addition & 4 deletions packages/playwright/src/common/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,10 +303,7 @@ export class TestCase extends Base implements reporterTypes.TestCase {
this.parent._collectTagTitlePath(path);
path.push(this.title);
const titleTags = path.join(' ').match(/@[\S]+/g) || [];
return [
...titleTags,
...this._tags,
];
return [...new Set([...titleTags, ...this._tags])];
}

_serialize(): any {
Expand Down
28 changes: 28 additions & 0 deletions tests/playwright-test/test-tag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,34 @@ test('should be included in testInfo if coming from describe or global tag', asy
expect(result.exitCode).toBe(0);
});

test('should deduplicate tags when same tag appears in both describe and test', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.ts': `
import { test, expect } from '@playwright/test';
test.describe('suite', { tag: '@foo' }, () => {
test('test', { tag: '@foo' }, async ({}, testInfo) => {
expect(testInfo.tags).toStrictEqual(['@foo']);
});
});
`,
});
expect(result.exitCode).toBe(0);
});

test('should deduplicate inline tags when same tag appears in both describe title and test title', async ({ runInlineTest }) => {
const result = await runInlineTest({
'a.test.ts': `
import { test, expect } from '@playwright/test';
test.describe('@foo suite', () => {
test('@foo test', async ({}, testInfo) => {
expect(testInfo.tags).toStrictEqual(['@foo']);
});
});
`,
});
expect(result.exitCode).toBe(0);
});

test('should not parse file names as tags', async ({ runInlineTest }) => {
const result = await runInlineTest({
'reporter.ts': `
Expand Down