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:
StylusFrost
2025-10-20 14:53:43 +02:00
parent 0d088eca13
commit 13436613d6
4 changed files with 219 additions and 14 deletions
+4
View File
@@ -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
+75 -12
View File
@@ -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
+52
View File
@@ -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
+88 -2
View File
@@ -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();
}
)
});