Skip to content

Conversation

@carlosthe19916
Copy link
Collaborator

@carlosthe19916 carlosthe19916 commented Nov 4, 2025

This PR enhances the Toolbar definition so we define the available filters at the time of instantiating the Toolbar, then when we apply filters we can only use the filters defined at the beginning. We enhance type safety and use the power of Typescript.

The following is how a toolbar will be instantiated after this PR:

const toolbar = await Toolbar.build(this._page, "advisory-toolbar", {
      "Filter text": "string",
      Revision: "dateRange",
      Label: "typeahead",
});

await toolbar.applyFilter({ "Filter text": "something" }); // Correct
await toolbar.applyFilter({ "Filter textttt": "something" }); // Typescript error: "Filter textttt" was not defined in Toolbar
await toolbar.applyFilter({ "Filter textttt": 123 }); // Typescript error: ""Filter text" only accept strings

await toolbar.applyFilter({ "Revision": {from: "01/01/2024", to: "01/01/2024" }); // Correct

Note: the current e2e tests are failing due to a backend issue that does not allow uploading parallel files, the backend engineers are working on fixing it. When we review this PR we can focus on the code and it won't be merged until the e2e tests are healthy again

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 4, 2025

Reviewer's Guide

This PR refactors the Toolbar helper to be fully type-safe by parameterizing its available filters at build time, introducing a mapping from filter keys to value types, adding type-guard functions, unifying all filter application into a single generic applyFilter method, and updating all page objects and tests to supply filter schemas and use the new API.

File-Level Changes

Change Details Files
Define filter type mappings and type guards
  • Introduce TFilterValue, TDateRange, TMultiValue, FilterValueTypeMap and FilterValueType generic types
  • Add isStringFilter, isDateRangeFilter, isMultiSelectFilter and isTypeaheadFilter type-guard functions
e2e/tests/ui/pages/Toolbar.ts
Unify filter application in Toolbar into a generic applyFilter method
  • Make Toolbar generic over TFilter, store provided filters in the instance
  • Replace separate public applyTextFilter, applyDateRangeFilter, applyMultiSelectFilter and applyLabelsFilter methods with private generic implementations
  • Implement applyFilter to iterate over keys, detect filter type via guards, and delegate to the correct private method
e2e/tests/ui/pages/Toolbar.ts
Switch test calls to use the new typed applyFilter API
  • Replace all direct calls to applyTextFilter, applyDateRangeFilter, applyMultiSelectFilter and applyLabelsFilter with applyFilter({ … })
  • Adjust arguments to object literals matching the new FilterValueType schema
e2e/tests/ui/pages/sbom-list/filter.spec.ts
e2e/tests/ui/pages/vulnerability-list/filter.spec.ts
e2e/tests/ui/pages/advisory-list/filter.spec.ts
e2e/tests/ui/pages/package-list/filter.spec.ts
e2e/tests/ui/pages/sbom-details/packages/filter.spec.ts
e2e/tests/ui/pages/sbom-details/vulnerabilities/filter.spec.ts
e2e/tests/ui/pages/advisory-list/columns.spec.ts
e2e/tests/ui/pages/package-list/columns.spec.ts
e2e/tests/ui/pages/sbom-details/packages/columns.spec.ts
e2e/tests/ui/pages/sbom-list/columns.spec.ts
e2e/tests/ui/pages/vulnerability-list/columns.spec.ts
e2e/tests/ui/pages/advisory-details/AdvisoryDetailsPage.ts
e2e/tests/ui/pages/vulnerability-details/VulnerabilityDetailsPage.ts
e2e/tests/ui/pages/sbom-details/SbomDetailsPage.ts
e2e/tests/ui/pages/package-details/PackageDetailsPage.ts
Provide filter definitions when building Toolbar in page objects
  • Update getToolbar methods to pass a filter-to-type mapping object into Toolbar.build
  • Define available filters per page with keys and corresponding filter types
e2e/tests/ui/pages/package-list/PackageListPage.ts
e2e/tests/ui/pages/sbom-list/SbomListPage.ts
e2e/tests/ui/pages/advisory-list/AdvisoryListPage.ts
e2e/tests/ui/pages/vulnerability-list/VulnerabilityListPage.ts
e2e/tests/ui/pages/sbom-details/packages/PackagesTab.ts
e2e/tests/ui/pages/vulnerability-details/advisories/AdvisoriesTab.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Consider making the filters argument required (remove the default empty object) so you can’t accidentally build a Toolbar with no filter definitions.
  • In applyFilter, add a final else or default case that throws when no filter type matches to avoid silently dropping invalid filter/value calls.
  • Enhance the type-guard functions to verify the runtime shape of the filter values (e.g. check dateRange has from and to, multiSelect is an array) so misconfigurations fail fast.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider making the `filters` argument required (remove the default empty object) so you can’t accidentally build a Toolbar with no filter definitions.
- In `applyFilter`, add a final `else` or `default` case that throws when no filter type matches to avoid silently dropping invalid filter/value calls.
- Enhance the type-guard functions to verify the runtime shape of the filter values (e.g. check `dateRange` has `from` and `to`, `multiSelect` is an array) so misconfigurations fail fast.

## Individual Comments

### Comment 1
<location> `e2e/tests/ui/pages/package-list/filter.spec.ts:38` </location>
<code_context>

     // Architecture
-    await toolbar.applyMultiSelectFilter("Architecture", ["S390", "No Arch"]);
+    await toolbar.applyFilter({ Architecture: ["S390", "No Arch"] });
     await table.waitUntilDataIsLoaded();
     await table.verifyTableHasNoData();
</code_context>

<issue_to_address>
**suggestion (testing):** Missing test for applying multiple filters simultaneously.

Add a test that applies multiple filters together to verify compound filtering works as expected.
</issue_to_address>

### Comment 2
<location> `e2e/tests/ui/pages/vulnerability-list/filter.spec.ts:24` </location>
<code_context>

     // Severity filter
-    await toolbar.applyMultiSelectFilter("CVSS", ["Unknown", "Medium"]);
+    await toolbar.applyFilter({ CVSS: ["Unknown", "Medium"] });
     await table.waitUntilDataIsLoaded();
     await table.verifyColumnContainsText("ID", "CVE-2024-26308");
</code_context>

<issue_to_address>
**suggestion (testing):** No test for empty filter application.

Add a test for `applyFilter({})` to ensure the Toolbar handles empty filters without errors or unintended behavior.

Suggested implementation:

```typescript
    // Severity filter

    // Empty filter application
    await toolbar.applyFilter({});
    await table.waitUntilDataIsLoaded();
    // Optionally, verify that the table is loaded and contains expected data or is not empty
    // For example, check that the table has at least one row
    expect(await table.getRowCount()).toBeGreaterThan(0);

    // Severity filter
    await toolbar.applyFilter({ CVSS: ["Unknown", "Medium"] });
    await table.waitUntilDataIsLoaded();
    await table.verifyColumnContainsText("ID", "CVE-2024-26308");

```

- If `table.getRowCount()` is not available, replace it with the appropriate method to check that the table is loaded and not empty.
- Adjust the assertion to match your application's expected behavior after applying an empty filter (e.g., all rows visible, no errors).
</issue_to_address>

### Comment 3
<location> `e2e/tests/ui/pages/advisory-list/filter.spec.ts:31` </location>
<code_context>

     // Labels filter
-    await toolbar.applyLabelsFilter("Label", ["type=cve"]);
+    await toolbar.applyFilter({ Label: ["type=cve"] });
     await table.waitUntilDataIsLoaded();
     await table.verifyColumnContainsText("ID", "CVE-2024-26308");
</code_context>

<issue_to_address>
**suggestion (testing):** No test for filter value edge cases (e.g., empty string, empty array).

Please add tests for filters with empty strings and empty arrays to verify correct UI behavior.

Suggested implementation:

```typescript
    // Labels filter
    // Edge case: empty string
    await toolbar.applyFilter({ Label: [""] });
    await table.waitUntilDataIsLoaded();
    // Expectation: table should show all data or no data depending on filter logic
    // Example: verify that at least one row is present (adjust as needed)
    await table.verifyTableHasRows();

    // Edge case: empty array
    await toolbar.applyFilter({ Label: [] });
    await table.waitUntilDataIsLoaded();
    // Expectation: table should show all data or no data depending on filter logic
    // Example: verify that at least one row is present (adjust as needed)
    await table.verifyTableHasRows();

```

- Adjust the expectation in `verifyTableHasRows()` to match your application's intended behavior for empty filters. If the table should be empty, use a method like `verifyTableIsEmpty()` instead.
- If your test framework has a more specific way to check for "no filter applied" or "empty filter", use that instead of the generic row check.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@carlosthe19916 carlosthe19916 added the backport release/0.4.z This PR should be backported to release/0.4.z branch. label Nov 4, 2025
Copy link
Contributor

@mrrajan mrrajan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@carlosthe19916 While running the tests locally, there are couple of errors occurred for CVSS score and severity which is due to known issue. But the sorting validation on SBOM list page and package details page - ui/pages/sbom-list/sort.spec.ts:13 and ui/pages/sbom-details/packages/sort.spec.ts:13 failed. Even though these errors not related to these changes, just highlighting that the sorting has been changed on the UI.

I am running against upstream release/0.4.z branch.

@carlosthe19916
Copy link
Collaborator Author

@carlosthe19916 While running the tests locally, there are couple of errors occurred for CVSS score and severity which is due to known issue. But the sorting validation on SBOM list page and package details page - ui/pages/sbom-list/sort.spec.ts:13 and ui/pages/sbom-details/packages/sort.spec.ts:13 failed. Even though these errors not related to these changes, just highlighting that the sorting has been changed on the UI.

I am running against upstream release/0.4.z branch.

Yeah, I don't think we should merge this PR until the e2e tests are back to healthy, I would like to avoid adding more commits and take the risk, let's wait.

On the other hand, this PR is targeting the main branch therefore it should be tested against it not against release/0.4.z branch. Once this PR is merged it will be backported and moved to the release/0.4.z branch and then that code can be triggered against the backend relase/0.4.z.

@carlosthe19916 carlosthe19916 removed the backport release/0.4.z This PR should be backported to release/0.4.z branch. label Nov 21, 2025
@codecov
Copy link

codecov bot commented Nov 21, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.59%. Comparing base (35fe4f5) to head (934f9a7).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #822      +/-   ##
==========================================
- Coverage   62.46%   61.59%   -0.88%     
==========================================
  Files         170      170              
  Lines        3080     3080              
  Branches      698      698              
==========================================
- Hits         1924     1897      -27     
- Misses        892      927      +35     
+ Partials      264      256       -8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants