mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
test(ui): add AWS provider management E2E tests
- Introduced new E2E tests for adding AWS providers with both static and role-based credentials. - Updated Playwright configuration to include a new test suite for providers. - Enhanced the UI workflow by adding necessary environment variables for E2E testing. - Created helper functions for provider management actions and validations.
This commit is contained in:
@@ -18,6 +18,12 @@ jobs:
|
||||
AUTH_TRUST_HOST: true
|
||||
NEXTAUTH_URL: 'http://localhost:3000'
|
||||
NEXT_PUBLIC_API_BASE_URL: 'http://localhost:8080/api/v1'
|
||||
E2E_ADMIN_USER: ${{ secrets.E2E_ADMIN_USER }}
|
||||
E2E_ADMIN_PASSWORD: ${{ secrets.E2E_ADMIN_PASSWORD }}
|
||||
E2E_AWS_PROVIDER_ACCOUNT_ID: ${{ secrets.E2E_AWS_PROVIDER_ACCOUNT_ID }}
|
||||
E2E_AWS_PROVIDER_ACCESS_KEY: ${{ secrets.E2E_AWS_PROVIDER_ACCESS_KEY }}
|
||||
E2E_AWS_PROVIDER_SECRET_KEY: ${{ secrets.E2E_AWS_PROVIDER_SECRET_KEY }}
|
||||
E2E_AWS_PROVIDER_ROLE_ARN: ${{ secrets.E2E_AWS_PROVIDER_ROLE_ARN }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
+4
-4
@@ -15,10 +15,10 @@
|
||||
"format:check": "./node_modules/.bin/prettier --check ./app",
|
||||
"format:write": "./node_modules/.bin/prettier --config .prettierrc.json --write ./app",
|
||||
"prepare": "husky",
|
||||
"test:e2e": "playwright test --project=chromium --project=sign-up",
|
||||
"test:e2e:ui": "playwright test --project=chromium --project=sign-up --ui",
|
||||
"test:e2e:debug": "playwright test --project=chromium --project=sign-up --debug",
|
||||
"test:e2e:headed": "playwright test --project=chromium --project=sign-up --headed",
|
||||
"test:e2e": "playwright test --project=chromium --project=sign-up --project=providers",
|
||||
"test:e2e:ui": "playwright test --project=chromium --project=sign-up --project=providers --ui",
|
||||
"test:e2e:debug": "playwright test --project=chromium --project=sign-up --project=providers --debug",
|
||||
"test:e2e:headed": "playwright test --project=chromium --project=sign-up --project=providers --headed",
|
||||
"test:e2e:report": "playwright show-report",
|
||||
"test:e2e:install": "playwright install"
|
||||
},
|
||||
|
||||
@@ -88,6 +88,12 @@ export default defineConfig({
|
||||
name: "sign-up",
|
||||
testMatch: "sign-up.spec.ts",
|
||||
},
|
||||
// This project runs the providers test suite
|
||||
{
|
||||
name: "providers",
|
||||
testMatch: "providers.spec.ts",
|
||||
dependencies: ["admin.auth.setup"],
|
||||
},
|
||||
],
|
||||
|
||||
webServer: {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Page, expect } from "@playwright/test";
|
||||
import { SignInPage, SignInCredentials } from "./sign-in/sign-in-page";
|
||||
import { ProvidersPage } from "./providers/providers-page";
|
||||
|
||||
export const ERROR_MESSAGES = {
|
||||
INVALID_CREDENTIALS: "Invalid email or password",
|
||||
@@ -187,3 +188,10 @@ export async function verifySessionValid(page: Page) {
|
||||
expect(session.refreshToken).toBeTruthy();
|
||||
return session;
|
||||
}
|
||||
|
||||
export async function deleteProviderIfExists(page: Page, accountId: string) {
|
||||
const providersPage = new ProvidersPage(page);
|
||||
if (await providersPage.verifyProviderExists(accountId)) {
|
||||
await providersPage.actionDeleteProvider(accountId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
import { Page, Locator, expect } from "@playwright/test";
|
||||
import { BasePage } from "../base-page";
|
||||
|
||||
export interface AWSProviderData {
|
||||
accountId: string;
|
||||
alias?: string;
|
||||
roleArn?: string;
|
||||
externalId?: string;
|
||||
accessKeyId?: string;
|
||||
secretAccessKey?: string;
|
||||
}
|
||||
|
||||
export interface ProviderCredentials {
|
||||
type: "role" | "credentials";
|
||||
roleArn?: string;
|
||||
externalId?: string;
|
||||
accessKeyId?: string;
|
||||
secretAccessKey?: string;
|
||||
}
|
||||
|
||||
export class ProvidersPage extends BasePage {
|
||||
readonly addProviderButton: Locator;
|
||||
readonly providersTable: Locator;
|
||||
|
||||
// Provider selection elements
|
||||
readonly awsProviderRadio: Locator;
|
||||
readonly gcpProviderRadio: Locator;
|
||||
readonly azureProviderRadio: Locator;
|
||||
readonly m365ProviderRadio: Locator;
|
||||
readonly kubernetesProviderRadio: Locator;
|
||||
readonly githubProviderRadio: Locator;
|
||||
|
||||
// AWS provider form elements
|
||||
readonly accountIdInput: Locator;
|
||||
readonly aliasInput: Locator;
|
||||
readonly nextButton: Locator;
|
||||
readonly backButton: Locator;
|
||||
readonly saveButton: Locator;
|
||||
readonly launchScanButton: Locator;
|
||||
|
||||
// AWS credentials type selection
|
||||
readonly roleCredentialsRadio: Locator;
|
||||
readonly staticCredentialsRadio: Locator;
|
||||
|
||||
// AWS role credentials form
|
||||
readonly roleArnInput: Locator;
|
||||
readonly externalIdInput: Locator;
|
||||
|
||||
// AWS static credentials form
|
||||
readonly accessKeyIdInput: Locator;
|
||||
readonly secretAccessKeyInput: Locator;
|
||||
|
||||
// Delete button
|
||||
readonly deleteProviderConfirmationButton: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
super(page);
|
||||
|
||||
// Button to add a new cloud provider
|
||||
this.addProviderButton = page.getByText("Add Cloud Provider", {
|
||||
exact: true,
|
||||
});
|
||||
|
||||
// Table displaying existing providers
|
||||
this.providersTable = page.getByRole("table");
|
||||
|
||||
// Radio buttons to select the type of cloud provider
|
||||
this.awsProviderRadio = page.getByRole("radio", {
|
||||
name: /Amazon Web Services/i,
|
||||
});
|
||||
this.gcpProviderRadio = page.getByRole("radio", {
|
||||
name: /Google Cloud Platform/i,
|
||||
});
|
||||
this.azureProviderRadio = page.getByRole("radio", {
|
||||
name: /Microsoft Azure/i,
|
||||
});
|
||||
this.m365ProviderRadio = page.getByRole("radio", {
|
||||
name: /Microsoft 365/i,
|
||||
});
|
||||
this.kubernetesProviderRadio = page.getByRole("radio", {
|
||||
name: /Kubernetes/i,
|
||||
});
|
||||
this.githubProviderRadio = page.getByRole("radio", { name: /GitHub/i });
|
||||
|
||||
// AWS provider form inputs
|
||||
this.accountIdInput = page.getByLabel("Account ID");
|
||||
this.aliasInput = page.getByLabel("Provider alias (optional)");
|
||||
|
||||
// Navigation buttons in the form (next and back)
|
||||
this.nextButton = page
|
||||
.locator("form")
|
||||
.getByRole("button", { name: "Next", exact: true });
|
||||
this.backButton = page.getByRole("button", { name: "Back" });
|
||||
|
||||
// Button to save the form
|
||||
this.saveButton = page.getByRole("button", { name: "Save", exact: true });
|
||||
|
||||
this.launchScanButton = page.getByRole("button", {
|
||||
name: "Launch scan",
|
||||
exact: true,
|
||||
});
|
||||
|
||||
// Radios for selecting AWS credentials method
|
||||
this.roleCredentialsRadio = page.getByRole("radio", {
|
||||
name: /Connect assuming IAM Role/i,
|
||||
});
|
||||
this.staticCredentialsRadio = page.getByRole("radio", {
|
||||
name: /Connect via Credentials/i,
|
||||
});
|
||||
|
||||
// Inputs for IAM Role credentials
|
||||
this.roleArnInput = page.getByLabel("Role ARN");
|
||||
this.externalIdInput = page.getByLabel("External ID");
|
||||
|
||||
// Inputs for static credentials
|
||||
this.accessKeyIdInput = page.getByLabel("Access Key ID");
|
||||
this.secretAccessKeyInput = page.getByLabel("Secret Access Key");
|
||||
|
||||
// Delete button
|
||||
this.deleteProviderConfirmationButton = page.locator(
|
||||
'button[aria-label="Delete"]',
|
||||
);
|
||||
}
|
||||
|
||||
async goto(): Promise<void> {
|
||||
await super.goto("/providers");
|
||||
}
|
||||
|
||||
async clickAddProvider(): Promise<void> {
|
||||
await this.addProviderButton.click();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async selectAWSProvider(): Promise<void> {
|
||||
// Prefer label-based click for radios, force if overlay intercepts
|
||||
await this.awsProviderRadio.click({ force: true });
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async fillAWSProviderDetails(data: AWSProviderData): Promise<void> {
|
||||
await this.accountIdInput.fill(data.accountId);
|
||||
if (data.alias) {
|
||||
await this.aliasInput.fill(data.alias);
|
||||
}
|
||||
}
|
||||
|
||||
async clickNext(): Promise<void> {
|
||||
// The wizard interface may use different labels for its primary action button on each step.
|
||||
// This function determines which button to click depending on the current URL and page content.
|
||||
|
||||
const url = this.page.url(); // Get the current page URL
|
||||
|
||||
// If on the "connect-account" step, click the "Next" button
|
||||
if (/\/providers\/connect-account/.test(url)) {
|
||||
await this.nextButton.click();
|
||||
await this.waitForPageLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
// If on the "add-credentials" step, check for "Save" and "Next" buttons
|
||||
if (/\/providers\/add-credentials/.test(url)) {
|
||||
// Some UI implementations use "Save" instead of "Next" for primary action
|
||||
const saveBtn = this.saveButton;
|
||||
if (await saveBtn.count()) {
|
||||
await saveBtn.click();
|
||||
await this.waitForPageLoad();
|
||||
return;
|
||||
}
|
||||
// If "Save" is not present, try clicking the "Next" button
|
||||
if (await this.nextButton.count()) {
|
||||
await this.nextButton.click();
|
||||
await this.waitForPageLoad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If on the "test-connection" step, click the "Launch scan" button
|
||||
if (/\/providers\/test-connection/.test(url)) {
|
||||
const buttonByText = this.page
|
||||
.locator("button")
|
||||
.filter({ hasText: "Launch scan" });
|
||||
await buttonByText.click();
|
||||
await this.waitForPageLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback logic: try finding any common primary action buttons in expected order
|
||||
const candidates = [
|
||||
{ name: "Next" }, // Try the "Next" button
|
||||
{ name: "Save" }, // Try the "Save" button
|
||||
{ name: "Launch scan" }, // Try the "Launch scan" button
|
||||
{ name: /Continue|Proceed/i }, // Try "Continue" or "Proceed" (case-insensitive)
|
||||
] as const;
|
||||
|
||||
for (const candidate of candidates) {
|
||||
// Try each candidate name and click it if found
|
||||
const btn = this.page.getByRole("button", {
|
||||
name: candidate.name as any,
|
||||
});
|
||||
if (await btn.count()) {
|
||||
await btn.click();
|
||||
await this.waitForPageLoad();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// If none of the expected action buttons are present, throw an error
|
||||
throw new Error(
|
||||
"Could not find an actionable Next/Save/Launch scan button on this step",
|
||||
);
|
||||
}
|
||||
|
||||
async selectCredentialsType(type: "role" | "credentials"): Promise<void> {
|
||||
// Ensure we are on the add-credentials page where the selector exists
|
||||
await expect(this.page).toHaveURL(/\/providers\/add-credentials/);
|
||||
if (type === "role") {
|
||||
await this.roleCredentialsRadio.click({ force: true });
|
||||
} else {
|
||||
await this.staticCredentialsRadio.click({ force: true });
|
||||
}
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async fillRoleCredentials(credentials: ProviderCredentials): Promise<void> {
|
||||
// Fill the role credentials form
|
||||
if (credentials.accessKeyId) {
|
||||
await this.accessKeyIdInput.fill(credentials.accessKeyId);
|
||||
}
|
||||
if (credentials.secretAccessKey) {
|
||||
await this.secretAccessKeyInput.fill(credentials.secretAccessKey);
|
||||
}
|
||||
if (credentials.roleArn) {
|
||||
await this.roleArnInput.fill(credentials.roleArn);
|
||||
}
|
||||
if (credentials.externalId) {
|
||||
// External ID may be prefilled and disabled; only fill if enabled
|
||||
if (await this.externalIdInput.isEnabled()) {
|
||||
await this.externalIdInput.fill(credentials.externalId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fillStaticCredentials(credentials: ProviderCredentials): Promise<void> {
|
||||
// Fill the static credentials form
|
||||
if (credentials.accessKeyId) {
|
||||
await this.accessKeyIdInput.fill(credentials.accessKeyId);
|
||||
}
|
||||
if (credentials.secretAccessKey) {
|
||||
await this.secretAccessKeyInput.fill(credentials.secretAccessKey);
|
||||
}
|
||||
}
|
||||
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
// Verify the providers page is loaded
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.addProviderButton).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyConnectAccountPageLoaded(): Promise<void> {
|
||||
// Verify the connect account page is loaded
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.awsProviderRadio).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyCredentialsPageLoaded(): Promise<void> {
|
||||
// Verify the credentials page is loaded
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.roleCredentialsRadio).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyLaunchScanPageLoaded(): Promise<void> {
|
||||
// Verify the launch scan page is loaded
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.page).toHaveURL(/\/providers\/test-connection/);
|
||||
|
||||
// Verify the Launch scan button is visible
|
||||
const launchScanButton = this.page
|
||||
.locator("button")
|
||||
.filter({ hasText: "Launch scan" });
|
||||
await expect(launchScanButton).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyProviderExists(providerUID: string): Promise<boolean> {
|
||||
// Filter search by providerUID
|
||||
await this.filterProvidersByProviderUID(providerUID);
|
||||
// Verify if table has 1 row
|
||||
if (!(await this.verifySingleRowForProviderUID(providerUID))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async verifyLoadProviderPageAfterNewProvider(): Promise<void> {
|
||||
// Verify the provider page is loaded
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.providersTable).toBeVisible();
|
||||
}
|
||||
|
||||
async verifySingleRowForProviderUID(providerUID: string): Promise<boolean> {
|
||||
// Verify if table has 1 row and that row contains providerUID
|
||||
await expect(this.providersTable).toBeVisible();
|
||||
const matchingRows = this.providersTable.locator("tbody tr", {
|
||||
hasText: providerUID,
|
||||
});
|
||||
const count = await matchingRows.count();
|
||||
if (count !== 1) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
async filterProvidersByProviderUID(providerUID: string): Promise<void> {
|
||||
// Filter providers by providerUID
|
||||
await this.goto();
|
||||
await expect(this.providersTable).toBeVisible();
|
||||
|
||||
const searchInput = this.page.getByPlaceholder(/search|filter/i);
|
||||
if (!searchInput) {
|
||||
throw new Error("No search input available");
|
||||
}
|
||||
|
||||
// Clear existing content and type the providerUID
|
||||
await searchInput.fill("");
|
||||
await searchInput.type(providerUID, { delay: 20 });
|
||||
|
||||
// Try to submit the filter if the input acts on Enter
|
||||
try {
|
||||
await searchInput.press("Enter");
|
||||
} catch (error) {
|
||||
// Enter press might not be needed for all UIs
|
||||
}
|
||||
|
||||
// Wait for table to update
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async actionDeleteProvider(providerUID: string): Promise<void> {
|
||||
// Delete the provider
|
||||
// Filter search by providerUID
|
||||
await this.filterProvidersByProviderUID(providerUID);
|
||||
|
||||
await expect(this.providersTable).toBeVisible();
|
||||
|
||||
// Find the first row in the filtered results
|
||||
const firstRow = this.providersTable.locator("tbody tr").first();
|
||||
await expect(firstRow).toBeVisible();
|
||||
|
||||
const lastCell = firstRow.locator("td").last();
|
||||
const actionButton = lastCell.locator("button").first();
|
||||
await actionButton.click();
|
||||
|
||||
// Wait for the dropdown menu to appear
|
||||
await this.page.waitForSelector('[role="menu"], [role="menuitem"]', {
|
||||
timeout: 5000,
|
||||
});
|
||||
|
||||
const deleteMenuItem = this.page.getByRole("menuitem", {
|
||||
name: /delete.*provider/i,
|
||||
});
|
||||
await expect(deleteMenuItem).toBeVisible();
|
||||
|
||||
// Click the delete menu item with force to handle unstable elements
|
||||
await deleteMenuItem.click({ force: true });
|
||||
|
||||
// Wait for the delete confirmation modal to appear
|
||||
await this.page.waitForSelector(
|
||||
'[role="dialog"], .modal, [data-testid*="modal"]',
|
||||
{ timeout: 10000 },
|
||||
);
|
||||
|
||||
// Find the delete confirmation button with multiple approaches
|
||||
let deleteButton = this.deleteProviderConfirmationButton;
|
||||
|
||||
await expect(deleteButton).toBeVisible();
|
||||
|
||||
// Click the delete button with force to handle unstable elements
|
||||
await deleteButton.click({ force: true });
|
||||
|
||||
// Wait for the modal to disappear and the page to update
|
||||
const modalToCheck = this.page
|
||||
.locator('[role="dialog"], .modal, [data-testid*="modal"]')
|
||||
.first();
|
||||
await expect(modalToCheck).not.toBeVisible();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
### E2E Tests: AWS Provider Management
|
||||
|
||||
**Suite ID:** `PROVIDER-E2E`
|
||||
**Feature:** AWS Provider Management - Add and configure AWS cloud providers with different authentication methods
|
||||
|
||||
---
|
||||
|
||||
## Test Case: `PROVIDER-E2E-001` - Add AWS Provider with Static Credentials
|
||||
|
||||
**Priority:** `critical`
|
||||
|
||||
**Tags:**
|
||||
|
||||
- type → @e2e, @serial
|
||||
- feature → @providers
|
||||
- provider → @aws
|
||||
|
||||
**Description/Objective:** Validates the complete flow of adding a new AWS provider using static access key credentials
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
- Admin user authentication required (admin.auth.setup setup)
|
||||
- Environment variables configured: E2E_AWS_PROVIDER_ACCOUNT_ID, E2E_AWS_PROVIDER_ACCESS_KEY and E2E_AWS_PROVIDER_SECRET_KEY
|
||||
- Remove any existing 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 not to be already registered beforehand.
|
||||
|
||||
### Flow Steps:
|
||||
|
||||
1. Navigate to providers page
|
||||
2. Click "Add Provider" button
|
||||
3. Select AWS provider type
|
||||
4. Fill provider details (account ID and alias)
|
||||
5. Select "credentials" authentication type
|
||||
6. Fill static credentials (access key and secret key)
|
||||
7. Launch initial scan
|
||||
8. Verify redirect to provider management page
|
||||
|
||||
### Expected Result:
|
||||
|
||||
- AWS provider successfully added with static credentials
|
||||
- Initial scan launched successfully
|
||||
- User redirected to provider details page
|
||||
|
||||
### Key verification points:
|
||||
|
||||
- Provider page loads correctly
|
||||
- Connect account page displays AWS option
|
||||
- Credentials form accepts static credentials
|
||||
- Launch scan page appears
|
||||
- Successful redirect to provider page after scan launch
|
||||
|
||||
### Notes:
|
||||
|
||||
- Test uses environment variables for AWS credentials
|
||||
- Provider cleanup performed before each test to ensure clean state
|
||||
- Requires valid AWS account with appropriate permissions
|
||||
|
||||
---
|
||||
|
||||
## Test Case: `PROVIDER-E2E-002` - Add AWS Provider with Assume Role Credentials Access Key and Secret Key
|
||||
|
||||
**Priority:** `critical`
|
||||
|
||||
**Tags:**
|
||||
|
||||
- type → @e2e, @serial
|
||||
- feature → @providers
|
||||
- provider → @aws
|
||||
|
||||
**Description/Objective:** Validates the complete flow of adding a new AWS provider using role-based authentication with Access Key and Secret Key
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
- Admin user authentication required (admin.auth.setup setup)
|
||||
- Environment variables configured: E2E_AWS_PROVIDER_ACCOUNT_ID, E2E_AWS_PROVIDER_ACCESS_KEY, E2E_AWS_PROVIDER_SECRET_KEY, E2E_AWS_PROVIDER_ROLE_ARN
|
||||
- Remove any existing 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 not to be already registered beforehand.
|
||||
|
||||
### Flow Steps:
|
||||
|
||||
1. Navigate to providers page
|
||||
2. Click "Add Provider" button
|
||||
3. Select AWS provider type
|
||||
4. Fill provider details (account ID and alias)
|
||||
5. Select "role" authentication type
|
||||
6. Fill role credentials (access key, secret key, and role ARN)
|
||||
7. Launch initial scan
|
||||
8. Verify redirect to provider management page
|
||||
|
||||
### Expected Result:
|
||||
|
||||
- AWS provider successfully added with role credentials
|
||||
- Initial scan launched successfully
|
||||
- User redirected to provider details page
|
||||
|
||||
### Key verification points:
|
||||
|
||||
- Provider page loads correctly
|
||||
- Connect account page displays AWS option
|
||||
- Role credentials form accepts all required fields
|
||||
- Launch scan page appears
|
||||
- Successful redirect to provider page after scan launch
|
||||
|
||||
### Notes:
|
||||
|
||||
- Test uses environment variables for AWS credentials and role ARN
|
||||
- Provider cleanup performed before each test to ensure clean state
|
||||
- Requires valid AWS account with role assumption permissions
|
||||
- Role ARN must be properly configured
|
||||
@@ -0,0 +1,156 @@
|
||||
import { test } from "@playwright/test";
|
||||
import * as helpers from "../helpers";
|
||||
import {
|
||||
ProvidersPage,
|
||||
AWSProviderData,
|
||||
ProviderCredentials,
|
||||
} from "./providers-page";
|
||||
|
||||
|
||||
|
||||
|
||||
// Configure serial execution for provider tests
|
||||
test.describe.serial("Add AWS Provider", () => {
|
||||
let providersPage: ProvidersPage;
|
||||
|
||||
// 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;
|
||||
const roleArn = process.env.E2E_AWS_PROVIDER_ROLE_ARN;
|
||||
|
||||
// Validate required environment variables
|
||||
if (!accountId) {
|
||||
throw new Error(
|
||||
"E2E_AWS_PROVIDER_ACCOUNT_ID environment variable is not set",
|
||||
);
|
||||
}
|
||||
|
||||
// Setup before each test
|
||||
test.beforeEach(async ({ page }) => {
|
||||
providersPage = new ProvidersPage(page);
|
||||
// Clean up existing provider to ensure clean test state
|
||||
await helpers.deleteProviderIfExists(page, accountId);
|
||||
});
|
||||
|
||||
// Use admin authentication for provider management
|
||||
test.use({ storageState: "playwright/.auth/admin_user.json" });
|
||||
|
||||
|
||||
test(
|
||||
"should add a new AWS provider with static credentials",
|
||||
{
|
||||
tag: ["@critical", "@e2e", "@providers", "@aws", "@serial", "@PROVIDER-E2E-001"],
|
||||
},
|
||||
async ({ page }) => {
|
||||
// Validate required environment variables
|
||||
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",
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare test data for AWS provider
|
||||
const awsProviderData: AWSProviderData = {
|
||||
accountId: accountId,
|
||||
alias: "Test E2E AWS Account - Credentials",
|
||||
};
|
||||
|
||||
// Prepare static credentials
|
||||
const staticCredentials: ProviderCredentials = {
|
||||
type: "credentials",
|
||||
accessKeyId: accessKey,
|
||||
secretAccessKey: secretKey,
|
||||
};
|
||||
|
||||
// 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("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
|
||||
await providersPage.verifyLoadProviderPageAfterNewProvider();
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
"should add a new AWS provider with assume role credentials with Access Key and Secret Key",
|
||||
{
|
||||
tag: ["@critical", "@e2e", "@providers", "@aws","@serial", "@PROVIDER-E2E-002"],
|
||||
},
|
||||
async ({ page }) => {
|
||||
// Validate required environment variables
|
||||
if (!accountId || !accessKey || !secretKey || !roleArn) {
|
||||
throw new Error(
|
||||
"E2E_AWS_PROVIDER_ACCOUNT_ID, E2E_AWS_PROVIDER_ACCESS_KEY, E2E_AWS_PROVIDER_SECRET_KEY, and E2E_AWS_PROVIDER_ROLE_ARN environment variables are not set",
|
||||
);
|
||||
}
|
||||
|
||||
// Prepare test data for AWS provider
|
||||
const awsProviderData: AWSProviderData = {
|
||||
accountId: accountId,
|
||||
alias: "Test E2E AWS Account - Credentials",
|
||||
};
|
||||
|
||||
// Prepare role-based credentials
|
||||
const roleCredentials: ProviderCredentials = {
|
||||
type: "role",
|
||||
accessKeyId: accessKey,
|
||||
secretAccessKey: secretKey,
|
||||
roleArn: roleArn,
|
||||
};
|
||||
|
||||
// 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 role credentials type
|
||||
await providersPage.selectCredentialsType("role");
|
||||
await providersPage.verifyCredentialsPageLoaded();
|
||||
|
||||
// Fill role credentials
|
||||
await providersPage.fillRoleCredentials(roleCredentials);
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Launch scan
|
||||
await providersPage.verifyLaunchScanPageLoaded();
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Wait for redirect to provider page
|
||||
await providersPage.verifyLoadProviderPageAfterNewProvider();
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user