import { Page, expect } from '@playwright/test'; export class RegistrationPage { readonly page: Page; private readonly selectors = { // Personal Information firstNameInput: '#first_name', lastNameInput: '#last_name', emailInput: '#email', passwordInput: '#password', displayNameInput: '#display_name', profileImageInput: '#profile_image', // Business Information businessNameInput: '#business_name', businessPhoneInput: '#business_phone', businessEmailInput: '#business_email', countrySelect: '#country', stateSelect: '#state', cityInput: '#city', businessTypeSelect: '#business_type', // Training Information trainingAudienceSelect: '#training_audience', trainingFormatsSelect: '#training_formats', trainingLocationsSelect: '#training_locations', trainingResourcesSelect: '#training_resources', applicationDetailsTextarea: '#application_details', // Form Controls submitButton: '#submit-registration', errorMessages: '.error-message', successMessage: '.success-message' }; constructor(page: Page) { this.page = page; } async navigate() { await this.page.goto('/community-registration/'); } async fillPersonalInfo(data: { firstName: string, lastName: string, email: string, password: string, displayName: string }) { await this.page.fill(this.selectors.firstNameInput, data.firstName); await this.page.fill(this.selectors.lastNameInput, data.lastName); await this.page.fill(this.selectors.emailInput, data.email); await this.page.fill(this.selectors.passwordInput, data.password); await this.page.fill(this.selectors.displayNameInput, data.displayName); } async fillBusinessInfo(data: { businessName: string, businessPhone: string, businessEmail: string, country: string, state: string, city: string, businessType: string }) { await this.page.fill(this.selectors.businessNameInput, data.businessName); await this.page.fill(this.selectors.businessPhoneInput, data.businessPhone); await this.page.fill(this.selectors.businessEmailInput, data.businessEmail); await this.page.selectOption(this.selectors.countrySelect, data.country); await this.page.waitForTimeout(500); // Wait for state dropdown to update await this.page.selectOption(this.selectors.stateSelect, data.state); await this.page.fill(this.selectors.cityInput, data.city); await this.page.selectOption(this.selectors.businessTypeSelect, data.businessType); } async fillTrainingInfo(data: { audience: string[], formats: string[], locations: string[], resources: string[], details: string }) { await this.page.selectOption(this.selectors.trainingAudienceSelect, data.audience); await this.page.selectOption(this.selectors.trainingFormatsSelect, data.formats); await this.page.selectOption(this.selectors.trainingLocationsSelect, data.locations); await this.page.selectOption(this.selectors.trainingResourcesSelect, data.resources); await this.page.fill(this.selectors.applicationDetailsTextarea, data.details); } async uploadProfileImage(filePath: string) { const input = await this.page.$(this.selectors.profileImageInput); if (input) { await input.setInputFiles(filePath); } } async submitForm() { await this.page.click(this.selectors.submitButton); } async verifyErrorMessage(expectedError: string) { const errorElement = await this.page.waitForSelector(this.selectors.errorMessages); const errorText = await errorElement.textContent(); expect(errorText?.toLowerCase()).toContain(expectedError.toLowerCase()); } async verifySuccessfulRegistration() { await this.page.waitForSelector(this.selectors.successMessage); const currentUrl = this.page.url(); expect(currentUrl).toContain('/registration-success'); } async verifyPasswordComplexity(password: string): Promise { const hasUpperCase = /[A-Z]/.test(password); const hasLowerCase = /[a-z]/.test(password); const hasNumber = /[0-9]/.test(password); const isLongEnough = password.length >= 8; return hasUpperCase && hasLowerCase && hasNumber && isLongEnough; } async verifyCountryStateLogic() { // Verify US/Canada states at top await this.page.selectOption(this.selectors.countrySelect, 'US'); let states = await this.page.$$eval(this.selectors.stateSelect + ' option', (options: HTMLOptionElement[]) => options.map(opt => opt.value) ); expect(states[1]).toMatch(/^(US-|CA-)/); // First state should be US or CA (after default option) // Verify "Other" option for non-US/Canada await this.page.selectOption(this.selectors.countrySelect, 'FR'); states = await this.page.$$eval(this.selectors.stateSelect + ' option', (options: HTMLOptionElement[]) => options.map(opt => opt.value) ); expect(states).toContain('OTHER'); } }