FIx E2E context manager

This commit is contained in:
MartinBraquet
2026-05-29 02:18:10 +02:00
parent c74c36af73
commit 699184081d
5 changed files with 111 additions and 71 deletions

View File

@@ -65,6 +65,6 @@ export default defineConfig({
],
timeout: 120000,
expect: {
timeout: 120000,
timeout: 60000,
},
})

View File

@@ -14,10 +14,15 @@ export class ContextManager {
if (existing) await existing.page.context().close()
const context = await this.browser.newContext()
const page = await context.newPage()
const app = new App(page)
this.contexts.set(name, app)
return app
try {
const page = await context.newPage()
const app = new App(page, false)
this.contexts.set(name, app)
return app
} catch (error) {
await context.close()
throw error
}
}
getContext(name: string): App | undefined {
@@ -26,7 +31,11 @@ export class ContextManager {
async closeAll(): Promise<void> {
for (const app of this.contexts.values()) {
await app.page.context().close()
try {
await app.page.context().close()
} catch {
// context may already be closed
}
}
this.contexts.clear()
}

View File

@@ -28,10 +28,13 @@ export class App {
readonly people: PeoplePage
readonly notifs: NotificationPage
readonly messages: MessagesPage
readonly contextManager: ContextManager
readonly contextManager: ContextManager | undefined
readonly context: BrowserContext
constructor(public readonly page: Page) {
constructor(
public readonly page: Page,
createContextManager = true,
) {
this.auth = new AuthPage(page)
this.compatibility = new CompatibilityPage(page)
this.home = new HomePage(page)
@@ -46,9 +49,11 @@ export class App {
this.messages = new MessagesPage(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)
if (createContextManager) {
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,17 +1,18 @@
import {expect, Locator, Page} from '@playwright/test'
import {
ConnectionTypeTuple,
EducationTuple,
DietTuple,
PsychedelicsTuple,
CannabisTuple,
LanguageTuple,
PoliticalTuple,
ReligionTuple,
PersonalityKey,
LastActiveTuple,
ConnectionTypeTuple,
DietTuple,
EducationTuple,
InterestedInGenderTuple,
LanguageTuple,
LastActiveTuple,
PersonalityKey,
PoliticalTuple,
PsychedelicsTuple,
ReligionTuple,
} from 'common/choices'
import {MinMaxNumbers} from '../utils/accountInformation'
export type BackgroundFilter = {
@@ -459,22 +460,7 @@ export class PeoplePage {
if (totalResults === 0) throw Error('No profiles found')
const chosenProfileNumber = Math.floor(Math.random() * totalResults)
const chosenProfile = await this.profileResults.nth(chosenProfileNumber)
const profileName = await chosenProfile.getByTestId('people-profile-name').textContent()
const ageGender = await chosenProfile.getByTestId('people-profile-age-gender').textContent()
const seekingInfo = await chosenProfile.getByTestId('people-profile-seeking').textContent()
const hideProfile = await chosenProfile.getByTestId('hide-profile-button')
const starProfile = await chosenProfile.getByTestId('star-profile-button')
const messageProfile = await chosenProfile.getByTestId('message-profile-button')
return {
profile: chosenProfile ?? '',
name: profileName ?? '',
ageGender: ageGender ?? '',
seeking: seekingInfo ?? '',
hide: hideProfile ?? '',
star: starProfile ?? '',
message: messageProfile ?? '',
}
return chosenProfile
}
async verifyProfileCount(totalProfiles: string) {
@@ -512,7 +498,8 @@ export class PeoplePage {
}
}
async verifySavedPerson(displayName: string) {
async verifySavedPerson(displayName: string | null | undefined) {
if (!displayName) throw new Error('No display name provided')
await expect(this.savedPeopleHeading).toBeVisible()
await this.page.waitForTimeout(1000)
const isThereSavedPeople = (await this.savedPeopleList.count()) > 0
@@ -530,3 +517,27 @@ export class PeoplePage {
}
}
}
export async function getCardName(profile: Locator) {
return await profile.getByTestId('people-profile-name').textContent()
}
export async function getCardAgeGender(profile: Locator) {
return await profile.getByTestId('people-profile-age-gender').textContent()
}
export async function getCardSeekingInfo(profile: Locator) {
return await profile.getByTestId('people-profile-seeking').textContent()
}
export async function getCardHide(profile: Locator) {
return await profile.getByTestId('hide-profile-button')
}
export async function getCardStar(profile: Locator) {
return await profile.getByTestId('star-profile-button')
}
export async function getCardMessage(profile: Locator) {
return await profile.getByTestId('message-profile-button')
}

View File

@@ -2,6 +2,7 @@ import {sleep} from 'common/util/time'
import {TEST_USER_DISPLAY_NAME} from '../../utils/seedDatabase'
import {expect, test} from '../fixtures/signInFixture'
import {getCardAgeGender, getCardName, getCardSeekingInfo, getCardStar} from '../pages/peoplePage'
test.describe('when given valid input', () => {
test('should be able to sign in to an available account', async ({
@@ -17,11 +18,13 @@ test.describe('when given valid input', () => {
await app.signinWithEmail(account)
await app.home.clickPeopleLink()
const profile = await app.people.getProfileInfo()
await expect(profile.star).toBeVisible()
await profile.star.click()
const star = await getCardStar(profile)
const name = await getCardName(profile)
await expect(star).toBeVisible()
await star.click()
await sleep(1000)
await app.people.clickSavedPeopleButton()
await app.people.verifySavedPerson(profile.name)
await app.people.verifySavedPerson(name)
})
test.describe('the applied filter should', () => {
@@ -42,9 +45,10 @@ test.describe('when given valid input', () => {
Number(filteredProfiles?.split(' ')[0]),
)
const results = await app.people.getProfileInfo()
if (!results) return
await expect(results.seeking).toContain('Collaboration')
const profile = await app.people.getProfileInfo()
if (!profile) throw new Error('No profile found')
const seeking = await getCardSeekingInfo(profile)
await expect(seeking).toContain('Collaboration')
})
/**
@@ -57,17 +61,19 @@ test.describe('when given valid input', () => {
await app.people.setDisplayFilter({filters: {Age: true}})
const totalProfiles = await app.people.profileCountLocator.textContent()
const profileResults = await app.people.getProfileInfo()
const profileAge = parseInt(profileResults.ageGender.match(/\d+/)?.[0] ?? '0')
const profile = await app.people.getProfileInfo()
const ageGender = await getCardAgeGender(profile)
if (!ageGender) throw new Error('Age not found')
const profileAge = parseInt(ageGender.match(/\d+/)?.[0] ?? '0')
const age = profileAge <= 60 ? profileAge : 60
console.log(profileResults, age)
console.log(profile, age)
await app.people.setAgeRangeFilter({min: String(age), max: String(age)})
const filterdProfiles = await app.people.profileCountLocator.textContent()
const filteredProfiles = await app.people.profileCountLocator.textContent()
if (!totalProfiles || !filterdProfiles) return
await expect(parseInt(totalProfiles)).not.toEqual(parseInt(filterdProfiles))
if (!totalProfiles || !filteredProfiles) return
await expect(parseInt(totalProfiles)).not.toEqual(parseInt(filteredProfiles))
})
test('show profiles with the correct gender', async ({app, signedOutAccount: account}) => {
@@ -185,36 +191,41 @@ test.describe('when given valid input', () => {
await app.home.clickPeopleLink()
await app.people.useSearch(TEST_USER_DISPLAY_NAME)
await sleep(1000)
const results = await app.people.getProfileInfo()
console.log(results)
const hideProfileButton = await results.profile.getByRole('button', {
const profile = await app.people.getProfileInfo()
if (!profile) throw new Error('Profile not found')
const name = await getCardName(profile)
console.log(profile)
const hideProfileButton = profile.getByRole('button', {
name: 'Hide this profile',
})
await expect(hideProfileButton).toBeVisible()
await hideProfileButton.click()
await expect(
app.page.getByText(`You won't see ${results.name} in your search results anymore.`),
app.page.getByText(`You won't see ${name} in your search results anymore.`),
).toBeVisible()
})
test('should be reversible using undo', async ({app, signedOutAccount: account}) => {
await app.signinWithEmail(account)
await app.home.clickPeopleLink()
const results = await app.people.getProfileInfo()
if (!results) return
const hideProfileButton = await results.profile.getByRole('button', {
await app.people.useSearch(TEST_USER_DISPLAY_NAME)
await sleep(1000)
const profile = await app.people.getProfileInfo()
if (!profile) throw new Error('Profile not found')
const name = await getCardName(profile)
const hideProfileButton = profile.getByRole('button', {
name: 'Hide this profile',
})
await expect(hideProfileButton).toBeVisible()
await hideProfileButton.click()
const hideProfileMessage = await app.page.getByText(
`You won't see ${results.name} in your search results anymore.`,
const hideProfileMessage = app.page.getByText(
`You won't see ${name} in your search results anymore.`,
)
await expect(hideProfileMessage).toBeVisible()
await app.people.page.getByRole('button', {name: 'Undo'}).click()
await expect(hideProfileMessage).not.toBeVisible()
const profile = await app.people.page.getByRole('heading', {name: `${results.name}`})
await expect(profile).toBeVisible()
const undoProfile = app.people.page.getByRole('heading', {name: `${name}`})
await expect(undoProfile).toBeVisible()
})
test('should be reversible using manage hidden profiles feature in settings', async ({
@@ -223,25 +234,29 @@ test.describe('when given valid input', () => {
}) => {
await app.signinWithEmail(account)
await app.home.clickPeopleLink()
const results = await app.people.getProfileInfo()
if (!results) return
const hideProfileButton = await results.profile.getByRole('button', {
await app.people.useSearch(TEST_USER_DISPLAY_NAME)
await sleep(1000)
const profile = await app.people.getProfileInfo()
if (!profile) throw new Error('Profile not found')
const name = await getCardName(profile)
if (!name) throw new Error('Name not found')
const hideProfileButton = profile.getByRole('button', {
name: 'Hide this profile',
})
await expect(hideProfileButton).toBeVisible()
await hideProfileButton.click()
const hideProfileMessage = await app.page.getByText(
`You won't see ${results.name} in your search results anymore.`,
const hideProfileMessage = app.page.getByText(
`You won't see ${name} in your search results anymore.`,
)
await expect(hideProfileMessage).toBeVisible()
await app.home.clickSettingsLink()
await app.settings.clickManageHiddenProfilesButton()
await app.settings.verifyHiddenProfiles([results.name])
await app.settings.unhideProfiles(results.name)
await app.settings.verifyHiddenProfiles([name])
await app.settings.unhideProfiles(name)
await app.settings.clickCloseButton()
await app.home.clickPeopleLink()
const profile = await app.people.page.getByRole('heading', {name: `${results.name}`})
await expect(profile).toBeVisible()
const undoProfile = app.people.page.getByRole('heading', {name: `${name}`})
await expect(undoProfile).toBeVisible()
})
})
@@ -252,7 +267,7 @@ test.describe('when given valid input', () => {
signedInAccount: sender,
signedOutAccount: receiver,
}) => {
const receiverApp = await app.contextManager.createContext()
const receiverApp = await app.contextManager!.createContext()
await receiverApp.signinWithEmail(receiver)
await app.home.clickMessagesLink()
@@ -269,7 +284,7 @@ test.describe('when given valid input', () => {
signedInAccount: sender,
signedOutAccount: receiver,
}) => {
const receiverApp = await app.contextManager.createContext()
const receiverApp = await app.contextManager!.createContext()
await receiverApp.signinWithEmail(receiver)
// To pass the min character limit for message intro (250 chars)