mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 04:21:52 +00:00
test(ui): add M365 provider management E2E tests
- Introduced new E2E tests for adding Microsoft 365 providers with static credentials. - Updated the ProvidersPage interface to include M365-specific fields and methods. - Enhanced the test suite to validate the complete flow of adding a new M365 provider, ensuring proper handling of credentials and provider details. - Added necessary environment variable checks and cleanup steps to maintain test integrity.
This commit is contained in:
@@ -28,6 +28,10 @@ jobs:
|
||||
E2E_AZURE_CLIENT_ID: ${{ secrets.E2E_AZURE_CLIENT_ID }}
|
||||
E2E_AZURE_SECRET_ID: ${{ secrets.E2E_AZURE_SECRET_ID }}
|
||||
E2E_AZURE_TENANT_ID: ${{ secrets.E2E_AZURE_TENANT_ID }}
|
||||
E2E_M365_DOMAIN_ID: ${{ secrets.E2E_M365_DOMAIN_ID }}
|
||||
E2E_M365_CLIENT_ID: ${{ secrets.E2E_M365_CLIENT_ID }}
|
||||
E2E_M365_SECRET_ID: ${{ secrets.E2E_M365_SECRET_ID }}
|
||||
E2E_M365_TENANT_ID: ${{ secrets.E2E_M365_TENANT_ID }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
||||
@@ -13,6 +13,12 @@ export interface AZUREProviderData {
|
||||
alias?: string;
|
||||
}
|
||||
|
||||
// M365 provider data
|
||||
export interface M365ProviderData {
|
||||
domainId: string;
|
||||
alias?: string;
|
||||
}
|
||||
|
||||
// AWS credential options
|
||||
export const AWS_CREDENTIAL_OPTIONS = {
|
||||
AWS_ROLE_ARN: "role",
|
||||
@@ -47,6 +53,22 @@ export interface AZUREProviderCredential {
|
||||
tenantId:string;
|
||||
}
|
||||
|
||||
// M365 credential options
|
||||
export const M365_CREDENTIAL_OPTIONS = {
|
||||
M365_CREDENTIALS: "credentials"
|
||||
} as const;
|
||||
|
||||
// M365 credential type
|
||||
type M365CredentialType = (typeof M365_CREDENTIAL_OPTIONS)[keyof typeof M365_CREDENTIAL_OPTIONS];
|
||||
|
||||
// M365 provider credential
|
||||
export interface M365ProviderCredential {
|
||||
type: M365CredentialType;
|
||||
clientId:string;
|
||||
clientSecret:string;
|
||||
tenantId:string;
|
||||
}
|
||||
|
||||
|
||||
// Providers page
|
||||
export class ProvidersPage extends BasePage {
|
||||
@@ -84,10 +106,16 @@ export class ProvidersPage extends BasePage {
|
||||
readonly secretAccessKeyInput: Locator;
|
||||
|
||||
// AZURE provider form elements
|
||||
readonly subscriptionIdInput: Locator;
|
||||
readonly clientIdInput: Locator;
|
||||
readonly clientSecretInput: Locator;
|
||||
readonly tenantIdInput: Locator;
|
||||
readonly azureSubscriptionIdInput: Locator;
|
||||
readonly azureClientIdInput: Locator;
|
||||
readonly azureClientSecretInput: Locator;
|
||||
readonly azureTenantIdInput: Locator;
|
||||
|
||||
// M365 provider form elements
|
||||
readonly m365domainIdInput: Locator;
|
||||
readonly m365ClientIdInput: Locator;
|
||||
readonly m365ClientSecretInput: Locator;
|
||||
readonly m365TenantIdInput: Locator;
|
||||
|
||||
// Delete button
|
||||
readonly deleteProviderConfirmationButton: Locator;
|
||||
@@ -125,10 +153,16 @@ export class ProvidersPage extends BasePage {
|
||||
this.accountIdInput = page.getByLabel("Account ID");
|
||||
|
||||
// AZURE provider form inputs
|
||||
this.subscriptionIdInput = page.getByLabel("Subscription ID");
|
||||
this.clientIdInput = page.getByLabel("Client ID");
|
||||
this.clientSecretInput = page.getByLabel("Client Secret");
|
||||
this.tenantIdInput = page.getByLabel("Tenant ID");
|
||||
this.azureSubscriptionIdInput = page.getByLabel("Subscription ID");
|
||||
this.azureClientIdInput = page.getByLabel("Client ID");
|
||||
this.azureClientSecretInput = page.getByLabel("Client Secret");
|
||||
this.azureTenantIdInput = page.getByLabel("Tenant ID");
|
||||
|
||||
// M365 provider form inputs
|
||||
this.m365domainIdInput = page.getByLabel("Domain ID");
|
||||
this.m365ClientIdInput = page.getByLabel("Client ID");
|
||||
this.m365ClientSecretInput = page.getByLabel("Client Secret");
|
||||
this.m365TenantIdInput = page.getByLabel("Tenant ID");
|
||||
|
||||
// Alias input
|
||||
this.aliasInput = page.getByLabel("Provider alias (optional)");
|
||||
@@ -197,6 +231,12 @@ export class ProvidersPage extends BasePage {
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async selectM365Provider(): Promise<void> {
|
||||
// Select the M365 provider
|
||||
|
||||
await this.m365ProviderRadio.click({ force: true });
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async fillAWSProviderDetails(data: AWSProviderData): Promise<void> {
|
||||
// Fill the AWS provider details
|
||||
@@ -211,7 +251,17 @@ export class ProvidersPage extends BasePage {
|
||||
async fillAZUREProviderDetails(data: AZUREProviderData): Promise<void> {
|
||||
// Fill the AWS provider details
|
||||
|
||||
await this.subscriptionIdInput.fill(data.subscriptionId);
|
||||
await this.azureSubscriptionIdInput.fill(data.subscriptionId);
|
||||
|
||||
if (data.alias) {
|
||||
await this.aliasInput.fill(data.alias);
|
||||
}
|
||||
}
|
||||
|
||||
async fillM365ProviderDetails(data: M365ProviderData): Promise<void> {
|
||||
// Fill the M365 provider details
|
||||
|
||||
await this.m365domainIdInput.fill(data.domainId);
|
||||
|
||||
if (data.alias) {
|
||||
await this.aliasInput.fill(data.alias);
|
||||
@@ -338,16 +388,29 @@ export class ProvidersPage extends BasePage {
|
||||
// Fill the azure credentials form
|
||||
|
||||
if (credentials.clientId) {
|
||||
await this.clientIdInput.fill(credentials.clientId);
|
||||
await this.azureClientIdInput.fill(credentials.clientId);
|
||||
}
|
||||
if (credentials.clientSecret) {
|
||||
await this.clientSecretInput.fill(credentials.clientSecret);
|
||||
await this.azureClientSecretInput.fill(credentials.clientSecret);
|
||||
}
|
||||
if (credentials.tenantId) {
|
||||
await this.tenantIdInput.fill(credentials.tenantId);
|
||||
await this.azureTenantIdInput.fill(credentials.tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
async fillM365Credentials(credentials: M365ProviderCredential): Promise<void> {
|
||||
// Fill the m365 credentials form
|
||||
|
||||
if (credentials.clientId) {
|
||||
await this.m365ClientIdInput.fill(credentials.clientId);
|
||||
}
|
||||
if (credentials.clientSecret) {
|
||||
await this.m365ClientSecretInput.fill(credentials.clientSecret);
|
||||
}
|
||||
if (credentials.tenantId) {
|
||||
await this.m365TenantIdInput.fill(credentials.tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
// Verify the providers page is loaded
|
||||
|
||||
@@ -159,3 +159,55 @@
|
||||
- Provider cleanup performed before each test to ensure clean state
|
||||
- Requires valid Azure subscription with appropriate permissions
|
||||
- Client credentials must have sufficient permissions for security scanning
|
||||
|
||||
---
|
||||
|
||||
## Test Case: `PROVIDER-E2E-004` - Add M365 Provider with Static Credentials
|
||||
|
||||
**Priority:** `critical`
|
||||
|
||||
**Tags:**
|
||||
|
||||
- type → @e2e, @serial
|
||||
- feature → @providers
|
||||
- provider → @m365
|
||||
|
||||
**Description/Objective:** Validates the complete flow of adding a new Microsoft 365 provider using static client credentials (Client ID, Client Secret, Tenant ID) tied to a Domain ID.
|
||||
|
||||
**Preconditions:**
|
||||
|
||||
- Admin user authentication required (admin.auth.setup setup)
|
||||
- Environment variables configured: E2E_M365_DOMAIN_ID, E2E_M365_CLIENT_ID, E2E_M365_SECRET_ID, E2E_M365_TENANT_ID
|
||||
- Remove any existing provider with the same Domain ID before starting the test
|
||||
- This test must be run serially and never in parallel with other tests, as it requires the Domain ID not to be already registered beforehand.
|
||||
|
||||
### Flow Steps:
|
||||
|
||||
1. Navigate to providers page
|
||||
2. Click "Add Provider" button
|
||||
3. Select M365 provider type
|
||||
4. Fill provider details (domain ID and alias)
|
||||
5. Fill M365 credentials (client ID, client secret, tenant ID)
|
||||
6. Launch initial scan
|
||||
7. Verify redirect to provider management page
|
||||
|
||||
### Expected Result:
|
||||
|
||||
- M365 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 M365 option
|
||||
- M365 credentials form accepts all required fields
|
||||
- Launch scan page appears
|
||||
- Successful redirect to provider page after scan launch
|
||||
|
||||
### Notes:
|
||||
|
||||
- Test uses environment variables for M365 credentials
|
||||
- Provider cleanup performed before each test to ensure clean state
|
||||
- Requires valid Microsoft 365 tenant with appropriate permissions
|
||||
- Client credentials must have sufficient permissions for security scanning
|
||||
|
||||
@@ -7,7 +7,10 @@ import {
|
||||
AWS_CREDENTIAL_OPTIONS,
|
||||
AZUREProviderData,
|
||||
AZUREProviderCredential,
|
||||
AZURE_CREDENTIAL_OPTIONS
|
||||
AZURE_CREDENTIAL_OPTIONS,
|
||||
M365ProviderData,
|
||||
M365ProviderCredential,
|
||||
M365_CREDENTIAL_OPTIONS
|
||||
} from "./providers-page";
|
||||
|
||||
|
||||
@@ -238,4 +241,87 @@ test.describe.serial("Add AZURE Provider", () => {
|
||||
await providersPage.verifyLoadProviderPageAfterNewProvider();
|
||||
}
|
||||
)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
test.describe.serial("Add M365 Provider", () => {
|
||||
|
||||
// Providers page object
|
||||
let providersPage: ProvidersPage;
|
||||
|
||||
// Test data from environment variables
|
||||
const domainId= process.env.E2E_M365_DOMAIN_ID;
|
||||
const clientId= process.env.E2E_M365_CLIENT_ID
|
||||
const clientSecret= process.env.E2E_M365_SECRET_ID
|
||||
const tenantId= process.env.E2E_M365_TENANT_ID
|
||||
|
||||
// Validate required environment variables
|
||||
if (!domainId || !clientId || !clientSecret || !tenantId) {
|
||||
throw new Error(
|
||||
"E2E_M365_DOMAIN_ID, E2E_M365_CLIENT_ID, E2E_M365_SECRET_ID, and E2E_M365_TENANT_ID environment variables are 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, domainId);
|
||||
});
|
||||
|
||||
// Use admin authentication for provider management
|
||||
test.use({ storageState: "playwright/.auth/admin_user.json" });
|
||||
|
||||
|
||||
test(
|
||||
"should add a new M365 provider with static credentials",
|
||||
{
|
||||
tag: ["@critical", "@e2e", "@providers", "@m365", "@serial", "@PROVIDER-E2E-004"],
|
||||
},
|
||||
async ({ page }) => {
|
||||
|
||||
// Prepare test data for M365 provider
|
||||
const m365ProviderData: M365ProviderData = {
|
||||
domainId:domainId,
|
||||
alias: "Test E2E M365 Account - Credentials",
|
||||
};
|
||||
|
||||
// Prepare static credentials
|
||||
const m365Credentials: M365ProviderCredential = {
|
||||
type: M365_CREDENTIAL_OPTIONS.M365_CREDENTIALS,
|
||||
clientId: clientId,
|
||||
clientSecret: clientSecret,
|
||||
tenantId: tenantId,
|
||||
};
|
||||
|
||||
// Navigate to providers page
|
||||
await providersPage.goto();
|
||||
await providersPage.verifyPageLoaded();
|
||||
|
||||
// Start adding new provider
|
||||
await providersPage.clickAddProvider();
|
||||
await providersPage.verifyConnectAccountPageLoaded();
|
||||
|
||||
// Select M365 provider
|
||||
await providersPage.selectM365Provider();
|
||||
|
||||
// Fill provider details
|
||||
await providersPage.fillM365ProviderDetails(m365ProviderData);
|
||||
await providersPage.clickNext();
|
||||
|
||||
// Fill static credentials details
|
||||
await providersPage.fillM365Credentials(m365Credentials);
|
||||
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