@@ -14,6 +14,7 @@ import {
1414} from 'common/choices'
1515
1616import { MinMaxNumbers } from '../utils/accountInformation'
17+ import { optionChip } from '../utils/optionChip'
1718
1819export type BackgroundFilter = {
1920 location ?: string
@@ -94,6 +95,8 @@ export class PeoplePage {
9495 private readonly searchBox : Locator
9596 private readonly savedPeopleButton : Locator
9697 private readonly profileCount : Locator
98+ private readonly filtersButton : Locator
99+ private readonly filtersPanel : Locator
97100 private readonly resetFilters : Locator
98101 private readonly yourFiltersCheckbox : Locator
99102 private readonly incompleteProfilesCheckbox : Locator
@@ -130,6 +133,7 @@ export class PeoplePage {
130133 private readonly profileStar : Locator
131134 private readonly profileMessage : Locator
132135 private readonly messageInput : Locator
136+ private readonly messageSubmit : Locator
133137 private readonly profileName : Locator
134138 private readonly profileAgeGender : Locator
135139 private readonly profileSeeking : Locator
@@ -141,32 +145,34 @@ export class PeoplePage {
141145 this . searchBox = page . getByRole ( 'textbox' , { name : 'Search anything...' } )
142146 this . savedPeopleButton = page . getByRole ( 'button' , { name : 'Saved People' } )
143147 this . profileCount = page . getByTestId ( 'people-profile-count' )
148+ this . filtersButton = page . getByTestId ( 'open-filters-button' )
149+ this . filtersPanel = page . getByTestId ( 'people-filters' )
144150 this . resetFilters = page . getByRole ( 'button' , { name : 'Reset filters' } )
145151 this . yourFiltersCheckbox = page . getByText ( 'Your filters' , { exact : true } )
146152 this . incompleteProfilesCheckbox = page . getByText ( 'Include incomplete profiles' , { exact : true } )
147- this . connectionTypeDropdown = page . getByRole ( 'button' , { name : 'Any connection ' } )
148- this . locationDropdown = page . getByRole ( 'button' , { name : 'Living anywhere ' } )
149- this . ageRangeDropdown = page . getByRole ( 'button' , { name : 'Any age ' } )
150- this . genderDropdown = page . getByRole ( 'button' , { name : 'Any gender ' } )
153+ this . connectionTypeDropdown = page . getByRole ( 'button' , { name : 'Connection ' } )
154+ this . locationDropdown = page . getByRole ( 'button' , { name : 'Location ' } )
155+ this . ageRangeDropdown = page . getByRole ( 'button' , { name : 'Age ' } )
156+ this . genderDropdown = page . getByRole ( 'button' , { name : 'Gender ' } )
151157 this . backgroundDropdown = page . getByRole ( 'button' , { name : 'Background' } )
152- this . backgroundLocation = page . getByRole ( 'button' , { name : 'Grew up anywhere ' } )
153- this . backgroundEducation = page . getByText ( 'Any education ' , { exact : true } )
154- this . backgroundWork = page . getByText ( 'Any work ' , { exact : true } )
158+ this . backgroundLocation = page . getByRole ( 'button' , { name : 'Grew up' } )
159+ this . backgroundEducation = page . getByText ( 'Education ' , { exact : true } )
160+ this . backgroundWork = page . getByText ( 'Work ' , { exact : true } )
155161 this . lifestyleDropdown = page . getByRole ( 'button' , { name : 'Lifestyle' } )
156- this . lifestyleInterests = page . getByRole ( 'button' , { name : 'Any interests ' } )
157- this . lifestyleCauses = page . getByRole ( 'button' , { name : 'Any causes ' } )
158- this . lifestyleDiet = page . getByRole ( 'button' , { name : 'Any diet ' } )
159- this . lifestyleAlcohol = page . getByRole ( 'button' , { name : 'Any drinks ' } )
162+ this . lifestyleInterests = page . getByRole ( 'button' , { name : 'Interests ' } )
163+ this . lifestyleCauses = page . getByRole ( 'button' , { name : 'Causes ' } )
164+ this . lifestyleDiet = page . getByRole ( 'button' , { name : 'Diet ' } )
165+ this . lifestyleAlcohol = page . getByRole ( 'button' , { name : 'Drinks ' } )
160166 this . lifestyleSmoker = page . getByTestId ( 'lifestyle-smoker' )
161- this . lifestylePsychedelics = page . getByRole ( 'button' , { name : 'Any psychedelics ' } )
162- this . lifestyleCannabis = page . getByRole ( 'button' , { name : 'Any cannabis ' } )
163- this . lifestyleLanguages = page . getByRole ( 'button' , { name : 'Any language ' } )
167+ this . lifestylePsychedelics = page . getByRole ( 'button' , { name : 'Psychedelics ' } )
168+ this . lifestyleCannabis = page . getByRole ( 'button' , { name : 'Cannabis ' } )
169+ this . lifestyleLanguages = page . getByRole ( 'button' , { name : 'Language ' } )
164170 this . valuesAndBeliefsDropdown = page . getByRole ( 'button' , { name : 'Values & Beliefs' } )
165- this . valuesAndBeliefsPolitics = page . getByRole ( 'button' , { name : 'Any politics ' } )
166- this . valuesAndBeliefsReligion = page . getByRole ( 'button' , { name : 'Any religion ' } )
171+ this . valuesAndBeliefsPolitics = page . getByRole ( 'button' , { name : 'Politics ' } )
172+ this . valuesAndBeliefsReligion = page . getByRole ( 'button' , { name : 'Religion ' } )
167173 this . personalityDropdown = page . getByRole ( 'button' , { name : 'Personality' } )
168- this . personalityMbti = page . getByRole ( 'button' , { name : 'Any MBTI' } )
169- this . personalityBigFive = page . getByRole ( 'button' , { name : 'Any Big 5' } )
174+ this . personalityMbti = page . getByRole ( 'button' , { name : 'MBTI' } )
175+ this . personalityBigFive = page . getByRole ( 'button' , { name : 'Big 5' } )
170176 this . advancedDropdown = page . getByRole ( 'button' , { name : 'Advanced' } )
171177 this . advancedActive = page . getByTestId ( 'advanced-active' )
172178 this . advancedPhotos = page . getByText ( 'Photos' , { exact : true } )
@@ -177,6 +183,7 @@ export class PeoplePage {
177183 this . profileStar = page . getByTestId ( 'star-profile-button' )
178184 this . profileMessage = page . getByTestId ( 'message-profile-button' )
179185 this . messageInput = page . locator ( '.tiptap' )
186+ this . messageSubmit = page . getByTestId ( 'send-message-submit' )
180187 this . profileName = page . getByTestId ( 'people-profile-name' )
181188 this . profileAgeGender = page . getByTestId ( 'people-profile-age-gender' )
182189 this . profileSeeking = page . getByTestId ( 'people-profile-seeking' )
@@ -249,11 +256,16 @@ export class PeoplePage {
249256 }
250257 }
251258
259+ /** See {@link optionChip} — filter options are chips, not clickable checkboxes. */
260+ optionChip ( label : string ) : Locator {
261+ return optionChip ( this . page , label )
262+ }
263+
252264 async selectOption ( trigger : Locator , label : string ) {
253265 await expect ( trigger ) . toBeVisible ( )
254266 await trigger . click ( )
255267
256- const option = this . page . getByLabel ( label , { exact : true } )
268+ const option = this . optionChip ( label )
257269 await expect ( option ) . toBeVisible ( )
258270 await option . click ( )
259271 }
@@ -274,22 +286,44 @@ export class PeoplePage {
274286 await this . page . waitForTimeout ( 1000 )
275287 }
276288
289+ /**
290+ * The filters panel starts closed, and the "Filters" button toggles it — so clicking it
291+ * unconditionally would close an already-open panel. Everything below that reaches into the panel
292+ * calls this first; it is a no-op when the panel is already open.
293+ */
294+ async openFilters ( ) {
295+ if ( await this . filtersPanel . isVisible ( ) ) return
296+ await expect ( this . filtersButton ) . toBeVisible ( )
297+ await this . filtersButton . click ( )
298+ await expect ( this . filtersPanel ) . toBeVisible ( )
299+ }
300+
301+ async closeFilters ( ) {
302+ if ( ! ( await this . filtersPanel . isVisible ( ) ) ) return
303+ await this . filtersButton . click ( )
304+ await expect ( this . filtersPanel ) . not . toBeVisible ( )
305+ }
306+
277307 async resetFilter ( ) {
308+ await this . openFilters ( )
278309 await expect ( this . resetFilters ) . toBeVisible ( )
279310 await this . resetFilters . click ( )
280311 }
281312
282313 async setYourFilters ( ) {
314+ await this . openFilters ( )
283315 await expect ( this . yourFiltersCheckbox ) . toBeVisible ( )
284316 await this . yourFiltersCheckbox . click ( )
285317 }
286318
287319 async setIncludeIncompleteProfiles ( ) {
320+ await this . openFilters ( )
288321 await expect ( this . incompleteProfilesCheckbox ) . toBeVisible ( )
289322 await this . incompleteProfilesCheckbox . click ( )
290323 }
291324
292325 async setConnectionTypeFilter ( connectionType : ConnectionTypeTuple ) {
326+ await this . openFilters ( )
293327 await this . selectOption ( this . connectionTypeDropdown , connectionType [ 0 ] )
294328 // await expect(this.connectionTypeDropdown).toBeVisible()
295329 // await this.connectionTypeDropdown.click()
@@ -298,19 +332,22 @@ export class PeoplePage {
298332 }
299333
300334 async setLocationFilter ( location : string ) {
335+ await this . openFilters ( )
301336 await expect ( this . locationDropdown ) . toBeVisible ( )
302337 await this . locationDropdown . click ( )
303338 await expect ( this . page . getByRole ( 'textbox' , { name : 'Search city...' } ) ) . toBeVisible ( )
304339 await this . page . getByRole ( 'textbox' , { name : 'Search city...' } ) . fill ( location )
305340 }
306341
307342 async setAgeRangeFilter ( ageRange : MinMaxNumbers ) {
343+ await this . openFilters ( )
308344 await expect ( this . ageRangeDropdown ) . toBeVisible ( )
309345 await this . ageRangeDropdown . click ( )
310346 await this . sliderHelper ( ageRange )
311347 }
312348
313349 async setGenderTypeFilter ( genderType : InterestedInGenderTuple ) {
350+ await this . openFilters ( )
314351 await this . selectOption ( this . genderDropdown , genderType [ 0 ] )
315352 // await expect(this.genderDropdown).toBeVisible()
316353 // await this.genderDropdown.click()
@@ -319,6 +356,7 @@ export class PeoplePage {
319356 }
320357
321358 async setBackgroundFilter ( background : BackgroundFilter ) {
359+ await this . openFilters ( )
322360 await expect ( this . backgroundDropdown ) . toBeVisible ( )
323361 await this . backgroundDropdown . click ( )
324362 if ( background . location ) {
@@ -330,19 +368,22 @@ export class PeoplePage {
330368 if ( background . education ) {
331369 await expect ( this . backgroundEducation ) . toBeVisible ( )
332370 await this . backgroundEducation . click ( )
333- await expect ( this . page . getByLabel ( background . education [ 0 ] , { exact : true } ) ) . toBeVisible ( )
334- await this . page . getByLabel ( background . education [ 0 ] , { exact : true } ) . click ( )
371+ const education = this . optionChip ( background . education [ 0 ] )
372+ await expect ( education ) . toBeVisible ( )
373+ await education . click ( )
335374 }
336375
337376 if ( background . work ) {
338377 await expect ( this . backgroundWork ) . toBeVisible ( )
339378 await this . backgroundWork . click ( )
340- await expect ( this . page . getByLabel ( background . work , { exact : true } ) ) . toBeVisible ( )
341- await this . page . getByLabel ( background . work , { exact : true } ) . click ( )
379+ const work = this . optionChip ( background . work )
380+ await expect ( work ) . toBeVisible ( )
381+ await work . click ( )
342382 }
343383 }
344384
345385 async setLifestyleFilter ( lifestyle : LifestyleFilter ) {
386+ await this . openFilters ( )
346387 await expect ( this . lifestyleDropdown ) . toBeVisible ( )
347388 await this . lifestyleDropdown . click ( )
348389
@@ -370,6 +411,7 @@ export class PeoplePage {
370411 }
371412
372413 async setValuesAndBeliefsFilter ( values : BeliefsFilter ) {
414+ await this . openFilters ( )
373415 await expect ( this . valuesAndBeliefsDropdown ) . toBeVisible ( )
374416 await this . valuesAndBeliefsDropdown . click ( )
375417
@@ -380,6 +422,7 @@ export class PeoplePage {
380422 }
381423
382424 async setPersonalityFilter ( personality : PersonalityFilter ) {
425+ await this . openFilters ( )
383426 await expect ( this . personalityDropdown ) . toBeVisible ( )
384427 await this . personalityDropdown . click ( )
385428
@@ -421,6 +464,7 @@ export class PeoplePage {
421464 }
422465
423466 async setAdvancedFilter ( advanced : AdvancedFilter ) {
467+ await this . openFilters ( )
424468 await expect ( this . advancedDropdown ) . toBeVisible ( )
425469 await this . advancedDropdown . click ( )
426470
@@ -436,6 +480,7 @@ export class PeoplePage {
436480 }
437481
438482 async setDisplayFilter ( display : DisplayFilter ) {
483+ await this . openFilters ( )
439484 await expect ( this . displayDropdown ) . toBeVisible ( )
440485 await this . displayDropdown . click ( )
441486
@@ -489,13 +534,21 @@ export class PeoplePage {
489534 for ( let i = 0 ; i < profiles . length ; i ++ ) {
490535 const profileName = await profiles [ i ] . getByTestId ( 'people-profile-name' ) . textContent ( )
491536 if ( profileName ?. toLowerCase ( ) === displayName . toLowerCase ( ) ) {
492- await profiles [ i ] . getByTestId ( 'message-profile-button' ) . click ( )
537+ const card = profiles [ i ]
538+ // Card actions are revealed on hover (opacity-0 until lg:group-hover), so hover the card
539+ // before reaching for the button rather than relying on the click's implicit hover.
540+ await card . hover ( )
541+ await card . getByTestId ( 'message-profile-button' ) . click ( )
493542 await expect ( this . messageInput ) . toBeVisible ( )
494543 await this . messageInput . fill ( message )
495- await this . page . getByTestId ( 'conversation-message-submit' ) . click ( )
544+ // The modal composer passes `hideSubmitButton` and renders its own send control in a pinned
545+ // footer, so this is `send-message-submit` — not the `conversation-message-submit` used by
546+ // the in-conversation composer on the messages page.
547+ await this . messageSubmit . click ( )
496548 return
497549 }
498550 }
551+ throw new Error ( `No profile card found for ${ displayName } ` )
499552 }
500553
501554 async verifySavedPerson ( displayName : string | null | undefined ) {
0 commit comments