diff --git a/profiler-cli/src/commands/filter.ts b/profiler-cli/src/commands/filter.ts index 6c17ae725c..c3d7f862e7 100644 --- a/profiler-cli/src/commands/filter.ts +++ b/profiler-cli/src/commands/filter.ts @@ -31,6 +31,10 @@ export function registerFilterCommand( .command('push') .description('Push a sticky sample filter') .option('--thread ', 'Thread handle') + .option( + '--search ', + 'Marker search text (used with --during-marker / --outside-marker)' + ) ) ).action(async (opts) => { const spec = parseFilterSpec({ diff --git a/profiler-cli/src/test/integration/basic.test.ts b/profiler-cli/src/test/integration/basic.test.ts index 8427403d7c..568cc900ac 100644 --- a/profiler-cli/src/test/integration/basic.test.ts +++ b/profiler-cli/src/test/integration/basic.test.ts @@ -16,6 +16,8 @@ import { type CliTestContext, } from './utils'; +import type { FilterStackResult } from '../../protocol'; + describe('profiler-cli basic functionality', () => { let ctx: CliTestContext; @@ -256,6 +258,24 @@ describe('profiler-cli basic functionality', () => { expect(afterPop.filters).toHaveLength(0); }); + it('filter push supports --during-marker with --search', async () => { + await cli(ctx, ['load', 'src/test/fixtures/upgrades/processed-1.json']); + await cli(ctx, ['thread', 'select', 't-0']); + + await cli(ctx, ['filter', 'push', '--during-marker', '--search', 'Reflow']); + + const filterListResult = await cli(ctx, ['filter', 'list', '--json']); + const filterList = JSON.parse(filterListResult.stdout) as FilterStackResult; + + expect(filterList.filters).toHaveLength(1); + expect(filterList.filters[0].transforms).toEqual([ + { type: 'filter-samples', filterType: 'marker-search', filter: 'Reflow' }, + ]); + expect(filterList.filters[0].description).toBe( + 'during marker matching: "Reflow"' + ); + }); + it('ephemeral sample filters do not persist into session state', async () => { await cli(ctx, ['load', 'src/test/fixtures/upgrades/processed-1.json']);