test(ui): align provider e2e no-scan flow

This commit is contained in:
Alan Buscaglia
2026-06-29 15:48:20 +02:00
parent 99e6ceed82
commit e663e8face
3 changed files with 21 additions and 23 deletions
+20 -17
View File
@@ -936,9 +936,11 @@ export class ProvidersPage extends BasePage {
}
}
private async waitForProviderLaunchChoice(timeout = 30000): Promise<void> {
const launchAction = this.page
.getByRole("button", { name: "Save", exact: true })
private async waitForProviderReadyToClose(): Promise<void> {
const launchStepReady = this.page
.getByText("Account Connected!", { exact: true })
.or(this.page.getByText("Loading scan options...", { exact: true }))
.or(this.page.getByRole("button", { name: "Save", exact: true }))
.or(this.page.getByRole("button", { name: "Launch scan", exact: true }));
const connectionError = this.page.locator(
"div.border-border-error p.text-text-error-primary",
@@ -946,8 +948,8 @@ export class ProvidersPage extends BasePage {
try {
await Promise.race([
launchAction.waitFor({ state: "visible", timeout }),
connectionError.waitFor({ state: "visible", timeout }),
launchStepReady.waitFor({ state: "visible", timeout: 30000 }),
connectionError.waitFor({ state: "visible", timeout: 30000 }),
]);
} catch {
// Continue and inspect visible state below.
@@ -960,12 +962,11 @@ export class ProvidersPage extends BasePage {
);
}
await expect(launchAction).toBeVisible({ timeout });
await expect(launchStepReady).toBeVisible({ timeout: 30000 });
}
async completeProviderConnectionWithoutLaunchingScan(
providerUID: string,
timeout = 30000,
): Promise<void> {
await this.verifyWizardModalOpen();
@@ -973,20 +974,22 @@ export class ProvidersPage extends BasePage {
name: "Check connection",
exact: true,
});
const launchAction = this.page
.getByRole("button", { name: "Save", exact: true })
const launchStepReady = this.page
.getByText("Account Connected!", { exact: true })
.or(this.page.getByText("Loading scan options...", { exact: true }))
.or(this.page.getByRole("button", { name: "Save", exact: true }))
.or(this.page.getByRole("button", { name: "Launch scan", exact: true }));
const connectionError = this.page.locator(
"div.border-border-error p.text-text-error-primary",
);
// The test-connection step renders its footer action only after an async
// load (canSubmit gate). Wait for the footer to settle on an actionable
// state (or surface a connection error) instead of reading visibility on
// the first frame, which races the render and falls through.
// The no-launch provider tests only need to know that the provider reached
// the post-connection step. Do not depend exclusively on scan launch/schedule
// actions, because those controls are owned by the launch flow and can be
// hidden while scan options load.
await expect(
checkConnectionButton.or(launchAction).or(connectionError),
).toBeVisible({ timeout });
checkConnectionButton.or(launchStepReady).or(connectionError),
).toBeVisible({ timeout: 30000 });
if (await connectionError.isVisible().catch(() => false)) {
const errorText = await connectionError.textContent();
@@ -1000,9 +1003,9 @@ export class ProvidersPage extends BasePage {
// scan execution itself is covered by scans.spec.ts.
if (await checkConnectionButton.isVisible().catch(() => false)) {
await checkConnectionButton.click();
await this.waitForProviderLaunchChoice(timeout);
await this.waitForProviderReadyToClose();
} else {
await expect(launchAction).toBeVisible({ timeout });
await expect(launchStepReady).toBeVisible({ timeout: 30000 });
}
await this.wizardModal
+1 -1
View File
@@ -1092,7 +1092,7 @@
- Environment variables configured: E2E_OKTA_DOMAIN, E2E_OKTA_CLIENT_ID, E2E_OKTA_BASE64_PRIVATE_KEY
- Remove any existing provider with the same Org Domain before starting the test
- This test must be run serially and never in parallel with other tests, as it requires the Org Domain not to be already registered beforehand.
- Okta provider authentication can take longer than the default Playwright test timeout in CI, so the test allows extra time for the provider connection step.
- The test validates provider creation and connection only; scan execution is covered by the Scans E2E suite.
### Flow Steps
-5
View File
@@ -1430,8 +1430,6 @@ test.describe("Add Provider", () => {
const orgDomain = (process.env.E2E_OKTA_DOMAIN ?? "").toLowerCase();
const clientId = process.env.E2E_OKTA_CLIENT_ID ?? "";
const privateKeyB64 = process.env.E2E_OKTA_BASE64_PRIVATE_KEY ?? "";
const oktaProviderTestTimeout = 150_000;
const oktaProviderConnectionTimeout = 60_000;
// Setup before each test
test.beforeEach(async ({ page }) => {
@@ -1459,8 +1457,6 @@ test.describe("Add Provider", () => {
],
},
async ({ page }) => {
test.setTimeout(oktaProviderTestTimeout);
// The Okta app private key is PEM-encoded (multi-line), so it is passed
// base64-encoded via the environment variable and decoded here.
const privateKey = Buffer.from(privateKeyB64, "base64").toString(
@@ -1505,7 +1501,6 @@ test.describe("Add Provider", () => {
// Confirm the provider connection without launching a scan
await providersPage.completeProviderConnectionWithoutLaunchingScan(
orgDomain,
oktaProviderConnectionTimeout,
);
},
);