import test, { expect, type Locator, type Page } from '@playwright/test'; import { BasePage } from './BasePage'; import { IClaimDetails, ICustomerDetails } from '@business-logic/types/CustomerDetails'; import { getClientAuthByClientTag, getClientSignature } from '@impl/api/AdminServiceApiUtil'; import { ICertificateInfo, IClientSignatureRequest } from '@business-logic/types/Authentication'; import { buildToken, getTimestamp } from '@impl/utils/TokenUtils'; import ClientData from "@business-logic/data/ClientData"; export class WelcomePage extends BasePage { private static readonly GENERIC_BRAND_WORDS = new Set(['insurance', 'mutual', 'group', 'company', 'private', 'client']); readonly page: Page; readonly policyNumber: Locator; readonly policyZip: Locator; readonly damageDate: Locator; readonly damageCause: Locator; readonly phoneNumber: Locator; readonly emailAddress: Locator; readonly city: Locator; readonly state: Locator; readonly cookieCloseButton: Locator; readonly GetStartedButton: Locator; readonly applicationPageHeader: Locator; readonly applicationLogo: Locator; readonly applicationSubHeader: Locator; url = process.env['BASE_URL']! + '/?issPage=welcome-page'; issPageValue = 'welcome-page'; constructor(page: Page) { super(page); this.page = page; this.policyNumber = page.getByRole('textbox', { name: 'Policy number' }); this.policyZip = page.getByRole('textbox', { name: 'Policy ZIP' }); this.damageDate = page.locator('#dateOfLossField'); this.damageCause = page.locator('#damageCauseQuestionField'); this.phoneNumber = page.getByRole('textbox', { name: 'Best number to reach you' }); this.emailAddress = page.getByRole('textbox', { name: 'Email address' }); this.city = page.getByRole('textbox', { name: 'In which city did the damage' }); this.state = page.locator('select[name="\\38 fdf9dc2e13e430eb57529499dceb3eb"]'); this.cookieCloseButton = page.getByRole('button', { name: 'Close' }); this.GetStartedButton = page.getByRole('button', { name: 'Get Started' }); this.applicationPageHeader = page.locator('.site-header-container'); this.applicationLogo = page.locator('#siteHeaderImage'); this.applicationSubHeader = page.locator('xpath=//h5[contains(@class,"subheader")]//span'); } async goto(clientTag: string) { await this.page.goto(process.env['BASE_URL']! + `/?issPage=entry-page&ClientTag=${clientTag}`); await this.waitForURL(this.url); await this.dismissCookiePopupIfPresent(); } async dismissCookiePopupIfPresent() { try { await this.cookieCloseButton.waitFor({ state: 'visible', timeout: 3000 }); await this.cookieCloseButton.click(); } catch { } } async gotoWithAuthentication(clientTag: string) { const clientAuth = await getClientAuthByClientTag(clientTag); const certificate = clientAuth.certificateInfo[0] as ICertificateInfo; let formData: Map = new Map(); formData.set("Timestamp", getTimestamp()) const request: IClientSignatureRequest = { clientTag: clientTag, token: buildToken(clientAuth, formData), certificateFileName: certificate.name, certificateKey: certificate.key, certificateAlgorithm: certificate.algorithm, certificateType: certificate.type } const result = await getClientSignature(request); await this.page.goto(process.env['BASE_URL']! + `/?issPage=entry-page&ClientTag=${clientTag}&token=${request.token}&signature=${result.signature}`); await this.waitForURL(this.url); await this.logReferralNumber(); await this.cookieCloseButton.click(); } async hasCityInfo() { await expect.soft(this.damageCause).toBeVisible(); return this.city.isVisible(); } async hasApplicationPageHeader(currentClientTag: string, accountNumber?: string) { const client = ClientData.resolveClientForTest(currentClientTag, accountNumber); if (client?.bgColor) { const actualBgColor = await this.applicationPageHeader.evaluate((el) => { return window.getComputedStyle(el).getPropertyValue('background-color'); }); const normalize = (color: string) => color.replace(/\s+/g, ''); expect(normalize(actualBgColor)).toBe(normalize(client.bgColor)); } } private getBrandTokens(name: string): string[] { return name .toLowerCase() .split(/\s+/) .filter(word => word.length > 2 && !WelcomePage.GENERIC_BRAND_WORDS.has(word)); } private matchesBrandText(text: string, name: string): boolean { return this.getBrandTokens(name).some(token => text.includes(token)); } async hasApplicationLogo(currentClientTag: string, accountNumber?: string) { await expect(this.applicationLogo).toBeVisible(); const client = ClientData.resolveClientForTest(currentClientTag, accountNumber); const altTextString = ((await this.applicationLogo.getAttribute('alt')) ?? '').toLowerCase(); const hasBrandMatch = this.matchesBrandText(altTextString, client?.accountName ?? ''); await expect(hasBrandMatch).toBeTruthy(); } async hasApplicationSubHeader(currentClientTag: string, accountNumber?: string) { await expect(this.applicationSubHeader).toBeVisible(); const client = ClientData.resolveClientForTest(currentClientTag, accountNumber); const subHeaderTextString = ((await this.applicationSubHeader.innerText()) ?? '').toLowerCase(); await expect(subHeaderTextString).toContain('welcome to'); const brandSourceName = client?.parentCarrierName ?? client?.accountName ?? ''; const hasBrandMatch = this.matchesBrandText(subHeaderTextString, brandSourceName); await expect(hasBrandMatch).toBeTruthy(); } async validateDamageLocationFieldsIfRequired(clientTag: string, accountNumber?: string) { const client = ClientData.resolveClientForTest(clientTag, accountNumber); if (!client?.clientFlags.isWelcomeDamageLocationRequired) { return; } await expect(this.page.getByText(/which state did the damage occur/i)).toBeVisible(); await expect(this.state).toBeVisible(); await expect(this.page.getByText(/which city did the damage occur/i)).toBeVisible(); await expect(this.city).toBeVisible(); } async populatePage(customerDetails: ICustomerDetails, claimDetails: IClaimDetails, isFillCityInfo: boolean) { await this.policyNumber.fill(claimDetails.policyNumber); await this.phoneNumber.fill(customerDetails.phoneNumber); await this.damageDate.click(); await this.damageDate.fill(claimDetails.damageDate); await this.damageCause.selectOption(claimDetails.damageCause); await this.damageCause.press('Tab'); await this.policyZip.fill(customerDetails.address.postalCode); if (isFillCityInfo) { await this.state.selectOption(customerDetails.address.state); await this.city.fill(customerDetails.address.city); } } }