Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ui-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ jobs:
E2E_OCI_KEY_CONTENT: ${{ secrets.E2E_OCI_KEY_CONTENT }}
E2E_OCI_REGION: ${{ secrets.E2E_OCI_REGION }}
E2E_NEW_USER_PASSWORD: ${{ secrets.E2E_NEW_USER_PASSWORD }}
E2E_ALIBABACLOUD_ACCOUNT_ID: ${{ secrets.E2E_ALIBABACLOUD_ACCOUNT_ID }}
E2E_ALIBABACLOUD_ACCESS_KEY_ID: ${{ secrets.E2E_ALIBABACLOUD_ACCESS_KEY_ID }}
E2E_ALIBABACLOUD_ACCESS_KEY_SECRET: ${{ secrets.E2E_ALIBABACLOUD_ACCESS_KEY_SECRET }}
E2E_ALIBABACLOUD_ROLE_ARN: ${{ secrets.E2E_ALIBABACLOUD_ROLE_ARN }}

steps:
- name: Checkout repository
Expand Down
3 changes: 2 additions & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,5 +154,6 @@
"@react-aria/interactions>react": "19.2.2"
}
},
"version": "0.0.1"
"version": "0.0.1",
"packageManager": "pnpm@10.24.0+sha512.01ff8ae71b4419903b65c60fb2dc9d34cf8bb6e06d03bde112ef38f7a34d6904c424ba66bea5cdcf12890230bf39f9580473140ed9c946fef328b6e5238a345a"
}
159 changes: 159 additions & 0 deletions ui/tests/providers/providers-page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export interface OCIProviderData {
alias?: string;
}

// AlibabaCloud provider data
export interface AlibabaCloudProviderData {
accountId: string;
alias?: string;
}

// AWS credential options
export const AWS_CREDENTIAL_OPTIONS = {
AWS_ROLE_ARN: "role",
Expand Down Expand Up @@ -167,6 +173,25 @@ export interface OCIProviderCredential {
region?: string;
}

// AlibabaCloud credential options
export const ALIBABACLOUD_CREDENTIAL_OPTIONS = {
ALIBABACLOUD_CREDENTIALS: "credentials",
ALIBABACLOUD_ROLE: "role",
} as const;

// AlibabaCloud credential type
type AlibabaCloudCredentialType =
(typeof ALIBABACLOUD_CREDENTIAL_OPTIONS)[keyof typeof ALIBABACLOUD_CREDENTIAL_OPTIONS];

// AlibabaCloud provider credential
export interface AlibabaCloudProviderCredential {
type: AlibabaCloudCredentialType;
accessKeyId: string;
accessKeySecret: string;
roleArn?: string;
roleSessionName?: string;
}

// Providers page
export class ProvidersPage extends BasePage {
// Alias input
Expand All @@ -184,6 +209,7 @@ export class ProvidersPage extends BasePage {
readonly kubernetesProviderRadio: Locator;
readonly githubProviderRadio: Locator;
readonly ociProviderRadio: Locator;
readonly alibabacloudProviderRadio: Locator;

// AWS provider form elements
readonly accountIdInput: Locator;
Expand Down Expand Up @@ -247,6 +273,15 @@ export class ProvidersPage extends BasePage {
readonly ociKeyContentInput: Locator;
readonly ociRegionInput: Locator;

// AlibabaCloud provider form elements
readonly alibabacloudAccountIdInput: Locator;
readonly alibabacloudAccessKeyIdInput: Locator;
readonly alibabacloudAccessKeySecretInput: Locator;
readonly alibabacloudRoleArnInput: Locator;
readonly alibabacloudRoleSessionNameInput: Locator;
readonly alibabacloudStaticCredentialsRadio: Locator;
readonly alibabacloudRoleCredentialsRadio: Locator;

// Delete button
readonly deleteProviderConfirmationButton: Locator;

Expand Down Expand Up @@ -290,6 +325,10 @@ export class ProvidersPage extends BasePage {
this.ociProviderRadio = page.getByRole("option", {
name: /Oracle Cloud Infrastructure/i,
});
// Alibaba Cloud
this.alibabacloudProviderRadio = page.getByRole("option", {
name: /Alibaba Cloud/i,
});

// AWS provider form inputs
this.accountIdInput = page.getByRole("textbox", { name: "Account ID" });
Expand Down Expand Up @@ -354,6 +393,30 @@ export class ProvidersPage extends BasePage {
});
this.ociRegionInput = page.getByRole("textbox", { name: /Region/i });

// AlibabaCloud provider form inputs
this.alibabacloudAccountIdInput = page.getByRole("textbox", {
name: "Account ID",
});
this.alibabacloudAccessKeyIdInput = page.getByRole("textbox", {
name: "Access Key ID",
});
this.alibabacloudAccessKeySecretInput = page.getByRole("textbox", {
name: "Access Key Secret",
});
this.alibabacloudRoleArnInput = page.getByRole("textbox", {
name: "Role ARN",
});
this.alibabacloudRoleSessionNameInput = page.getByRole("textbox", {
name: "Role Session Name",
});
// Radios for selecting AlibabaCloud credentials method
this.alibabacloudStaticCredentialsRadio = page.getByRole("radio", {
name: /Connect via Access Keys/i,
});
this.alibabacloudRoleCredentialsRadio = page.getByRole("radio", {
name: /Connect assuming RAM Role/i,
});

// Alias input
this.aliasInput = page.getByRole("textbox", {
name: "Provider alias (optional)",
Expand Down Expand Up @@ -857,6 +920,101 @@ export class ProvidersPage extends BasePage {
await expect(this.ociRegionInput).toBeVisible();
}

async selectAlibabaCloudProvider(): Promise<void> {
await this.selectProviderRadio(this.alibabacloudProviderRadio);
}

async fillAlibabaCloudProviderDetails(
data: AlibabaCloudProviderData,
): Promise<void> {
// Fill the AlibabaCloud provider details

await this.alibabacloudAccountIdInput.fill(data.accountId);

if (data.alias) {
await this.aliasInput.fill(data.alias);
}
}

async selectAlibabaCloudCredentialsType(
type: AlibabaCloudCredentialType,
): Promise<void> {
// Ensure we are on the add-credentials page where the selector exists

await expect(this.page).toHaveURL(/\/providers\/add-credentials/);

if (type === ALIBABACLOUD_CREDENTIAL_OPTIONS.ALIBABACLOUD_CREDENTIALS) {
await this.alibabacloudStaticCredentialsRadio.click({ force: true });
} else if (type === ALIBABACLOUD_CREDENTIAL_OPTIONS.ALIBABACLOUD_ROLE) {
await this.alibabacloudRoleCredentialsRadio.click({ force: true });
} else {
throw new Error(`Invalid AlibabaCloud credential type: ${type}`);
}
}

async fillAlibabaCloudStaticCredentials(
credentials: AlibabaCloudProviderCredential,
): Promise<void> {
// Fill the AlibabaCloud static credentials form

if (credentials.accessKeyId) {
await this.alibabacloudAccessKeyIdInput.fill(credentials.accessKeyId);
}
if (credentials.accessKeySecret) {
await this.alibabacloudAccessKeySecretInput.fill(
credentials.accessKeySecret,
);
}
}

async fillAlibabaCloudRoleCredentials(
credentials: AlibabaCloudProviderCredential,
): Promise<void> {
// Fill the AlibabaCloud RAM Role credentials form

if (credentials.roleArn) {
await this.alibabacloudRoleArnInput.fill(credentials.roleArn);
}
if (credentials.accessKeyId) {
await this.alibabacloudAccessKeyIdInput.fill(credentials.accessKeyId);
}
if (credentials.accessKeySecret) {
await this.alibabacloudAccessKeySecretInput.fill(
credentials.accessKeySecret,
);
}
if (credentials.roleSessionName) {
await this.alibabacloudRoleSessionNameInput.fill(
credentials.roleSessionName,
);
}
}

async verifyAlibabaCloudCredentialsPageLoaded(): Promise<void> {
// Verify the AlibabaCloud credentials page is loaded

await this.verifyPageHasProwlerTitle();
await expect(this.alibabacloudStaticCredentialsRadio).toBeVisible();
await expect(this.alibabacloudRoleCredentialsRadio).toBeVisible();
}

async verifyAlibabaCloudStaticCredentialsPageLoaded(): Promise<void> {
// Verify the AlibabaCloud static credentials page is loaded

await this.verifyPageHasProwlerTitle();
await expect(this.alibabacloudAccessKeyIdInput).toBeVisible();
await expect(this.alibabacloudAccessKeySecretInput).toBeVisible();
}

async verifyAlibabaCloudRoleCredentialsPageLoaded(): Promise<void> {
// Verify the AlibabaCloud RAM Role credentials page is loaded

await this.verifyPageHasProwlerTitle();
await expect(this.alibabacloudRoleArnInput).toBeVisible();
await expect(this.alibabacloudAccessKeyIdInput).toBeVisible();
await expect(this.alibabacloudAccessKeySecretInput).toBeVisible();
}

async verifyPageLoaded(): Promise<void> {
// Verify the providers page is loaded

Expand All @@ -875,6 +1033,7 @@ export class ProvidersPage extends BasePage {
await expect(this.m365ProviderRadio).toBeVisible();
await expect(this.kubernetesProviderRadio).toBeVisible();
await expect(this.githubProviderRadio).toBeVisible();
await expect(this.alibabacloudProviderRadio).toBeVisible();
}

async verifyCredentialsPageLoaded(): Promise<void> {
Expand Down
125 changes: 125 additions & 0 deletions ui/tests/providers/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -708,3 +708,128 @@
- Provider cleanup performed before each test to ensure clean state
- Requires valid OCI account with API Key set up
- API Key credential type is automatically used for OCI providers

---

## Test Case: `PROVIDER-E2E-013` - Add AlibabaCloud Provider with Static Credentials

**Priority:** `critical`

**Tags:**

- type → @e2e, @serial
- feature → @providers
- provider → @alibabacloud

**Description/Objective:** Validates the complete flow of adding a new Alibaba Cloud provider using static credentials (Access Key ID and Access Key Secret)

**Preconditions:**

- Admin user authentication required (admin.auth.setup setup)
- Environment variables configured: E2E_ALIBABACLOUD_ACCOUNT_ID, E2E_ALIBABACLOUD_ACCESS_KEY_ID, E2E_ALIBABACLOUD_ACCESS_KEY_SECRET
- 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 AlibabaCloud provider type
4. Fill provider details (account ID and alias)
5. Verify AlibabaCloud credentials page is loaded
6. Select static credentials type
7. Verify static credentials page is loaded
8. Fill AlibabaCloud credentials (access key ID and access key secret)
9. Launch initial scan
10. Verify redirect to Scans page
11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")

### Expected Result:

- AlibabaCloud provider successfully added with static credentials
- Initial scan launched successfully
- User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name

### Key verification points:

- Provider page loads correctly
- Connect account page displays AlibabaCloud option
- Provider details form accepts account ID and alias
- Credentials page loads with credential type selection
- Static credentials page loads with access key ID and access key secret fields
- Static credentials are properly filled in the correct fields
- Launch scan page appears
- Successful redirect to Scans page after scan launch
- Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan"

### Notes:

- Test uses environment variables for AlibabaCloud credentials
- Provider cleanup performed before each test to ensure clean state
- Requires valid Alibaba Cloud account with appropriate permissions
- Static credentials must have sufficient permissions for security scanning

---

## Test Case: `PROVIDER-E2E-014` - Add AlibabaCloud Provider with RAM Role Credentials

**Priority:** `critical`

**Tags:**

- type → @e2e, @serial
- feature → @providers
- provider → @alibabacloud

**Description/Objective:** Validates the complete flow of adding a new Alibaba Cloud provider using RAM Role credentials (Access Key ID, Access Key Secret, and Role ARN)

**Preconditions:**

- Admin user authentication required (admin.auth.setup setup)
- Environment variables configured: E2E_ALIBABACLOUD_ACCOUNT_ID, E2E_ALIBABACLOUD_ACCESS_KEY_ID, E2E_ALIBABACLOUD_ACCESS_KEY_SECRET, E2E_ALIBABACLOUD_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 AlibabaCloud provider type
4. Fill provider details (account ID and alias)
5. Verify AlibabaCloud credentials page is loaded
6. Select RAM Role credentials type
7. Verify RAM Role credentials page is loaded
8. Fill AlibabaCloud RAM Role credentials (access key ID, access key secret, and role ARN)
9. Launch initial scan
10. Verify redirect to Scans page
11. Verify scheduled scan status in Scans table (provider exists and scan name is "scheduled scan")

### Expected Result:

- AlibabaCloud provider successfully added with RAM Role credentials
- Initial scan launched successfully
- User redirected to Scans page
- Scheduled scan appears in Scans table with correct provider and scan name

### Key verification points:

- Provider page loads correctly
- Connect account page displays AlibabaCloud option
- Provider details form accepts account ID and alias
- Credentials page loads with credential type selection
- RAM Role credentials page loads with access key ID, access key secret, and role ARN fields
- RAM Role credentials are properly filled in the correct fields
- Launch scan page appears
- Successful redirect to Scans page after scan launch
- Provider exists in Scans table (verified by account ID)
- Scan name field contains "scheduled scan"

### Notes:

- Test uses environment variables for AlibabaCloud RAM Role credentials
- Provider cleanup performed before each test to ensure clean state
- Requires valid Alibaba Cloud account with RAM Role configured
- RAM Role must have sufficient permissions for security scanning
- Role ARN must be properly configured and assumable
Loading
Loading