mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 04:51:51 +00:00
test(ui): add scans E2E test suite and enhance scans functionality
- Introduced a new scans test suite to validate the on-demand scan execution flow. - Added methods in the ScansPage class for selecting providers, filling scan aliases, and verifying scan launches. - Updated the ProvidersPage class to include a method for adding AWS providers. - Created comprehensive end-to-end tests for executing scans, including necessary preconditions and environment variable checks. - Documented the new test cases and flow in the scans markdown file.
This commit is contained in:
@@ -96,6 +96,12 @@ export default defineConfig({
|
||||
name: "sign-up",
|
||||
testMatch: "sign-up.spec.ts",
|
||||
},
|
||||
// This project runs the scans test suite
|
||||
{
|
||||
name: "scans",
|
||||
testMatch: "scans.spec.ts",
|
||||
dependencies: ["admin.auth.setup"],
|
||||
},
|
||||
// This project runs the providers test suite
|
||||
{
|
||||
name: "providers",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Page, Locator, expect } from "@playwright/test";
|
||||
import { BasePage } from "../base-page";
|
||||
import { ScansPage } from "../scans/scans-page";
|
||||
|
||||
// AWS provider data
|
||||
export interface AWSProviderData {
|
||||
@@ -954,4 +955,60 @@ export class ProvidersPage extends BasePage {
|
||||
await this.goto();
|
||||
await expect(this.providersTable).toBeVisible({ timeout: 10000 });
|
||||
}
|
||||
|
||||
async AddAWSProvider(
|
||||
accountId: string,
|
||||
accessKey: string,
|
||||
secretKey: string,
|
||||
): Promise<void> {
|
||||
|
||||
// Prepare test data for AWS provider
|
||||
const awsProviderData: AWSProviderData = {
|
||||
accountId: accountId,
|
||||
alias: "Test E2E AWS Account - Credentials",
|
||||
};
|
||||
|
||||
// Prepare static credentials
|
||||
const staticCredentials: AWSProviderCredential = {
|
||||
type: AWS_CREDENTIAL_OPTIONS.AWS_CREDENTIALS,
|
||||
accessKeyId: accessKey,
|
||||
secretAccessKey: secretKey,
|
||||
};
|
||||
|
||||
// Create providers page object
|
||||
const providersPage = new ProvidersPage(this.page);
|
||||
|
||||
// Navigate to providers page
|
||||
await providersPage.goto();
|
||||
await providersPage.verifyPageLoaded();
|
||||
|
||||
// Start adding new provider
|
||||
await providersPage.clickAddProvider();
|
||||
await providersPage.verifyConnectAccountPageLoaded();
|
||||
|
||||
// Select AWS provider
|
||||
await providersPage.selectAWSProvider();
|
||||
|
||||
// Fill provider details
|
||||
await providersPage.fillAWSProviderDetails(awsProviderData);
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Select static credentials type
|
||||
await providersPage.selectCredentialsType(
|
||||
AWS_CREDENTIAL_OPTIONS.AWS_CREDENTIALS,
|
||||
);
|
||||
await providersPage.verifyCredentialsPageLoaded();
|
||||
|
||||
// Fill static credentials
|
||||
await providersPage.fillStaticCredentials(staticCredentials);
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Launch scan
|
||||
await providersPage.verifyLaunchScanPageLoaded();
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Wait for redirect to provider page
|
||||
const scansPage = new ScansPage(this.page);
|
||||
await scansPage.verifyPageLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,22 @@ export class ScansPage extends BasePage {
|
||||
|
||||
// Main content elements
|
||||
readonly scanTable: Locator;
|
||||
|
||||
// Scan provider selection elements
|
||||
readonly scanProviderSelect: Locator;
|
||||
readonly scanAliasInput: Locator;
|
||||
readonly startNowButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
|
||||
// Scan provider selection elements
|
||||
this.scanProviderSelect = page.getByRole("button", { name: "Select a cloud provider to launch a scan" });
|
||||
this.scanAliasInput = page.getByRole("textbox", { name: "Scan label (optional)" });
|
||||
this.startNowButton = page.getByRole("button", { name: /Start now|Start scan now/i });
|
||||
|
||||
// Main content elements
|
||||
this.scanTable = page.locator("table");
|
||||
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
@@ -19,10 +29,69 @@ export class ScansPage extends BasePage {
|
||||
await super.goto("/scans");
|
||||
}
|
||||
|
||||
// Verification methods
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
// Verify the scans page is loaded
|
||||
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.scanTable).toBeVisible();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async selectProviderByUID(uid: string): Promise<void> {
|
||||
// Select the provider by UID
|
||||
|
||||
await this.scanProviderSelect.click();
|
||||
await this.page.getByRole("option", { name: new RegExp(uid) }).click();
|
||||
}
|
||||
|
||||
async fillScanAlias(alias: string): Promise<void> {
|
||||
// Fill the scan alias
|
||||
|
||||
await this.scanAliasInput.fill(alias);
|
||||
}
|
||||
|
||||
async clickStartNowButton(): Promise<void> {
|
||||
// Click the start now button
|
||||
|
||||
await expect(this.startNowButton).toBeVisible();
|
||||
await this.startNowButton.click();
|
||||
}
|
||||
|
||||
async verifyScanLaunched(alias: string): Promise<void> {
|
||||
// Verify the scan was launched
|
||||
|
||||
// Optional success toast (best-effort)
|
||||
const successToast = this.page.getByRole("alert", { name: "The scan was launched successfully." }).getByText(
|
||||
"The scan was launched successfully.",
|
||||
);
|
||||
|
||||
// Verify the success toast is visible
|
||||
await successToast.isVisible().catch(() => {});
|
||||
|
||||
// Wait for the scans table to be visible
|
||||
await expect(this.scanTable).toBeVisible();
|
||||
|
||||
// Find a row that contains the scan alias
|
||||
const rowWithAlias = this.scanTable
|
||||
.locator("tbody tr")
|
||||
.filter({ hasText: alias })
|
||||
.first();
|
||||
|
||||
// Verify the row with the scan alias is visible
|
||||
await expect(rowWithAlias).toBeVisible();
|
||||
|
||||
// Basic state/assertion hint: queued/available/executing (non-blocking if not present)
|
||||
await rowWithAlias.textContent().then((text) => {
|
||||
|
||||
if (!text) return;
|
||||
|
||||
const hasExpectedState = /executing|available|queued/i.test(text);
|
||||
|
||||
if (!hasExpectedState) {
|
||||
// Fall back to just ensuring alias is present in the row
|
||||
// The expectation above already ensures visibility
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
### E2E Tests: Scans - On Demand
|
||||
|
||||
**Suite ID:** `SCANS-E2E`
|
||||
**Feature:** On-demand Scans.
|
||||
|
||||
---
|
||||
|
||||
## Test Case: `SCANS-E2E-001` - Execute On-Demand Scan
|
||||
|
||||
**Priority:** `critical`
|
||||
|
||||
**Tags:**
|
||||
|
||||
- type → @e2e, @serial
|
||||
- feature → @scans
|
||||
|
||||
**Description/Objective:** Validates the complete flow to execute an on-demand scan selecting a provider by UID and confirming success on the Scans page.
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
- Admin user authentication required (admin.auth.setup setup)
|
||||
- Environment variables configured for : E2E_AWS_PROVIDER_ACCOUNT_ID,E2E_AWS_PROVIDER_ACCESS_KEY and E2E_AWS_PROVIDER_SECRET_KEY
|
||||
- Remove any existing AWS provider with the same Account ID before starting the test
|
||||
- This test must be run serially and never in parallel with other tests, as it requires the Account ID Provider to be already registered.
|
||||
|
||||
### Flow Steps:
|
||||
|
||||
1. Navigate to Scans page
|
||||
2. Open provider selector and choose the entry whose text contains E2E_AWS_PROVIDER_ACCOUNT_ID
|
||||
3. Optionally fill scan label (alias)
|
||||
4. Click "Start now" to launch the scan
|
||||
5. Verify the success toast appears
|
||||
6. Verify a row in the Scans table contains the provided scan label (or shows the new scan entry)
|
||||
|
||||
### Expected Result:
|
||||
|
||||
- Scan is launched successfully
|
||||
- Success toast is displayed to the user
|
||||
- Scans table displays the new scan entry (including the alias when provided)
|
||||
|
||||
### Key verification points:
|
||||
|
||||
- Scans page loads correctly
|
||||
- Provider select is available and lists the configured provider UID
|
||||
- "Start now" button is rendered and enabled when form is valid
|
||||
- Success toast message: "The scan was launched successfully."
|
||||
- Table contains a row with the scan label or new scan state (queued/available/executing)
|
||||
|
||||
### Notes:
|
||||
|
||||
- The table may take a short time to reflect the new scan; assertions look for a row containing the alias.
|
||||
- Provider cleanup performed before each test to ensure clean state
|
||||
- Tests should run serially to avoid state conflicts.
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { ScansPage } from "./scans-page";
|
||||
import { ProvidersPage } from "../providers/providers-page";
|
||||
|
||||
// Scans E2E suite scaffold
|
||||
test.describe("Scans", () => {
|
||||
test.describe.serial("Execute Scans", () => {
|
||||
// Scans page object
|
||||
let scansPage: ScansPage;
|
||||
|
||||
// Use scans-specific authenticated user
|
||||
test.use({ storageState: "playwright/.auth/admin_user.json" });
|
||||
|
||||
// Before each scans test, ensure an AWS provider exists using admin context
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// Create scans page object
|
||||
const providersPage = new ProvidersPage(page);
|
||||
|
||||
// Test data from environment variables
|
||||
const accountId = process.env.E2E_AWS_PROVIDER_ACCOUNT_ID;
|
||||
const accessKey = process.env.E2E_AWS_PROVIDER_ACCESS_KEY;
|
||||
const secretKey = process.env.E2E_AWS_PROVIDER_SECRET_KEY;
|
||||
|
||||
if (!accountId || !accessKey || !secretKey) {
|
||||
throw new Error(
|
||||
"E2E_AWS_PROVIDER_ACCOUNT_ID, E2E_AWS_PROVIDER_ACCESS_KEY, and E2E_AWS_PROVIDER_SECRET_KEY environment variables are not set",
|
||||
);
|
||||
}
|
||||
|
||||
// Clean up existing provider to ensure clean test state
|
||||
await providersPage.deleteProviderIfExists(accountId);
|
||||
// Add AWS provider
|
||||
await providersPage.AddAWSProvider(accountId, accessKey, secretKey);
|
||||
});
|
||||
|
||||
test(
|
||||
"should execute on demand scan",
|
||||
{
|
||||
tag: ["@e2e", "@scans", "@critical", "@serial", "@SCAN-E2E-001"],
|
||||
},
|
||||
async ({ page }) => {
|
||||
|
||||
const accountId = process.env.E2E_AWS_PROVIDER_ACCOUNT_ID;
|
||||
|
||||
if (!accountId) {
|
||||
throw new Error(
|
||||
"E2E_AWS_PROVIDER_ACCOUNT_ID environment variable is not set",
|
||||
);
|
||||
}
|
||||
|
||||
scansPage = new ScansPage(page);
|
||||
await scansPage.goto();
|
||||
|
||||
// Select provider by UID (accountId)
|
||||
await scansPage.selectProviderByUID(accountId);
|
||||
|
||||
// Complete scan alias
|
||||
await scansPage.fillScanAlias("E2E Test Scan - On Demand");
|
||||
|
||||
// Press start now button
|
||||
await scansPage.clickStartNowButton();
|
||||
|
||||
// Verify the scan was launched
|
||||
await scansPage.verifyScanLaunched("E2E Test Scan - On Demand");
|
||||
|
||||
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user