From 17c9f40244e255800798a8bd7f56a6aac642ab96 Mon Sep 17 00:00:00 2001 From: Savio Dias Date: Fri, 17 Jul 2026 16:23:08 +0530 Subject: [PATCH 1/2] feat(testmanagement): stamp "MCP generated" tag on createTestCase Manual test cases created via the MCP server carried no origin marker, so they were missing from the Test Case Activity Report (PMAA-166). Stamp the "MCP generated" tag on the create payload, preserving and de-duping any user-supplied tags. "AI Generated" stays reserved for TCG Agent output. Co-Authored-By: Claude Opus 4.8 --- .../testmanagement-utils/create-testcase.ts | 4 + tests/tools/create-testcase-tag.test.ts | 80 +++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 tests/tools/create-testcase-tag.test.ts diff --git a/src/tools/testmanagement-utils/create-testcase.ts b/src/tools/testmanagement-utils/create-testcase.ts index 1119fda..85eab4a 100644 --- a/src/tools/testmanagement-utils/create-testcase.ts +++ b/src/tools/testmanagement-utils/create-testcase.ts @@ -320,6 +320,10 @@ export async function createTestCase( ): Promise { const testCaseParams: TestCaseCreateRequest = { ...params }; + testCaseParams.tags = Array.from( + new Set([...(testCaseParams.tags ?? []), "MCP generated"]), + ); + if ( testCaseParams.priority !== undefined || testCaseParams.case_type !== undefined diff --git a/tests/tools/create-testcase-tag.test.ts b/tests/tools/create-testcase-tag.test.ts new file mode 100644 index 0000000..1cf33db --- /dev/null +++ b/tests/tools/create-testcase-tag.test.ts @@ -0,0 +1,80 @@ +import { beforeEach, describe, it, expect, vi, Mock } from 'vitest'; +import { apiClient } from '../../src/lib/apiClient'; +import { + createTestCase, + TestCaseCreateRequest, +} from '../../src/tools/testmanagement-utils/create-testcase'; + +// Reach the real createTestCase implementation; stub only its external deps so +// we can assert on the payload it builds (PMAA-166: MCP-origin tag stamping). +vi.mock('../../src/lib/apiClient', () => ({ + apiClient: { get: vi.fn(), post: vi.fn() }, +})); +vi.mock('../../src/lib/tm-base-url', () => ({ + getTMBaseURL: vi.fn(async () => 'https://test-management.browserstack.com'), +})); +vi.mock('../../src/lib/get-auth', () => ({ + getBrowserStackAuth: vi.fn(() => 'fake-user:fake-key'), +})); +vi.mock('../../src/tools/testmanagement-utils/TCG-utils/api', () => ({ + projectIdentifierToId: vi.fn(async () => '999'), + fetchFormFields: vi.fn(), + normalizeDefaultFieldValue: vi.fn(), +})); +vi.mock('../../src/logger', () => ({ + default: { error: vi.fn(), warn: vi.fn(), info: vi.fn(), debug: vi.fn() }, +})); + +const mockConfig = { + 'browserstack-username': 'fake-user', + 'browserstack-access-key': 'fake-key', +} as any; + +const baseArgs: TestCaseCreateRequest = { + project_identifier: 'proj-123', + folder_id: 'fold-456', + name: 'Sample Test Case', + test_case_steps: [{ step: 'Step 1', result: 'Result 1' }], +}; + +function mockCreateSuccess() { + (apiClient.post as Mock).mockResolvedValue({ + data: { + data: { + success: true, + test_case: { + identifier: 'TC-001', + title: 'Sample Test Case', + template: undefined, + }, + }, + }, + }); +} + +function sentTags(): string[] { + const req = (apiClient.post as Mock).mock.calls[0][0]; + return req.body.test_case.tags; +} + +describe('createTestCase MCP-origin tag (PMAA-166)', () => { + beforeEach(() => { + vi.clearAllMocks(); + mockCreateSuccess(); + }); + + it('stamps "MCP generated" when the caller passes no tags', async () => { + await createTestCase({ ...baseArgs }, mockConfig); + expect(sentTags()).toEqual(['MCP generated']); + }); + + it('preserves user tags and appends "MCP generated"', async () => { + await createTestCase({ ...baseArgs, tags: ['smoke', 'regression'] }, mockConfig); + expect(sentTags()).toEqual(['smoke', 'regression', 'MCP generated']); + }); + + it('does not duplicate "MCP generated" if already present', async () => { + await createTestCase({ ...baseArgs, tags: ['MCP generated'] }, mockConfig); + expect(sentTags()).toEqual(['MCP generated']); + }); +}); From fd54e7604e8afe593237ae129e23338a2add38b3 Mon Sep 17 00:00:00 2001 From: Savio Dias Date: Fri, 17 Jul 2026 16:35:45 +0530 Subject: [PATCH 2/2] fix(testmanagement): match bulk path casing "MCP Generated" Align the createTestCase origin tag with the existing bulk createTestCasesFromFile path (TCG-utils/helpers.ts), which uses "MCP Generated" (capital G). Keeps a single canonical tag string across both create paths for the Test Case Activity Report (PMAA-166). Co-Authored-By: Claude Opus 4.8 --- src/tools/testmanagement-utils/create-testcase.ts | 2 +- tests/tools/create-testcase-tag.test.ts | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tools/testmanagement-utils/create-testcase.ts b/src/tools/testmanagement-utils/create-testcase.ts index 85eab4a..446e2fe 100644 --- a/src/tools/testmanagement-utils/create-testcase.ts +++ b/src/tools/testmanagement-utils/create-testcase.ts @@ -321,7 +321,7 @@ export async function createTestCase( const testCaseParams: TestCaseCreateRequest = { ...params }; testCaseParams.tags = Array.from( - new Set([...(testCaseParams.tags ?? []), "MCP generated"]), + new Set([...(testCaseParams.tags ?? []), "MCP Generated"]), ); if ( diff --git a/tests/tools/create-testcase-tag.test.ts b/tests/tools/create-testcase-tag.test.ts index 1cf33db..01bf621 100644 --- a/tests/tools/create-testcase-tag.test.ts +++ b/tests/tools/create-testcase-tag.test.ts @@ -63,18 +63,18 @@ describe('createTestCase MCP-origin tag (PMAA-166)', () => { mockCreateSuccess(); }); - it('stamps "MCP generated" when the caller passes no tags', async () => { + it('stamps "MCP Generated" when the caller passes no tags', async () => { await createTestCase({ ...baseArgs }, mockConfig); - expect(sentTags()).toEqual(['MCP generated']); + expect(sentTags()).toEqual(['MCP Generated']); }); - it('preserves user tags and appends "MCP generated"', async () => { + it('preserves user tags and appends "MCP Generated"', async () => { await createTestCase({ ...baseArgs, tags: ['smoke', 'regression'] }, mockConfig); - expect(sentTags()).toEqual(['smoke', 'regression', 'MCP generated']); + expect(sentTags()).toEqual(['smoke', 'regression', 'MCP Generated']); }); - it('does not duplicate "MCP generated" if already present', async () => { - await createTestCase({ ...baseArgs, tags: ['MCP generated'] }, mockConfig); - expect(sentTags()).toEqual(['MCP generated']); + it('does not duplicate "MCP Generated" if already present', async () => { + await createTestCase({ ...baseArgs, tags: ['MCP Generated'] }, mockConfig); + expect(sentTags()).toEqual(['MCP Generated']); }); });