Added a context manager to test with multiple accounts interacting with each other

Added an option to verify the users email when creating an account
This commit is contained in:
Okechi Jones-Williams
2026-05-27 20:01:43 +01:00
parent 4c2bd90431
commit 00e7662d60
8 changed files with 145 additions and 10 deletions

View File

@@ -0,0 +1,27 @@
import {Browser, BrowserContext} from '@playwright/test'
import {App} from '../web/pages/app'
export class ContextManager {
private contexts: Map<string, App> = new Map()
constructor(private browser: Browser) {}
async createContext(name: string): Promise<App> {
const context = await this.browser.newContext()
const page = await context.newPage()
const app = new App(page)
this.contexts.set(name, app)
return app
}
getContext(name: string): App | undefined {
return this.contexts.get(name)
}
async closeAll(): Promise<void> {
for (const app of this.contexts.values()) {
await app.page.context().close()
}
this.contexts.clear()
}
}

View File

@@ -37,6 +37,36 @@ export async function findUser(idToken: string) {
}
}
export async function sendVerificationEmail(idToken: string) {
await axios.post(`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.SEND_EMAIL_VERIFICATION}`, {
requestType: 'VERIFY_EMAIL',
idToken,
})
}
export async function getOobCode(oobCodes: any[], email: string) {
return oobCodes.find((item) => item.email.toLowerCase() === email.toLowerCase())?.oobCode
}
export async function verifyEmail(email: string, password: string) {
try {
const loginInfo = await firebaseLoginEmailPassword(email, password)
await sendVerificationEmail(loginInfo.data.idToken)
const oobResponse = await axios.get(`${config.FIREBASE_URL.FIREBASE_EMULATOR_API}`)
const oobCode = await getOobCode(oobResponse.data.oobCodes, email)
console.log(oobCode)
const response = await axios.post(
`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.CONFIRM_EMAIL_VERIFICATION}`,
{
oobCode,
},
)
} catch (err: any) {
console.log(err)
throw err
}
}
export async function firebaseSignUp(email: string, password: string) {
try {
const response = await axios.post(`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.SIGNUP}`, {

View File

@@ -9,7 +9,7 @@ import {insert} from 'shared/supabase/utils'
import {getUser} from 'shared/utils'
import UserAccountInformationForSeeding from '../backend/utils/userInformation'
import {firebaseSignUp} from './firebaseUtils'
import {firebaseSignUp, verifyEmail} from './firebaseUtils'
/**
* Function used to populate the database with profiles.
@@ -151,6 +151,7 @@ export async function seedUser(
profileType?: string | undefined,
displayName?: string | undefined,
userName?: string | undefined,
verifyUserEmail?: boolean,
) {
const userInfo = new UserAccountInformationForSeeding()
if (email) userInfo.email = email
@@ -162,4 +163,5 @@ export async function seedUser(
// Fall back to the pre-generated faker id when Firebase is unreachable
const created = await seedDbUser(userInfo, profileType ?? 'full')
if (created) debug('User created in Supabase:', userInfo.email)
if (verifyUserEmail) await verifyEmail(userInfo.email, userInfo.password)
}

View File

@@ -2,10 +2,13 @@ export const config = {
BASE_URL: 'http://localhost:3000',
FIREBASE_URL: {
BASE: 'http://localhost:9099/identitytoolkit.googleapis.com/v1',
FIREBASE_EMULATOR_API: 'http://localhost:9099/emulator/v1/projects/compass-57c3c/oobCodes',
SIGNUP: '/accounts:signUp?key=fake-api-key',
SIGN_IN_PASSWORD: '/accounts:signInWithPassword?key=fake-api-key',
ACCOUNT_LOOKUP: '/accounts:lookup?key=fake-api-key',
DELETE: '/accounts:delete?key=fake-api-key',
SEND_EMAIL_VERIFICATION: '/accounts:sendOobCode?key=fake-api-key',
CONFIRM_EMAIL_VERIFICATION: '/accounts:update?key=fake-api-key',
},
USERS: {
DEV_1: {

View File

@@ -7,7 +7,9 @@ import {deleteUser} from '../utils/deleteUser'
export const test = base.extend<{
app: App
dev_one_account: UserAccountInformation
devOneAccount: UserAccountInformation
devTwoAccount: UserAccountInformation
specAccount: UserAccountInformation
fakerAccount: UserAccountInformation
googleAccountOne: UserAccountInformation
googleAccountTwo: UserAccountInformation
@@ -43,6 +45,45 @@ export const test = base.extend<{
await use(account)
await deleteUser('Email/Password', account)
},
devOneAccount: async ({}, use) => {
const account = testAccounts.dev_one_account()
await seedUser(
account.email,
account.password,
undefined,
account.display_name,
account.username,
true,
)
await use(account)
await deleteUser('Email/Password', account)
},
devTwoAccount: async ({}, use) => {
const account = testAccounts.dev_two_account()
await seedUser(
account.email,
account.password,
undefined,
account.display_name,
account.username,
true,
)
await use(account)
await deleteUser('Email/Password', account)
},
specAccount: async ({}, use) => {
const account = testAccounts.spec_account()
await seedUser(
account.email,
account.password,
undefined,
account.display_name,
account.username,
true,
)
await use(account)
await deleteUser('Email/Password', account)
},
fakerAccount: async ({}, use) => {
const account = testAccounts.faker_account()
await use(account)

View File

@@ -1,6 +1,7 @@
import {Page} from '@playwright/test'
import {BrowserContext, Page} from '@playwright/test'
import {UserAccountInformation} from '../utils/accountInformation'
import {ContextManager} from '../../utils/contextManager'
import {AuthPage} from './authPage'
import {CompatibilityPage} from './compatibilityPage'
import {HomePage} from './homePage'
@@ -25,6 +26,8 @@ export class App {
readonly social: SocialPage
readonly people: PeoplePage
readonly notifs: NotificationPage
readonly contextManager: ContextManager
readonly context: BrowserContext
constructor(public readonly page: Page) {
this.auth = new AuthPage(page)
@@ -38,6 +41,11 @@ export class App {
this.social = new SocialPage(page)
this.people = new PeoplePage(page)
this.notifs = new NotificationPage(page)
this.context = page.context()
const browser = page.context().browser()
if (!browser) throw new Error('Could not get Browser from page.context().browser()')
this.contextManager = new ContextManager(browser)
}
async deleteProfileFromSettings() {

View File

@@ -1,15 +1,27 @@
import axios from 'axios'
import {config} from '../SPEC_CONFIG'
import {
firebaseLoginEmailPassword,
getOobCode,
getUserId,
sendVerificationEmail,
} from '../../utils/firebaseUtils'
async function setup() {
const results = await axios.post(`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.SIGNUP}`, {
email: 'trial_test@email.com',
password: 'trialTestPassword',
returnSecureToken: true,
})
const loginInfo = await firebaseLoginEmailPassword('AnotherTest@email.com', 'Password')
await sendVerificationEmail(loginInfo.data.idToken)
const oobResponse = await axios.get(`${config.FIREBASE_URL.FIREBASE_EMULATOR_API}`)
const oobCode = await getOobCode(oobResponse.data.oobCodes, 'AnotherTest@email.com')
console.log(oobCode)
console.log('Auth created: ', 'trial_test@email.com')
console.log('Id: ', results.data.localId)
const response = await axios.post(
`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.CONFIRM_EMAIL_VERIFICATION}`,
{
oobCode,
},
)
console.log(response)
console.log(response.status)
}
setup()

View File

@@ -1,4 +1,5 @@
import {expect, test} from '../fixtures/signInFixture'
import {ContextManager} from '../../utils/contextManager'
test.describe('when given valid input', () => {
test('should be able to sign in to an available account', async ({
@@ -223,6 +224,17 @@ test.describe('when given valid input', () => {
await expect(profile).toBeVisible()
})
})
test.describe('a verified account should', () => {
test('be able to send a message', async ({app, devOneAccount, devTwoAccount}) => {
const devOne = await app.contextManager.createContext('devOne')
const devTwo = await app.contextManager.createContext('devTwo')
await devOne.signinWithEmail(devOneAccount)
await devOne.home.clickPeopleLink()
await devTwo.signinWithEmail(devTwoAccount)
await devTwo.home.clickPeopleLink()
})
})
})
test.describe('when given invalid input', () => {