import { expect, ExpectMatcherState, MatcherReturnType } from '@playwright/test'; export const customAssertions = { toHaveValidationError: async function( this: ExpectMatcherState, element: any, message: string ): Promise { const errorText = await element.textContent(); const pass = errorText?.toLowerCase().includes(message.toLowerCase()); return { pass, message: () => pass ? `Expected error message not to contain "${message}"` : `Expected error message to contain "${message}"` }; }, toBeValidPassword: function( this: ExpectMatcherState, password: string ): MatcherReturnType { const hasMinLength = password.length >= 8; const hasUpperCase = /[A-Z]/.test(password); const hasLowerCase = /[a-z]/.test(password); const hasNumber = /[0-9]/.test(password); const pass = hasMinLength && hasUpperCase && hasLowerCase && hasNumber; return { pass, message: () => pass ? `Expected "${password}" not to be a valid password` : `Expected "${password}" to be a valid password (8+ chars, upper, lower, number)` }; }, toBeValidFileType: function( this: ExpectMatcherState, filename: string ): MatcherReturnType { const validExtensions = ['.jpg', '.png', '.gif', '.mpg']; const extension = filename.toLowerCase().match(/\.[^.]+$/)?.[0]; const pass = extension ? validExtensions.includes(extension) : false; return { pass, message: () => pass ? `Expected "${filename}" not to be a valid file type` : `Expected "${filename}" to be one of: ${validExtensions.join(', ')}` }; }, toBeValidCountryState: function( this: ExpectMatcherState, state: string, country: string ): MatcherReturnType { let pass = false; if (country === 'US') { pass = /^US-[A-Z]{2}$/.test(state); } else if (country === 'CA') { pass = /^CA-[A-Z]{2}$/.test(state); } else { pass = state === 'OTHER'; } return { pass, message: () => pass ? `Expected "${state}" not to be valid for country "${country}"` : `Expected "${state}" to be valid for country "${country}"` }; } }; expect.extend(customAssertions); declare global { namespace PlaywrightTest { interface Matchers { toHaveValidationError(message: string): Promise; toBeValidPassword(): R; toBeValidFileType(): R; toBeValidCountryState(country: string): R; } } }