mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-20 02:51:52 +00:00
Merge branch 'PROWLER-187-create-new-user' into PROWLER-179-aws-add-an-connect-the-provider
This commit is contained in:
@@ -24,6 +24,7 @@ jobs:
|
||||
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 }}
|
||||
E2E_NEW_PASSWORD: ${{ secrets.E2E_NEW_PASSWORD }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
|
||||
@@ -17,8 +17,8 @@ export abstract class BasePage {
|
||||
|
||||
// Common locators that most pages share
|
||||
this.title = page.locator("h1, h2, [role='heading']").first();
|
||||
this.loadingIndicator = page.getByText("Loading");
|
||||
this.themeToggle = page.getByLabel("Toggle theme");
|
||||
this.loadingIndicator = page.getByRole("status", { name: "Loading" });
|
||||
this.themeToggle = page.getByRole("button", { name: "Toggle theme" });
|
||||
}
|
||||
|
||||
// Common navigation methods
|
||||
|
||||
@@ -25,7 +25,7 @@ export class HomePage extends BasePage {
|
||||
|
||||
// Main content elements
|
||||
this.mainContent = page.locator("main");
|
||||
this.breadcrumbs = page.getByLabel("Breadcrumbs");
|
||||
this.breadcrumbs = page.getByRole("navigation", { name: "Breadcrumbs" });
|
||||
this.overviewHeading = page.getByRole("heading", { name: "Overview", exact: true });
|
||||
|
||||
// Navigation elements
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
import { Page, Locator, expect } from "@playwright/test";
|
||||
|
||||
export class HomePage {
|
||||
readonly page: Page;
|
||||
|
||||
// Main content elements
|
||||
readonly mainContent: Locator;
|
||||
readonly breadcrumbs: Locator;
|
||||
readonly overviewHeading: Locator;
|
||||
|
||||
// Navigation elements
|
||||
readonly navigationMenu: Locator;
|
||||
readonly userMenu: Locator;
|
||||
readonly signOutButton: Locator;
|
||||
|
||||
// Dashboard elements
|
||||
readonly dashboardCards: Locator;
|
||||
readonly overviewSection: Locator;
|
||||
|
||||
// UI elements
|
||||
readonly themeToggle: Locator;
|
||||
readonly logo: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
|
||||
// Main content elements
|
||||
this.mainContent = page.locator("main");
|
||||
this.breadcrumbs = page.getByLabel("Breadcrumbs");
|
||||
this.overviewHeading = page.getByRole("heading", { name: "Overview", exact: true });
|
||||
|
||||
// Navigation elements
|
||||
this.navigationMenu = page.locator("nav");
|
||||
this.userMenu = page.getByRole("button", { name: /user menu/i });
|
||||
this.signOutButton = page.getByRole("button", { name: "Sign out" });
|
||||
|
||||
// Dashboard elements
|
||||
this.dashboardCards = page.locator('[data-testid="dashboard-card"]');
|
||||
this.overviewSection = page.locator('[data-testid="overview-section"]');
|
||||
|
||||
// UI elements
|
||||
this.themeToggle = page.getByLabel("Toggle theme");
|
||||
this.logo = page.locator('svg[width="300"]');
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
async goto(): Promise<void> {
|
||||
await this.page.goto("/");
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async waitForPageLoad(): Promise<void> {
|
||||
await this.page.waitForLoadState("networkidle");
|
||||
}
|
||||
|
||||
// Verification methods
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
await expect(this.page).toHaveURL("/");
|
||||
await expect(this.mainContent).toBeVisible();
|
||||
await expect(this.overviewHeading).toBeVisible();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async verifyBreadcrumbs(): Promise<void> {
|
||||
await expect(this.breadcrumbs).toBeVisible();
|
||||
await expect(this.overviewHeading).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyMainContent(): Promise<void> {
|
||||
await expect(this.mainContent).toBeVisible();
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
async navigateToOverview(): Promise<void> {
|
||||
await this.overviewHeading.click();
|
||||
}
|
||||
|
||||
async openUserMenu(): Promise<void> {
|
||||
await this.userMenu.click();
|
||||
}
|
||||
|
||||
async signOut(): Promise<void> {
|
||||
await this.openUserMenu();
|
||||
await this.signOutButton.click();
|
||||
}
|
||||
|
||||
// Dashboard methods
|
||||
async verifyDashboardCards(): Promise<void> {
|
||||
await expect(this.dashboardCards.first()).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyOverviewSection(): Promise<void> {
|
||||
await expect(this.overviewSection).toBeVisible();
|
||||
}
|
||||
|
||||
// Utility methods
|
||||
async refresh(): Promise<void> {
|
||||
await this.page.reload();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async goBack(): Promise<void> {
|
||||
await this.page.goBack();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
// Accessibility methods
|
||||
async verifyKeyboardNavigation(): Promise<void> {
|
||||
// Test tab navigation through main elements
|
||||
await this.page.keyboard.press("Tab");
|
||||
await expect(this.themeToggle).toBeFocused();
|
||||
}
|
||||
|
||||
// Wait methods
|
||||
async waitForRedirect(expectedUrl: string): Promise<void> {
|
||||
await this.page.waitForURL(expectedUrl);
|
||||
}
|
||||
|
||||
async waitForContentLoad(): Promise<void> {
|
||||
await this.page.waitForFunction(() => {
|
||||
const main = document.querySelector("main");
|
||||
return main && main.offsetHeight > 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,316 +0,0 @@
|
||||
import { Page, Locator, expect } from "@playwright/test";
|
||||
import { HomePage } from "./home-page";
|
||||
|
||||
export interface SignInCredentials {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
export interface SocialAuthConfig {
|
||||
googleEnabled: boolean;
|
||||
githubEnabled: boolean;
|
||||
}
|
||||
|
||||
export class SignInPage {
|
||||
readonly page: Page;
|
||||
readonly homePage: HomePage;
|
||||
|
||||
// Form elements
|
||||
readonly emailInput: Locator;
|
||||
readonly passwordInput: Locator;
|
||||
readonly loginButton: Locator;
|
||||
readonly form: Locator;
|
||||
|
||||
// Social authentication buttons
|
||||
readonly googleButton: Locator;
|
||||
readonly githubButton: Locator;
|
||||
readonly samlButton: Locator;
|
||||
|
||||
// Navigation elements
|
||||
readonly signUpLink: Locator;
|
||||
readonly backButton: Locator;
|
||||
|
||||
// UI elements
|
||||
readonly title: Locator;
|
||||
readonly logo: Locator;
|
||||
readonly themeToggle: Locator;
|
||||
|
||||
// Error messages
|
||||
readonly errorMessages: Locator;
|
||||
readonly loadingIndicator: Locator;
|
||||
|
||||
// SAML specific elements
|
||||
readonly samlModeTitle: Locator;
|
||||
readonly samlEmailInput: Locator;
|
||||
|
||||
constructor(page: Page) {
|
||||
this.page = page;
|
||||
this.homePage = new HomePage(page);
|
||||
|
||||
// Form elements
|
||||
this.emailInput = page.getByLabel("Email");
|
||||
this.passwordInput = page.getByLabel("Password");
|
||||
this.loginButton = page.getByRole("button", { name: "Log in" });
|
||||
this.form = page.locator("form");
|
||||
|
||||
// Social authentication buttons
|
||||
this.googleButton = page.getByText("Continue with Google");
|
||||
this.githubButton = page.getByText("Continue with Github");
|
||||
this.samlButton = page.getByText("Continue with SAML SSO");
|
||||
|
||||
// Navigation elements
|
||||
this.signUpLink = page.getByRole("link", { name: "Sign up" });
|
||||
this.backButton = page.getByText("Back");
|
||||
|
||||
// UI elements
|
||||
this.title = page.getByText("Sign in", { exact: true });
|
||||
this.logo = page.locator('svg[width="300"]');
|
||||
this.themeToggle = page.getByLabel("Toggle theme");
|
||||
|
||||
// Error messages
|
||||
this.errorMessages = page.locator('[role="alert"], .error-message, [data-testid="error"]');
|
||||
this.loadingIndicator = page.getByText("Loading");
|
||||
|
||||
// SAML specific elements
|
||||
this.samlModeTitle = page.getByText("Sign in with SAML SSO");
|
||||
this.samlEmailInput = page.getByLabel("Email");
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
async goto(): Promise<void> {
|
||||
await this.page.goto("/sign-in");
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async waitForPageLoad(): Promise<void> {
|
||||
await this.page.waitForLoadState("networkidle");
|
||||
}
|
||||
|
||||
// Form interaction methods
|
||||
async fillEmail(email: string): Promise<void> {
|
||||
await this.emailInput.fill(email);
|
||||
}
|
||||
|
||||
async fillPassword(password: string): Promise<void> {
|
||||
await this.passwordInput.fill(password);
|
||||
}
|
||||
|
||||
async fillCredentials(credentials: SignInCredentials): Promise<void> {
|
||||
await this.fillEmail(credentials.email);
|
||||
await this.fillPassword(credentials.password);
|
||||
}
|
||||
|
||||
async submitForm(): Promise<void> {
|
||||
await this.loginButton.click();
|
||||
}
|
||||
|
||||
async login(credentials: SignInCredentials): Promise<void> {
|
||||
await this.fillCredentials(credentials);
|
||||
await this.submitForm();
|
||||
}
|
||||
|
||||
// Social authentication methods
|
||||
async clickGoogleAuth(): Promise<void> {
|
||||
await this.googleButton.click();
|
||||
}
|
||||
|
||||
async clickGithubAuth(): Promise<void> {
|
||||
await this.githubButton.click();
|
||||
}
|
||||
|
||||
async clickSamlAuth(): Promise<void> {
|
||||
await this.samlButton.click();
|
||||
}
|
||||
|
||||
// SAML SSO methods
|
||||
async toggleSamlMode(): Promise<void> {
|
||||
await this.clickSamlAuth();
|
||||
}
|
||||
|
||||
async goBackFromSaml(): Promise<void> {
|
||||
await this.backButton.click();
|
||||
}
|
||||
|
||||
async fillSamlEmail(email: string): Promise<void> {
|
||||
await this.samlEmailInput.fill(email);
|
||||
}
|
||||
|
||||
async submitSamlForm(): Promise<void> {
|
||||
await this.submitForm();
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
async goToSignUp(): Promise<void> {
|
||||
await this.signUpLink.click();
|
||||
}
|
||||
|
||||
// Validation and assertion methods
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.logo).toBeVisible();
|
||||
await expect(this.title).toBeVisible();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async verifyFormElements(): Promise<void> {
|
||||
await expect(this.emailInput).toBeVisible();
|
||||
await expect(this.passwordInput).toBeVisible();
|
||||
await expect(this.loginButton).toBeVisible();
|
||||
}
|
||||
|
||||
async verifySocialButtons(config: SocialAuthConfig): Promise<void> {
|
||||
if (config.googleEnabled) {
|
||||
await expect(this.googleButton).toBeVisible();
|
||||
}
|
||||
if (config.githubEnabled) {
|
||||
await expect(this.githubButton).toBeVisible();
|
||||
}
|
||||
await expect(this.samlButton).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyNavigationLinks(): Promise<void> {
|
||||
await expect(this.page.getByText("Need to create an account?")).toBeVisible();
|
||||
await expect(this.signUpLink).toBeVisible();
|
||||
}
|
||||
|
||||
async verifySuccessfulLogin(): Promise<void> {
|
||||
await this.homePage.verifyPageLoaded();
|
||||
}
|
||||
|
||||
async verifyLoginError(errorMessage: string = "Invalid email or password"): Promise<void> {
|
||||
await expect(this.page.getByText(errorMessage).first()).toBeVisible();
|
||||
await expect(this.page).toHaveURL("/sign-in");
|
||||
}
|
||||
|
||||
async verifySamlModeActive(): Promise<void> {
|
||||
await expect(this.samlModeTitle).toBeVisible();
|
||||
await expect(this.passwordInput).not.toBeVisible();
|
||||
await expect(this.backButton).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyNormalModeActive(): Promise<void> {
|
||||
await expect(this.title).toBeVisible();
|
||||
await expect(this.passwordInput).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyLoadingState(): Promise<void> {
|
||||
await expect(this.loginButton).toHaveAttribute("aria-disabled", "true");
|
||||
await expect(this.loadingIndicator).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyFormValidation(): Promise<void> {
|
||||
// Check for common validation messages
|
||||
const emailError = this.page.getByText("Please enter a valid email address.");
|
||||
const passwordError = this.page.getByText("Password is required.");
|
||||
|
||||
// At least one validation error should be visible
|
||||
await expect(emailError.or(passwordError)).toBeVisible();
|
||||
}
|
||||
|
||||
// Accessibility methods
|
||||
async verifyKeyboardNavigation(): Promise<void> {
|
||||
// Test tab navigation through form elements
|
||||
await this.page.keyboard.press("Tab"); // Theme toggle
|
||||
await this.page.keyboard.press("Tab"); // Email field
|
||||
await expect(this.emailInput).toBeFocused();
|
||||
|
||||
await this.page.keyboard.press("Tab"); // Password field
|
||||
await expect(this.passwordInput).toBeFocused();
|
||||
|
||||
await this.page.keyboard.press("Tab"); // Show password button
|
||||
await this.page.keyboard.press("Tab"); // Login button
|
||||
await expect(this.loginButton).toBeFocused();
|
||||
}
|
||||
|
||||
async verifyAriaLabels(): Promise<void> {
|
||||
await expect(this.page.getByRole("textbox", { name: "Email" })).toBeVisible();
|
||||
await expect(this.page.getByRole("textbox", { name: "Password" })).toBeVisible();
|
||||
await expect(this.page.getByRole("button", { name: "Log in" })).toBeVisible();
|
||||
}
|
||||
|
||||
// Utility methods
|
||||
async clearForm(): Promise<void> {
|
||||
await this.emailInput.clear();
|
||||
await this.passwordInput.clear();
|
||||
}
|
||||
|
||||
async isFormValid(): Promise<boolean> {
|
||||
const emailValue = await this.emailInput.inputValue();
|
||||
const passwordValue = await this.passwordInput.inputValue();
|
||||
return emailValue.length > 0 && passwordValue.length > 0;
|
||||
}
|
||||
|
||||
async getFormErrors(): Promise<string[]> {
|
||||
const errorElements = await this.errorMessages.all();
|
||||
const errors: string[] = [];
|
||||
|
||||
for (const element of errorElements) {
|
||||
const text = await element.textContent();
|
||||
if (text) {
|
||||
errors.push(text.trim());
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Browser interaction methods
|
||||
async refresh(): Promise<void> {
|
||||
await this.page.reload();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async goBack(): Promise<void> {
|
||||
await this.page.goBack();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
// Session management methods
|
||||
async logout(): Promise<void> {
|
||||
await this.homePage.signOut();
|
||||
}
|
||||
|
||||
async verifyLogoutSuccess(): Promise<void> {
|
||||
await expect(this.page).toHaveURL("/sign-in");
|
||||
await expect(this.title).toBeVisible();
|
||||
}
|
||||
|
||||
// Advanced interaction methods
|
||||
async fillFormWithValidation(credentials: SignInCredentials): Promise<void> {
|
||||
// Fill email first and check for validation
|
||||
await this.fillEmail(credentials.email);
|
||||
await this.page.keyboard.press("Tab"); // Trigger validation
|
||||
|
||||
// Fill password
|
||||
await this.fillPassword(credentials.password);
|
||||
}
|
||||
|
||||
async submitFormWithEnterKey(): Promise<void> {
|
||||
await this.passwordInput.press("Enter");
|
||||
}
|
||||
|
||||
async submitFormWithButtonClick(): Promise<void> {
|
||||
await this.submitForm();
|
||||
}
|
||||
|
||||
// Error handling methods
|
||||
async handleSamlError(): Promise<void> {
|
||||
const samlError = this.page.getByText("SAML Authentication Error");
|
||||
if (await samlError.isVisible()) {
|
||||
// Handle SAML error if present
|
||||
console.log("SAML authentication error detected");
|
||||
}
|
||||
}
|
||||
|
||||
// Wait methods
|
||||
async waitForFormSubmission(): Promise<void> {
|
||||
await this.page.waitForFunction(() => {
|
||||
const button = document.querySelector('button[aria-disabled="true"]');
|
||||
return button === null;
|
||||
});
|
||||
}
|
||||
|
||||
async waitForRedirect(expectedUrl: string): Promise<void> {
|
||||
await this.page.waitForURL(expectedUrl);
|
||||
}
|
||||
}
|
||||
@@ -45,19 +45,19 @@ export class SignInPage extends BasePage {
|
||||
this.homePage = new HomePage(page);
|
||||
|
||||
// Form elements
|
||||
this.emailInput = page.getByLabel("Email");
|
||||
this.passwordInput = page.getByLabel("Password");
|
||||
this.emailInput = page.getByRole("textbox", { name: "Email" });
|
||||
this.passwordInput = page.getByRole("textbox", { name: "Password" });
|
||||
this.loginButton = page.getByRole("button", { name: "Log in" });
|
||||
this.form = page.locator("form");
|
||||
|
||||
// Social authentication buttons
|
||||
this.googleButton = page.getByText("Continue with Google");
|
||||
this.githubButton = page.getByText("Continue with Github");
|
||||
this.samlButton = page.getByText("Continue with SAML SSO");
|
||||
this.googleButton = page.getByRole("button", { name: "Continue with Google" });
|
||||
this.githubButton = page.getByRole("button", { name: "Continue with Github" });
|
||||
this.samlButton = page.getByRole("button", { name: "Continue with SAML SSO" });
|
||||
|
||||
// Navigation elements
|
||||
this.signUpLink = page.getByRole("link", { name: "Sign up" });
|
||||
this.backButton = page.getByText("Back");
|
||||
this.backButton = page.getByRole("button", { name: "Back" });
|
||||
|
||||
// UI elements
|
||||
this.logo = page.locator('svg[width="300"]');
|
||||
@@ -66,8 +66,8 @@ export class SignInPage extends BasePage {
|
||||
this.errorMessages = page.locator('[role="alert"], .error-message, [data-testid="error"]');
|
||||
|
||||
// SAML specific elements
|
||||
this.samlModeTitle = page.getByText("Sign in with SAML SSO");
|
||||
this.samlEmailInput = page.getByLabel("Email");
|
||||
this.samlModeTitle = page.getByRole("heading", { name: "Sign in with SAML SSO" });
|
||||
this.samlEmailInput = page.getByRole("textbox", { name: "Email" });
|
||||
}
|
||||
|
||||
// Navigation methods
|
||||
@@ -137,7 +137,7 @@ export class SignInPage extends BasePage {
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
await expect(this.page).toHaveTitle(/Prowler/);
|
||||
await expect(this.logo).toBeVisible();
|
||||
await expect(this.page.getByText("Sign in", { exact: true })).toBeVisible();
|
||||
await expect(this.page.getByRole("heading", { name: "Sign in", exact: true })).toBeVisible();
|
||||
}
|
||||
|
||||
async verifyFormElements(): Promise<void> {
|
||||
@@ -157,7 +157,7 @@ export class SignInPage extends BasePage {
|
||||
}
|
||||
|
||||
async verifyNavigationLinks(): Promise<void> {
|
||||
await expect(this.page.getByText("Need to create an account?")).toBeVisible();
|
||||
await expect(this.page.getByRole('link', { name: /Need to create an account\?/i })).toBeVisible();
|
||||
await expect(this.signUpLink).toBeVisible();
|
||||
}
|
||||
|
||||
@@ -166,7 +166,7 @@ export class SignInPage extends BasePage {
|
||||
}
|
||||
|
||||
async verifyLoginError(errorMessage: string = "Invalid email or password"): Promise<void> {
|
||||
await expect(this.page.getByText(errorMessage).first()).toBeVisible();
|
||||
await expect(this.page.getByRole("alert", { name: errorMessage })).toBeVisible();
|
||||
await expect(this.page).toHaveURL("/sign-in");
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ export class SignInPage extends BasePage {
|
||||
}
|
||||
|
||||
async verifyNormalModeActive(): Promise<void> {
|
||||
await expect(this.page.getByText("Sign in", { exact: true })).toBeVisible();
|
||||
await expect(this.page.getByRole("heading", { name: "Sign in", exact: true })).toBeVisible();
|
||||
await expect(this.passwordInput).toBeVisible();
|
||||
}
|
||||
|
||||
@@ -188,8 +188,8 @@ export class SignInPage extends BasePage {
|
||||
|
||||
async verifyFormValidation(): Promise<void> {
|
||||
// Check for common validation messages
|
||||
const emailError = this.page.getByText("Please enter a valid email address.");
|
||||
const passwordError = this.page.getByText("Password is required.");
|
||||
const emailError = this.page.getByRole("alert", { name: "Please enter a valid email address." });
|
||||
const passwordError = this.page.getByRole("alert", { name: "Password is required." });
|
||||
|
||||
// At least one validation error should be visible
|
||||
await expect(emailError.or(passwordError)).toBeVisible();
|
||||
@@ -237,7 +237,7 @@ export class SignInPage extends BasePage {
|
||||
|
||||
async verifyLogoutSuccess(): Promise<void> {
|
||||
await expect(this.page).toHaveURL("/sign-in");
|
||||
await expect(this.page.getByText("Sign in", { exact: true })).toBeVisible();
|
||||
await expect(this.page.getByRole("heading", { name: "Sign in", exact: true })).toBeVisible();
|
||||
}
|
||||
|
||||
// Advanced interaction methods
|
||||
@@ -260,7 +260,7 @@ export class SignInPage extends BasePage {
|
||||
|
||||
// Error handling methods
|
||||
async handleSamlError(): Promise<void> {
|
||||
const samlError = this.page.getByText("SAML Authentication Error");
|
||||
const samlError = this.page.getByRole("alert", { name: "SAML Authentication Error" });
|
||||
if (await samlError.isVisible()) {
|
||||
// Handle SAML error if present
|
||||
console.log("SAML authentication error detected");
|
||||
|
||||
@@ -32,14 +32,14 @@ export class SignUpPage extends BasePage {
|
||||
// Prefer stable name attributes to avoid label ambiguity in composed inputs
|
||||
this.nameInput = page.locator('input[name="name"]');
|
||||
this.companyInput = page.locator('input[name="company"]');
|
||||
this.emailInput = page.getByLabel("Email");
|
||||
this.emailInput = page.getByRole("textbox", { name: "Email" });
|
||||
this.passwordInput = page.locator('input[name="password"]');
|
||||
this.confirmPasswordInput = page.locator('input[name="confirmPassword"]');
|
||||
this.invitationTokenInput = page.locator('input[name="invitationToken"]');
|
||||
|
||||
this.submitButton = page.getByRole("button", { name: "Sign up" });
|
||||
this.loginLink = page.getByRole("link", { name: "Log in" });
|
||||
this.termsCheckbox = page.getByText("I agree with the");
|
||||
this.termsCheckbox = page.getByRole("checkbox", { name: /I agree with the/i });
|
||||
}
|
||||
|
||||
async goto(): Promise<void> {
|
||||
@@ -47,9 +47,10 @@ export class SignUpPage extends BasePage {
|
||||
}
|
||||
|
||||
async verifyPageLoaded(): Promise<void> {
|
||||
await expect(this.page.getByText("Sign up", { exact: true })).toBeVisible();
|
||||
await expect(this.page.getByRole("heading", { name: "Sign up" })).toBeVisible();
|
||||
await expect(this.emailInput).toBeVisible();
|
||||
await expect(this.submitButton).toBeVisible();
|
||||
await this.waitForPageLoad();
|
||||
}
|
||||
|
||||
async fillName(name: string): Promise<void> {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
**Preconditions:**
|
||||
- Application is running, email domain & password is acceptable for sign-up.
|
||||
- No existing data in Prowler is required; the test can run on a clean state.
|
||||
- `E2E_NEW_PASSWORD` environment variable must be set with a valid password for the test.
|
||||
|
||||
### Flow Steps:
|
||||
1. Navigate to the Sign up page.
|
||||
@@ -37,5 +38,6 @@
|
||||
|
||||
### Notes:
|
||||
- Test data uses a random base36 suffix to avoid collisions with email.
|
||||
- The test requires the `E2E_NEW_PASSWORD` environment variable to be set before running.
|
||||
|
||||
|
||||
|
||||
@@ -4,38 +4,46 @@ import { SignInPage } from "../sign-in/sign-in-page";
|
||||
import { makeSuffix } from "../helpers";
|
||||
|
||||
test.describe("Sign Up Flow", () => {
|
||||
test("should register a new user successfully", { tag: ['@critical', '@e2e', '@signup', '@SIGNUP-E2E-001'] }, async ({ page }) => {
|
||||
const signUpPage = new SignUpPage(page);
|
||||
await signUpPage.goto();
|
||||
test(
|
||||
"should register a new user successfully",
|
||||
{ tag: ["@critical", "@e2e", "@signup", "@SIGNUP-E2E-001"] },
|
||||
async ({ page }) => {
|
||||
const password = process.env.E2E_NEW_PASSWORD;
|
||||
|
||||
// Generate unique test data
|
||||
const suffix = makeSuffix(10);
|
||||
const uniqueEmail = `e2e+${suffix}@prowler.com`;
|
||||
if (!password) {
|
||||
throw new Error("E2E_NEW_PASSWORD environment variable is not set");
|
||||
}
|
||||
|
||||
// Fill and submit the sign-up form
|
||||
await signUpPage.signup({
|
||||
name: `E2E User ${suffix}`,
|
||||
company: `Test E2E Co ${suffix}`,
|
||||
email: uniqueEmail,
|
||||
password: "Thisisapassword123@",
|
||||
confirmPassword: "Thisisapassword123@",
|
||||
acceptTerms: true,
|
||||
});
|
||||
|
||||
// Verify no errors occurred during sign-up
|
||||
await signUpPage.verifyNoErrors();
|
||||
|
||||
// Verify redirect to login page (OSS environment)
|
||||
await signUpPage.verifyRedirectToLogin();
|
||||
|
||||
// Verify the newly created user can log in successfully
|
||||
const signInPage = new SignInPage(page);
|
||||
await signInPage.login({
|
||||
email: uniqueEmail,
|
||||
password: "Thisisapassword123@",
|
||||
});
|
||||
await signInPage.verifySuccessfulLogin();
|
||||
});
|
||||
const signUpPage = new SignUpPage(page);
|
||||
await signUpPage.goto();
|
||||
|
||||
// Generate unique test data
|
||||
const suffix = makeSuffix(10);
|
||||
const uniqueEmail = `e2e+${suffix}@prowler.com`;
|
||||
|
||||
// Fill and submit the sign-up form
|
||||
await signUpPage.signup({
|
||||
name: `E2E User ${suffix}`,
|
||||
company: `Test E2E Co ${suffix}`,
|
||||
email: uniqueEmail,
|
||||
password: password,
|
||||
confirmPassword: password,
|
||||
acceptTerms: true,
|
||||
});
|
||||
|
||||
// Verify no errors occurred during sign-up
|
||||
await signUpPage.verifyNoErrors();
|
||||
|
||||
// Verify redirect to login page (OSS environment)
|
||||
await signUpPage.verifyRedirectToLogin();
|
||||
|
||||
// Verify the newly created user can log in successfully
|
||||
const signInPage = new SignInPage(page);
|
||||
await signInPage.login({
|
||||
email: uniqueEmail,
|
||||
password: password,
|
||||
});
|
||||
await signInPage.verifySuccessfulLogin();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user