Skip to content
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
5 changes: 3 additions & 2 deletions src/api/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,18 +229,19 @@ export async function getComparison(client, comparisonId) {
* Search for comparisons by name
* @param {Object} client - API client
* @param {string} name - Screenshot name to search for
* @param {Object} filters - Optional filters (branch, limit, offset)
* @param {Object} filters - Optional filters (branch, project, organization, limit, offset)
* @returns {Promise<Object>} Search results with comparisons and pagination
*/
export async function searchComparisons(client, name, filters = {}) {
if (!name || typeof name !== 'string') {
throw new VizzlyError('name is required and must be a non-empty string');
}

let { branch, project, limit = 50, offset = 0 } = filters;
let { branch, project, organization, limit = 50, offset = 0 } = filters;
let params = { name, limit: String(limit), offset: String(offset) };
if (branch) params.branch = branch;
if (project) params.project = project;
if (organization) params.organization = organization;

let endpoint = buildEndpointWithParams('/api/sdk/comparisons/search', params);
return client.request(endpoint);
Expand Down
6 changes: 5 additions & 1 deletion src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,7 @@ program
)
.option('--environment <env>', 'Filter by environment')
.option('-p, --project <slug>', 'Filter by project slug')
.option('--org <slug>', 'Filter by organization slug')
.option(
'--limit <n>',
'Maximum results to return (1-250)',
Expand All @@ -640,7 +641,8 @@ program
Examples:
$ vizzly builds # List recent builds
$ vizzly builds --branch main # Filter by branch
$ vizzly builds --project abc123 # Filter by project
$ vizzly builds --project storybook # Filter by project
$ vizzly builds --project storybook --org my-org # Disambiguate by org
$ vizzly builds --status completed # Filter by status
$ vizzly builds -b abc123-def456 # Get specific build by ID
$ vizzly builds -b abc123 --comparisons # Include comparisons
Expand Down Expand Up @@ -679,6 +681,7 @@ program
)
.option('--offset <n>', 'Skip first N results', val => parseInt(val, 10), 0)
.option('-p, --project <slug>', 'Filter by project slug')
.option('--org <slug>', 'Filter by organization slug')
.addHelpText(
'after',
`
Expand All @@ -687,6 +690,7 @@ Examples:
$ vizzly comparisons --id def456 # Get specific comparison by ID
$ vizzly comparisons --name "Button" # Search by screenshot name
$ vizzly comparisons --name "Login*" # Wildcard search
$ vizzly comparisons --name "Button" --org my-org # Filter by org
$ vizzly comparisons --status changed # Only changed comparisons
$ vizzly comparisons --json # Output as JSON for scripting
`
Expand Down
1 change: 1 addition & 0 deletions src/commands/builds.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export async function buildsCommand(
if (options.status) filters.status = options.status;
if (options.environment) filters.environment = options.environment;
if (options.project) filters.project = options.project;
if (options.org) filters.organization = options.org;

let response = await getBuilds(client, filters);
output.stopSpinner();
Expand Down
1 change: 1 addition & 0 deletions src/commands/comparisons.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export async function comparisonsCommand(
let filters = {
branch: options.branch,
project: options.project,
organization: options.org,
limit: options.limit || 50,
offset: options.offset || 0,
};
Expand Down
23 changes: 23 additions & 0 deletions tests/commands/builds.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,5 +307,28 @@ describe('commands/builds', () => {

assert.strictEqual(capturedFilters.project, 'proj-123');
});

it('passes organization filter to API', async () => {
let output = createMockOutput();
let capturedFilters = null;

await buildsCommand(
{ project: 'storybook', org: 'my-org' },
{ json: true },
{
loadConfig: async () => ({ apiKey: 'test-token' }),
createApiClient: () => ({}),
getBuilds: async (_client, filters) => {
capturedFilters = filters;
return { builds: [], pagination: { total: 0, hasMore: false } };
},
output,
exit: () => {},
}
);

assert.strictEqual(capturedFilters.project, 'storybook');
assert.strictEqual(capturedFilters.organization, 'my-org');
});
});
});
26 changes: 26 additions & 0 deletions tests/commands/comparisons.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,32 @@ describe('commands/comparisons', () => {
assert.strictEqual(capturedFilters.project, 'my-project');
});

it('passes organization filter to search', async () => {
let output = createMockOutput();
let capturedFilters = null;

await comparisonsCommand(
{ name: 'button-*', project: 'storybook', org: 'my-org' },
{ json: true },
{
loadConfig: async () => ({ apiKey: 'test-token' }),
createApiClient: () => ({}),
searchComparisons: async (_client, _name, filters) => {
capturedFilters = filters;
return {
comparisons: [],
pagination: { total: 0, hasMore: false },
};
},
output,
exit: () => {},
}
);

assert.strictEqual(capturedFilters.project, 'storybook');
assert.strictEqual(capturedFilters.organization, 'my-org');
});

it('fetches single comparison by ID', async () => {
let output = createMockOutput();
let mockComparison = {
Expand Down