Skip to content

test(e2e): fix downstream failures for UI tests regarding the Importe… - #1203

Open
matejnesuta wants to merge 4 commits into
guacsec:mainfrom
matejnesuta:importer-flake-fix
Open

test(e2e): fix downstream failures for UI tests regarding the Importe…#1203
matejnesuta wants to merge 4 commits into
guacsec:mainfrom
matejnesuta:importer-flake-fix

Conversation

@matejnesuta

@matejnesuta matejnesuta commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

Some of the importer UI tests fail on downstream setups, as the downstream setup does not contain specific Importer objects, which are expected by the tests. This PR fixes the issue.

Related Issues

TC-5453

Type of Change

  • Bug fix

Testing

  • All tests pass both on local upstream env and a downstream 3.0 deployment

Summary by Sourcery

Ensure importer UI end-to-end tests provision their required data so they pass consistently across deployment environments.

Bug Fixes:

  • Make importer UI end-to-end tests reliable across upstream and downstream deployments by creating any required importer fixtures before scenarios run.

Enhancements:

  • Use the configured API endpoint and authenticated session token to verify and provision missing importer resources during tests.
  • Replace environment-specific importer examples with dedicated test importers and allow longer time for importer enablement.

Tests:

  • Add shared importer setup and authentication helpers for UI test scenarios.

@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds helper utilities to ensure required importer configurations exist via the backend API before running UI importer tests, and wires these helpers into relevant Playwright BDD steps to prevent downstream failures where importers are missing.

File-Level Changes

Change Details Files
Introduce reusable helpers to create/check importer configurations via the importer API based on predefined configs.
  • Defined IMPORTER_CONFIGS as a mapping of importer names to their API payload configuration, including clearly-defined-curations and cve-from-2024 sample data.
  • Implemented getOidcAccessToken to retrieve the OIDC access token from window.sessionStorage for authenticated API calls.
  • Added ensureImporterExists to lazily create a single importer via /api/v3/importer/{name} if a 404 is returned, then reload the page so the UI reflects changes.
  • Added ensureAllImportersExist to iterate over IMPORTER_CONFIGS, creating any missing importers in one pass and reloading the page once if needed.
e2e/tests/ui/helpers/Importer.ts
Wire importer existence helpers into importer explorer E2E tests to make them robust across downstream deployments.
  • Imported ensureAllImportersExist, ensureImporterExists, and IMPORTER_CONFIGS into importer-explorer.step.ts.
  • Ensured all predefined importers exist when navigating to the Importers page by calling ensureAllImportersExist after page build.
  • Before applying a filter, pre-created any importers whose names match the filter value using ensureImporterExists and IMPORTER_CONFIGS.
  • When enabling a disabled importer, increased the test timeout and ensured the importer exists (if configured) prior to interacting with the UI.
e2e/tests/ui/features/@importer-explorer/importer-explorer.step.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

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • The logic for resolving base URL, building headers (including the OIDC token) and performing GET/POST requests is duplicated between ensureImporterExists and ensureAllImportersExist; consider extracting a small helper to centralize this and reduce the chance of future inconsistencies.
  • Both helpers rely on page.waitForTimeout(1000) after reloads; it would be more robust to wait for a specific UI condition (e.g., table selector/state) or network idle instead of a fixed delay to reduce flakiness.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The logic for resolving base URL, building headers (including the OIDC token) and performing GET/POST requests is duplicated between `ensureImporterExists` and `ensureAllImportersExist`; consider extracting a small helper to centralize this and reduce the chance of future inconsistencies.
- Both helpers rely on `page.waitForTimeout(1000)` after reloads; it would be more robust to wait for a specific UI condition (e.g., table selector/state) or network idle instead of a fixed delay to reduce flakiness.

## Individual Comments

### Comment 1
<location path="e2e/tests/ui/helpers/Importer.ts" line_range="123-91" />
<code_context>
+    }
+  }
+
+  if (anyCreated) {
+    await page.reload();
+    await page.waitForTimeout(1000);
+  }
+};
</code_context>
<issue_to_address>
**suggestion (testing):** Replace fixed sleep with a UI-level wait to reduce flakiness

Since this helper uses `page.reload()` followed by `waitForTimeout(1000)`, the test may become flaky under load or on slower environments. Prefer waiting on a specific UI condition (e.g. the importer row appearing or a stable table selector) instead of a fixed delay, so the test only proceeds once the UI is actually ready.

Suggested implementation:

```typescript
  if (anyCreated) {
    await page.reload();

    // Wait for the page to be fully loaded and the importer table to be visible
    await Promise.all([
      page.waitForLoadState("networkidle"),
      page.waitForSelector('[data-testid="importers-table"]', { state: "visible" }),
    ]);
  }
};

```

1. Ensure that the selector `[data-testid="importers-table"]` exists in the importer UI. If your app uses a different data-testid or selector for the importer list/table, update the selector in `waitForSelector` accordingly (e.g. a row selector like `[data-testid="importer-row"]`).
2. If your project prefers a different load state (e.g. `"domcontentloaded"` instead of `"networkidle"`), adjust `waitForLoadState` to match your existing Playwright patterns.
</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.

Comment thread e2e/tests/ui/helpers/Importer.ts Outdated
data: importerConfig,
});
await page.reload();
await page.waitForTimeout(1000);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion (testing): Replace fixed sleep with a UI-level wait to reduce flakiness

Since this helper uses page.reload() followed by waitForTimeout(1000), the test may become flaky under load or on slower environments. Prefer waiting on a specific UI condition (e.g. the importer row appearing or a stable table selector) instead of a fixed delay, so the test only proceeds once the UI is actually ready.

Suggested implementation:

  if (anyCreated) {
    await page.reload();

    // Wait for the page to be fully loaded and the importer table to be visible
    await Promise.all([
      page.waitForLoadState("networkidle"),
      page.waitForSelector('[data-testid="importers-table"]', { state: "visible" }),
    ]);
  }
};
  1. Ensure that the selector [data-testid="importers-table"] exists in the importer UI. If your app uses a different data-testid or selector for the importer list/table, update the selector in waitForSelector accordingly (e.g. a row selector like [data-testid="importer-row"]).
  2. If your project prefers a different load state (e.g. "domcontentloaded" instead of "networkidle"), adjust waitForLoadState to match your existing Playwright patterns.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 54.20%. Comparing base (00adb72) to head (f36d13e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1203      +/-   ##
==========================================
+ Coverage   54.19%   54.20%   +0.01%     
==========================================
  Files         255      255              
  Lines        5715     5715              
  Branches     1774     1774              
==========================================
+ Hits         3097     3098       +1     
  Misses       2355     2355              
+ Partials      263      262       -1     
Flag Coverage Δ
e2e 70.38% <ø> (+0.02%) ⬆️
unit 8.65% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 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.

@vobratil vobratil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@matejnesuta I appreciate what you're trying to do here, but I'm not sure I agree with the approach. Currently we have a problem with the importer tests failing, because we don't have the importers set up. But that's often on purpose, since for a lot of testing it's just nicer to have a clean instance. I don't think importers should be automatically enabled every time we run the testsuite. Instead, I would like to propose conditionally skipping the importer tests, if importers are not enabled. We have an example of a conditionally skipped test here:

If you don't agree, feel free to bring up the topic at the nearest QE sync and we can see what others think.

Comment thread e2e/tests/ui/helpers/Importer.ts Outdated
},
};

const getOidcAccessToken = (page: Page): Promise<string | null> =>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We shouldn't make another method for this, since we already have on here:

const getToken = async (baseURL?: string) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If it's not suitable for the use case for any reason, please just try to alter the method first, if possible.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I rewrote the thing. Now the token is obtain directly from the session right after the UI login is successful. I hope it is fine, I felt kind of weird reusing API fixtures in the UI suite and it also caused some issues on downstream setups.

Comment thread e2e/tests/ui/helpers/Importer.ts Outdated
importerName: string,
importerConfig: ImporterConfig,
) => {
const accessToken = await getOidcAccessToken(page);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actually, this whole thing with getting an access token should be unnecessary, since we should be using our custom axios fixture that takes care of this automatically. Calling the API should be enough.

Comment thread e2e/tests/ui/helpers/Importer.ts Outdated
* sessionStorage is accessible. Reloads once if any importer was created.
*/
export const ensureAllImportersExist = async (page: Page): Promise<void> => {
const accessToken = await getOidcAccessToken(page);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as above.

@queria

queria commented Aug 18, 2026

Copy link
Copy Markdown

I am bit concerned about adding actual proper importers mid-test too, as mentioned by Vilem, they could pull in data which can break the other tests.

The other side of the problem is of course not having any Importer results in all these Importer tests to fail.

What I was thinking about is, if we could ensure we have exact for-tests importer(s) added (as part of setup) - in a way where such importer(s) would not pull in any data - or only such data which do not collide.

As other problem importers may cause depending on the setup/env is the amount of resources and time consumed.

So I would advocate for only very controlled ones:

  • limited to exact 1-5 items to import (or such low counts) (so use importers which allow selecting by regexp and such)
  • to finish importing in seconds or at most some minute
  • to pull in data we can select to not collide with any other tests

@matejnesuta
matejnesuta requested a review from vobratil August 21, 2026 11:57
@matejnesuta

matejnesuta commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

As a part of this PR, I created a repository with 50000 fake advisories*. These advisories do not reference any real packages, so they should not cause any conflicts for the rest of the test suite. I hope it is fine this way.

*Well, it contains 4 different fake advisories copied multiple times, just with different CVE-XXXX-XXXXX ID.

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

3 participants