Changed POM/Fixture structure to use an app class to instantiate the page objects (#47)

* Added Database checks to the onboarding flow

* Added compatibility page setup
Added more compatibility questions

* Finished up the onboarding flow suite
Added compatibility question tests and verifications
Updated tests to cover Keywords and Headline changes recently made
Updated tests to cover all of the big5 personality traits

* .

* Fix: Merge conflict

* .

* Fix: Added fix for None discriptive error issue #36
Updated signUp.spec.ts to use new fixture
Updated Account information variable names
Deleted "deleteUserFixture.ts" as it was incorporated into the "base.ts" file

* Linting and Prettier

* Minor cleaning

* Organizing helper func

* Added Google account to the Onboarding flow

* Added account cleanup for google accounts

* Started work on Sign-in tests
Updated seedDatabase.ts to throw an error if the user already exists, to also add display names and usernames so they seedUser func acts like a normal basic user
Some organising of the google auth code

* Linting and Prettier

* Added checks to the deleteUser func to check if the accout exists
Added account deletion checks

* Linting and Prettier

* Added POM's for social and organisation page
Updated settings POM

* Formatting update, fixed homePage locator for signin

* .

* .

* .

* Coderabbitai fix's

* Fix

* Improve test utilities and stabilize onboarding flow tests

* Changes requested

* Seperated deletion tests from onboarding

* .

* Changed POM/Fixture structure to use an app class to instantiate the page objects

* Apply suggestion from @MartinBraquet

* Apply suggestion from @MartinBraquet

* Delete .vscode/settings.json

* Apply suggestion from @MartinBraquet

* Apply suggestions from code review

Co-authored-by: Martin Braquet <martin.braquet@gmail.com>

* Apply suggestion from @MartinBraquet

* Apply suggestion from @MartinBraquet

* Linting and Prettier

---------

Co-authored-by: MartinBraquet <martin.braquet@gmail.com>
This commit is contained in:
Okechi Jones-Williams
2026-04-04 20:11:46 +01:00
committed by GitHub
parent 5b6c30b987
commit 73487af964
13 changed files with 266 additions and 402 deletions

View File

@@ -17,7 +17,7 @@ reviews:
enabled: true
# Skip auto-review if PR title contains these keywords
ignore_title_keywords:
- "WIP"
- 'WIP'
# Don't auto-review draft PRs
drafts: false
# Only auto-review PRs targeting these branches
@@ -57,17 +57,17 @@ reviews:
# Exclude these paths from reviews (build artifacts and dependencies)
path_filters:
- "!**/node_modules/**" # npm dependencies
- "!**/android/**" # Native Android build files
- "!**/ios/**" # Native iOS build files
- "!**/.expo/**" # Expo build cache
- "!**/.expo-shared/**" # Expo shared config
- "!**/dist/**" # Build output
- '!**/node_modules/**' # npm dependencies
- '!**/android/**' # Native Android build files
- '!**/ios/**' # Native iOS build files
- '!**/.expo/**' # Expo build cache
- '!**/.expo-shared/**' # Expo shared config
- '!**/dist/**' # Build output
# Custom review instructions for specific file patterns
path_instructions:
# TypeScript/JavaScript files - main app code
- path: "**/*.{ts,tsx,js,jsx}"
- path: '**/*.{ts,tsx,js,jsx}'
instructions: |
General practices:
- Summarize the changes clearly.
@@ -78,7 +78,7 @@ reviews:
- Flag any hardcoded strings; they should be in the constants file.
- Check for edge cases like null values or empty arrays.
- Suggest performance optimizations where appropriate.
Mobile best practices:
- Proper use of hooks (useRouter, useFonts, useAssets)
- Accessibility: touch targets min 44x44, screen reader support
@@ -105,7 +105,7 @@ reviews:
const message = t('key', 'english string')
```
- path: "tests/e2e/**/*.ts"
- path: 'tests/e2e/**/*.ts'
instructions: |
Playwright E2E test guidelines for this repo:
- Page objects live in `tests/e2e/web/pages/`. Each class wraps one page/route, holds only `private readonly` Locators, and exposes action methods.

View File

@@ -316,7 +316,7 @@ describe('loadProfiles', () => {
})
describe('when an error occurs', () => {
it('throw if there is no compatability', async () => {
it('throw if there is no compatibility', async () => {
const props = {
orderBy: 'compatibility_score',
}

View File

@@ -348,7 +348,6 @@ jest.mock('path/to/module')
* This creates an object containing all named exports from ./path/to/module
*/
import * as mockModule from 'path/to/module'
;(mockModule.module as jest.Mock).mockResolvedValue(mockReturnValue)
```

View File

@@ -1,5 +1,6 @@
{
"compilerOptions": {
"rootDir": "../../",
"module": "commonjs",
"jsx": "react-jsx",
"moduleResolution": "node",

View File

@@ -1,5 +1,4 @@
import axios from 'axios'
import {config} from '../web/SPEC_CONFIG'
export async function firebaseLoginEmailPassword(

View File

@@ -1,29 +1,11 @@
import {test as base} from '@playwright/test'
import {AuthPage} from '../pages/AuthPage'
import {ComatibilityPage} from '../pages/compatibilityPage'
import {HomePage} from '../pages/homePage'
import {OnboardingPage} from '../pages/onboardingPage'
import {OrganizationPage} from '../pages/organizationPage'
import {ProfilePage} from '../pages/profilePage'
import {SettingsPage} from '../pages/settingsPage'
import {SignUpPage} from '../pages/signUpPage'
import {SocialPage} from '../pages/socialPage'
import {testAccounts, UserAccountInformation} from '../utils/accountInformation'
import {deleteUser} from '../utils/deleteUser'
import {getAuthAccountInfo} from '../utils/networkUtils'
import {App} from '../pages/app'
export const test = base.extend<{
homePage: HomePage
onboardingPage: OnboardingPage
signUpPage: SignUpPage
profilePage: ProfilePage
authPage: AuthPage
settingsPage: SettingsPage
socialPage: SocialPage
organizationPage: OrganizationPage
compatabilityPage: ComatibilityPage
cleanUpUsers: void
app: App
onboardingAccount: UserAccountInformation
fakerAccount: UserAccountInformation
specAccount: UserAccountInformation
@@ -62,41 +44,9 @@ export const test = base.extend<{
console.log('Cleaning up spec account...')
await deleteUser('Email/Password', account)
},
onboardingPage: async ({page}, use) => {
const onboardingPage = new OnboardingPage(page)
await use(onboardingPage)
},
homePage: async ({page}, use) => {
const homePage = new HomePage(page)
await use(homePage)
},
signUpPage: async ({page}, use) => {
const signUpPage = new SignUpPage(page)
await use(signUpPage)
},
authPage: async ({page}, use) => {
const authPage = new AuthPage(page)
await use(authPage)
},
profilePage: async ({page}, use) => {
const profilePage = new ProfilePage(page)
await use(profilePage)
},
compatabilityPage: async ({page}, use) => {
const compatibilityPage = new ComatibilityPage(page)
await use(compatibilityPage)
},
settingsPage: async ({page}, use) => {
const settingsPage = new SettingsPage(page)
await use(settingsPage)
},
socialPage: async ({page}, use) => {
const socialPage = new SocialPage(page)
await use(socialPage)
},
organizationPage: async ({page}, use) => {
const organizationPage = new OrganizationPage(page)
await use(organizationPage)
app: async ({page}, use) => {
const appPage = new App(page)
await use(appPage)
},
})

View File

@@ -1,47 +1,17 @@
import {test as base} from '@playwright/test'
import {AuthPage} from '../pages/AuthPage'
import {HomePage} from '../pages/homePage'
import {App} from '../pages/app'
import {testAccounts, UserAccountInformation} from '../utils/accountInformation'
import { OnboardingPage } from '../pages/onboardingPage'
import { SignUpPage } from '../pages/signUpPage'
import { ProfilePage } from '../pages/profilePage'
import { SettingsPage } from '../pages/settingsPage'
export const test = base.extend<{
homePage: HomePage
onboardingPage: OnboardingPage
signUpPage: SignUpPage
profilePage: ProfilePage
settingsPage: SettingsPage
authPage: AuthPage
app: App
dev_one_account: UserAccountInformation
fakerAccount: UserAccountInformation
googleAccountOne: UserAccountInformation
googleAccountTwo: UserAccountInformation
}>({
homePage: async ({page}, use) => {
const homePage = new HomePage(page)
await use(homePage)
},
onboardingPage: async ({page}, use) => {
const onboardingPage = new OnboardingPage(page)
await use(onboardingPage)
},
signUpPage: async ({page}, use) => {
const signUpPage = new SignUpPage(page)
await use(signUpPage)
},
profilePage: async ({page}, use) => {
const profilePage = new ProfilePage(page)
await use(profilePage)
},
settingsPage: async ({page}, use) => {
const settingsPage = new SettingsPage(page)
await use(settingsPage)
},
authPage: async ({page}, use) => {
const authPage = new AuthPage(page)
await use(authPage)
app: async ({page}, use) => {
const appPage = new App(page)
await use(appPage)
},
dev_one_account: async ({}, use) => {
const account = testAccounts.dev_one_account()

View File

@@ -0,0 +1,75 @@
import {Page} from '@playwright/test'
import {UserAccountInformation} from '../utils/accountInformation'
import {AuthPage} from './authPage'
import {ComatibilityPage} from './compatibilityPage'
import {HomePage} from './homePage'
import {OnboardingPage} from './onboardingPage'
import {OrganizationPage} from './organizationPage'
import {ProfilePage} from './profilePage'
import {SettingsPage} from './settingsPage'
import {SignUpPage} from './signUpPage'
import {SocialPage} from './socialPage'
export class App {
readonly auth: AuthPage
readonly compatibility: ComatibilityPage
readonly home: HomePage
readonly onboarding: OnboardingPage
readonly organization: OrganizationPage
readonly profile: ProfilePage
readonly settings: SettingsPage
readonly signUp: SignUpPage
readonly social: SocialPage
constructor(public readonly page: Page) {
this.auth = new AuthPage(page)
this.compatibility = new ComatibilityPage(page)
this.home = new HomePage(page)
this.onboarding = new OnboardingPage(page)
this.organization = new OrganizationPage(page)
this.profile = new ProfilePage(page)
this.settings = new SettingsPage(page)
this.signUp = new SignUpPage(page)
this.social = new SocialPage(page)
}
async deleteProfileFromSettings() {
await this.home.clickSettingsLink()
await this.settings.clickDeleteAccountButton()
await this.settings.fillDeleteAccountSurvey('Delete me')
await this.settings.clickDeleteAccountButton()
await this.home.verifyHomePageLinks()
}
async skipOnboardingHeadToProfile(account: UserAccountInformation) {
await this.onboarding.clickSkipOnboardingButton()
await this.signUp.fillDisplayName(account.display_name)
await this.signUp.fillUsername(account.username)
await this.signUp.clickNextButton()
await this.signUp.clickNextButton()
await this.profile.clickCloseButton()
await this.onboarding.clickRefineProfileButton()
}
async registerWithEmail(account: UserAccountInformation) {
await this.home.goToRegisterPage()
await this.auth.fillEmailField(account.email)
await this.auth.fillPasswordField(account.password)
await this.auth.clickSignUpWithEmailButton()
}
async signinWithEmail(accountOrEmail: UserAccountInformation | string, password?: string) {
const email = typeof accountOrEmail === 'string' ? accountOrEmail : accountOrEmail.email
const resolvedPassword = typeof accountOrEmail === 'string' ? password : accountOrEmail.password
if (!email || !resolvedPassword) {
throw new Error('Provide either an `account` or `email` and `password`.')
}
await this.home.goToSigninPage()
await this.auth.fillEmailField(email)
await this.auth.fillPasswordField(resolvedPassword)
await this.auth.clickSignInWithEmailButton()
}
}

View File

@@ -1,138 +1,133 @@
import {userInformationFromDb} from '../../utils/databaseUtils'
import {expect, test} from '../fixtures/base'
import {registerWithEmail, skipOnboardingHeadToProfile} from '../utils/testCleanupHelpers'
test.describe('when given valid input', () => {
test('should successfully complete the onboarding flow with email', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
app,
onboardingAccount,
}) => {
await registerWithEmail(homePage, authPage, onboardingAccount)
await onboardingPage.clickContinueButton() //First continue
await onboardingPage.clickContinueButton() //Second continue
await onboardingPage.clickGetStartedButton()
await signUpPage.fillDisplayName(onboardingAccount.display_name)
await signUpPage.fillUsername(onboardingAccount.username)
await signUpPage.clickNextButton()
await signUpPage.chooseGender(onboardingAccount.gender)
await signUpPage.fillAge(onboardingAccount.age)
await signUpPage.fillHeight({
await app.registerWithEmail(onboardingAccount)
await app.onboarding.clickContinueButton() //First continue
await app.onboarding.clickContinueButton() //Second continue
await app.onboarding.clickGetStartedButton()
await app.signUp.fillDisplayName(onboardingAccount.display_name)
await app.signUp.fillUsername(onboardingAccount.username)
await app.signUp.clickNextButton()
await app.signUp.chooseGender(onboardingAccount.gender)
await app.signUp.fillAge(onboardingAccount.age)
await app.signUp.fillHeight({
feet: onboardingAccount.height?.feet,
inches: onboardingAccount.height?.inches,
})
await signUpPage.fillEthnicity(onboardingAccount.ethnicity_origin)
await signUpPage.fillHeadline(onboardingAccount.headline)
await signUpPage.fillKeywords(onboardingAccount.keywords)
await signUpPage.fillInterestedInConnectingWith(onboardingAccount.interested_in)
await signUpPage.fillAgeRangeInterest(
await app.signUp.fillEthnicity(onboardingAccount.ethnicity_origin)
await app.signUp.fillHeadline(onboardingAccount.headline)
await app.signUp.fillKeywords(onboardingAccount.keywords)
await app.signUp.fillInterestedInConnectingWith(onboardingAccount.interested_in)
await app.signUp.fillAgeRangeInterest(
onboardingAccount.Interested_in_ages?.min,
onboardingAccount.Interested_in_ages?.max,
)
await signUpPage.setConnectionType(onboardingAccount.connection_type)
await signUpPage.setRelationshipStatus(onboardingAccount.relationship_status)
await signUpPage.setRelationshipStyle(onboardingAccount.relationship_style)
await signUpPage.fillCurrentNumberOfChildren(onboardingAccount.number_of_kids)
await signUpPage.setWantChildrenExpectation(onboardingAccount.children_expectation)
await signUpPage.setInterests(onboardingAccount.interests)
await signUpPage.setCauses(onboardingAccount.causes)
await signUpPage.setHighestEducationLevel(onboardingAccount.education_level)
await signUpPage.fillUniversity(onboardingAccount.university)
await signUpPage.fillJobTitle(onboardingAccount.job_title)
await signUpPage.fillCompany(onboardingAccount.company)
await signUpPage.setWorkArea(onboardingAccount.work_area)
await signUpPage.setPoliticalBeliefs(
await app.signUp.setConnectionType(onboardingAccount.connection_type)
await app.signUp.setRelationshipStatus(onboardingAccount.relationship_status)
await app.signUp.setRelationshipStyle(onboardingAccount.relationship_style)
await app.signUp.fillCurrentNumberOfChildren(onboardingAccount.number_of_kids)
await app.signUp.setWantChildrenExpectation(onboardingAccount.children_expectation)
await app.signUp.setInterests(onboardingAccount.interests)
await app.signUp.setCauses(onboardingAccount.causes)
await app.signUp.setHighestEducationLevel(onboardingAccount.education_level)
await app.signUp.fillUniversity(onboardingAccount.university)
await app.signUp.fillJobTitle(onboardingAccount.job_title)
await app.signUp.fillCompany(onboardingAccount.company)
await app.signUp.setWorkArea(onboardingAccount.work_area)
await app.signUp.setPoliticalBeliefs(
onboardingAccount.beliefs?.political?.belief,
onboardingAccount.beliefs?.political?.details,
)
await signUpPage.setReligiousBeliefs(
await app.signUp.setReligiousBeliefs(
onboardingAccount.beliefs?.religious?.belief,
onboardingAccount.beliefs?.religious?.details,
)
await signUpPage.setPersonalityType(onboardingAccount.personality_type)
await signUpPage.setOpennessPersonalityValue(
await app.signUp.setPersonalityType(onboardingAccount.personality_type)
await app.signUp.setOpennessPersonalityValue(
onboardingAccount.big_five_personality_traits?.openness,
)
await signUpPage.setAgreeablenessPersonalityValue(
await app.signUp.setAgreeablenessPersonalityValue(
onboardingAccount.big_five_personality_traits?.agreeableness,
)
await signUpPage.setConscientiousnessPersonalityValue(
await app.signUp.setConscientiousnessPersonalityValue(
onboardingAccount.big_five_personality_traits?.conscientiousness,
)
await signUpPage.setExtraversionPersonalityValue(
await app.signUp.setExtraversionPersonalityValue(
onboardingAccount.big_five_personality_traits?.extraversion,
)
await signUpPage.setNeuroticismPersonalityValue(
await app.signUp.setNeuroticismPersonalityValue(
onboardingAccount.big_five_personality_traits?.neuroticism,
)
await signUpPage.setDietType(onboardingAccount.diet)
await signUpPage.setIsSmoker(onboardingAccount.is_smoker)
await signUpPage.fillAlcoholPerMonth(onboardingAccount.alcohol_consumed_per_month)
await signUpPage.setLanguages(onboardingAccount.languages)
await signUpPage.addSocialMediaPlatform(onboardingAccount.social_media)
await signUpPage.fillBio(onboardingAccount.bio)
await signUpPage.clickNextButton()
await profilePage.clickCloseButton()
await onboardingPage.clickRefineProfileButton()
await profilePage.clickAnswerQuestionsButton()
const compatQuestionOne = await profilePage.answerCompatibilityQuestion(
await app.signUp.setDietType(onboardingAccount.diet)
await app.signUp.setIsSmoker(onboardingAccount.is_smoker)
await app.signUp.fillAlcoholPerMonth(onboardingAccount.alcohol_consumed_per_month)
await app.signUp.setLanguages(onboardingAccount.languages)
await app.signUp.addSocialMediaPlatform(onboardingAccount.social_media)
await app.signUp.fillBio(onboardingAccount.bio)
await app.signUp.clickNextButton()
await app.profile.clickCloseButton()
await app.onboarding.clickRefineProfileButton()
await app.profile.clickAnswerQuestionsButton()
const compatQuestionOne = await app.profile.answerCompatibilityQuestion(
onboardingAccount.compatibility,
)
await profilePage.clickNextCompatibilityQuestionButton()
await profilePage.clickSkipCompatibilityQuestionButton()
await profilePage.clickSkipCompatibilityQuestionButton()
await app.profile.clickNextCompatibilityQuestionButton()
await app.profile.clickSkipCompatibilityQuestionButton()
await app.profile.clickSkipCompatibilityQuestionButton()
await profilePage.clickCloseButton()
await app.profile.clickCloseButton()
//Verify information is correct
await profilePage.verifyDisplayName(onboardingAccount.display_name)
await profilePage.verifyHeadline(onboardingAccount.headline)
await profilePage.verifyKeywords(onboardingAccount.keywords)
await profilePage.verifyGenderLocationHeightAge(
await app.profile.verifyDisplayName(onboardingAccount.display_name)
await app.profile.verifyHeadline(onboardingAccount.headline)
await app.profile.verifyKeywords(onboardingAccount.keywords)
await app.profile.verifyGenderLocationHeightAge(
onboardingAccount.gender,
undefined,
onboardingAccount.height?.feet,
onboardingAccount.height?.inches,
onboardingAccount.age,
)
await profilePage.verifySeeking(
await app.profile.verifySeeking(
onboardingAccount.interested_in,
onboardingAccount.Interested_in_ages?.min,
onboardingAccount.Interested_in_ages?.max,
onboardingAccount.connection_type,
onboardingAccount.relationship_style,
)
await profilePage.verifyRelationshipStatus(onboardingAccount.relationship_status)
await profilePage.verifyCurrentNumberOfKids(onboardingAccount.number_of_kids)
await profilePage.verifyWantChildrenExpectation(onboardingAccount.children_expectation)
await profilePage.verifyInterests(onboardingAccount.interests)
await profilePage.verifyCauses(onboardingAccount.causes)
await profilePage.verifyEducationLevelAndUniversity(
await app.profile.verifyRelationshipStatus(onboardingAccount.relationship_status)
await app.profile.verifyCurrentNumberOfKids(onboardingAccount.number_of_kids)
await app.profile.verifyWantChildrenExpectation(onboardingAccount.children_expectation)
await app.profile.verifyInterests(onboardingAccount.interests)
await app.profile.verifyCauses(onboardingAccount.causes)
await app.profile.verifyEducationLevelAndUniversity(
onboardingAccount.education_level,
onboardingAccount.university,
)
await profilePage.verifyJobInformation(onboardingAccount.job_title, onboardingAccount.company)
await profilePage.verifyWorkArea(onboardingAccount.work_area)
await profilePage.verifyPoliticalBeliefs(
await app.profile.verifyJobInformation(onboardingAccount.job_title, onboardingAccount.company)
await app.profile.verifyWorkArea(onboardingAccount.work_area)
await app.profile.verifyPoliticalBeliefs(
onboardingAccount.beliefs?.political?.belief,
onboardingAccount.beliefs?.political?.details,
)
await profilePage.verifyReligiousBeliefs(
await app.profile.verifyReligiousBeliefs(
onboardingAccount.beliefs?.religious?.belief,
onboardingAccount.beliefs?.religious?.details,
)
await profilePage.verifyPersonalityType(onboardingAccount.personality_type)
await profilePage.verifyBigFivePersonalitySection(onboardingAccount.big_five_personality_traits)
await profilePage.verifyDiet(onboardingAccount.diet)
await profilePage.verifySmoker(onboardingAccount.is_smoker)
await profilePage.verifyDrinksPerMonth(onboardingAccount.alcohol_consumed_per_month)
await profilePage.verifyLanguages(onboardingAccount.languages)
await profilePage.verifySocialMedia(onboardingAccount.social_media)
await profilePage.verifyBio(onboardingAccount.bio)
await profilePage.verifyCompatibilityAnswers(compatQuestionOne)
await app.profile.verifyPersonalityType(onboardingAccount.personality_type)
await app.profile.verifyBigFivePersonalitySection(onboardingAccount.big_five_personality_traits)
await app.profile.verifyDiet(onboardingAccount.diet)
await app.profile.verifySmoker(onboardingAccount.is_smoker)
await app.profile.verifyDrinksPerMonth(onboardingAccount.alcohol_consumed_per_month)
await app.profile.verifyLanguages(onboardingAccount.languages)
await app.profile.verifySocialMedia(onboardingAccount.social_media)
await app.profile.verifyBio(onboardingAccount.bio)
await app.profile.verifyCompatibilityAnswers(compatQuestionOne)
//Verify Database Information
const dbInfo = await userInformationFromDb(onboardingAccount)
@@ -219,26 +214,22 @@ test.describe('when given valid input', () => {
})
test('should successfully complete the onboarding flow with google account', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
app,
googleAccountOne,
headless,
}) => {
test.skip(headless, 'Google popup auth test requires headed mode')
await homePage.goToRegisterPage()
await authPage.fillPasswordField('') //The test only passes when this is added...something is weird here
await authPage.signInToGoogleAccount(
await app.home.goToRegisterPage()
await app.auth.fillPasswordField('') //The test only passes when this is added...something is weird here
await app.auth.signInToGoogleAccount(
googleAccountOne.email,
googleAccountOne.display_name,
googleAccountOne.username,
)
await skipOnboardingHeadToProfile(onboardingPage, signUpPage, profilePage, googleAccountOne)
await app.skipOnboardingHeadToProfile(googleAccountOne)
//Verify displayed information is correct
await profilePage.verifyDisplayName(googleAccountOne.display_name)
await app.profile.verifyDisplayName(googleAccountOne.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(googleAccountOne)
@@ -247,19 +238,12 @@ test.describe('when given valid input', () => {
await expect(dbInfo.user.username).toContain(googleAccountOne.username)
})
test('should successfully skip the onboarding flow', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
fakerAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await skipOnboardingHeadToProfile(onboardingPage, signUpPage, profilePage, fakerAccount)
test('should successfully skip the onboarding flow', async ({app, fakerAccount}) => {
await app.registerWithEmail(fakerAccount)
await app.skipOnboardingHeadToProfile(fakerAccount)
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyDisplayName(fakerAccount.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(fakerAccount)
@@ -269,27 +253,23 @@ test.describe('when given valid input', () => {
})
test('should successfully enter optional information after completing flow', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
app,
fakerAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await skipOnboardingHeadToProfile(onboardingPage, signUpPage, profilePage, fakerAccount)
await profilePage.clickEditProfileButton()
await signUpPage.chooseGender(fakerAccount.gender)
await signUpPage.fillAge(fakerAccount.age)
await signUpPage.fillHeight({
await app.registerWithEmail(fakerAccount)
await app.skipOnboardingHeadToProfile(fakerAccount)
await app.profile.clickEditProfileButton()
await app.signUp.chooseGender(fakerAccount.gender)
await app.signUp.fillAge(fakerAccount.age)
await app.signUp.fillHeight({
feet: fakerAccount.height?.feet,
inches: fakerAccount.height?.inches,
})
await signUpPage.saveProfileChanges()
await app.signUp.saveProfileChanges()
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await profilePage.verifyGenderLocationHeightAge(
await app.profile.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyGenderLocationHeightAge(
fakerAccount.gender,
undefined,
fakerAccount.height?.feet,
@@ -308,31 +288,27 @@ test.describe('when given valid input', () => {
})
test('should successfully use the start answering option', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
app,
fakerAccount,
onboardingAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await onboardingPage.clickSkipOnboardingButton()
await signUpPage.fillDisplayName(fakerAccount.display_name)
await signUpPage.fillUsername(fakerAccount.username)
await signUpPage.clickNextButton()
await signUpPage.clickNextButton() //Skip optional information
await profilePage.clickStartAnsweringButton()
const compatTwoQuestionOne = await profilePage.answerCompatibilityQuestion(
await app.registerWithEmail(fakerAccount)
await app.onboarding.clickSkipOnboardingButton()
await app.signUp.fillDisplayName(fakerAccount.display_name)
await app.signUp.fillUsername(fakerAccount.username)
await app.signUp.clickNextButton()
await app.signUp.clickNextButton() //Skip optional information
await app.profile.clickStartAnsweringButton()
const compatTwoQuestionOne = await app.profile.answerCompatibilityQuestion(
onboardingAccount.compatibility,
)
await profilePage.clickNextCompatibilityQuestionButton()
await profilePage.clickCloseButton()
await onboardingPage.clickRefineProfileButton()
await app.profile.clickNextCompatibilityQuestionButton()
await app.profile.clickCloseButton()
await app.onboarding.clickRefineProfileButton()
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await profilePage.verifyCompatibilityAnswers(compatTwoQuestionOne)
await app.profile.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyCompatibilityAnswers(compatTwoQuestionOne)
//Verify database info
const dbInfo = await userInformationFromDb(fakerAccount)
@@ -342,29 +318,22 @@ test.describe('when given valid input', () => {
})
test.describe('should successfully complete the onboarding flow after using the back button', () => {
test("the first time it's an option", async ({
homePage,
authPage,
onboardingPage,
signUpPage,
profilePage,
fakerAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await onboardingPage.clickContinueButton()
await onboardingPage.clickBackButton()
await onboardingPage.clickContinueButton()
await onboardingPage.clickContinueButton()
await onboardingPage.clickGetStartedButton()
await signUpPage.fillDisplayName(fakerAccount.display_name)
await signUpPage.fillUsername(fakerAccount.username)
await signUpPage.clickNextButton()
await signUpPage.clickNextButton() //Skip optional information
await profilePage.clickCloseButton()
await onboardingPage.clickRefineProfileButton()
test("the first time it's an option", async ({app, fakerAccount}) => {
await app.registerWithEmail(fakerAccount)
await app.onboarding.clickContinueButton()
await app.onboarding.clickBackButton()
await app.onboarding.clickContinueButton()
await app.onboarding.clickContinueButton()
await app.onboarding.clickGetStartedButton()
await app.signUp.fillDisplayName(fakerAccount.display_name)
await app.signUp.fillUsername(fakerAccount.username)
await app.signUp.clickNextButton()
await app.signUp.clickNextButton() //Skip optional information
await app.profile.clickCloseButton()
await app.onboarding.clickRefineProfileButton()
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyDisplayName(fakerAccount.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(fakerAccount)
@@ -373,29 +342,22 @@ test.describe('when given valid input', () => {
await expect(dbInfo.user.username).toContain(fakerAccount.username)
})
test("the second time it's an option", async ({
homePage,
authPage,
onboardingPage,
signUpPage,
profilePage,
fakerAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await onboardingPage.clickContinueButton()
await onboardingPage.clickContinueButton()
await onboardingPage.clickBackButton()
await onboardingPage.clickContinueButton()
await onboardingPage.clickGetStartedButton()
await signUpPage.fillDisplayName(fakerAccount.display_name)
await signUpPage.fillUsername(fakerAccount.username)
await signUpPage.clickNextButton()
await signUpPage.clickNextButton() //Skip optional information
await profilePage.clickCloseButton()
await onboardingPage.clickRefineProfileButton()
test("the second time it's an option", async ({app, fakerAccount}) => {
await app.registerWithEmail(fakerAccount)
await app.onboarding.clickContinueButton()
await app.onboarding.clickContinueButton()
await app.onboarding.clickBackButton()
await app.onboarding.clickContinueButton()
await app.onboarding.clickGetStartedButton()
await app.signUp.fillDisplayName(fakerAccount.display_name)
await app.signUp.fillUsername(fakerAccount.username)
await app.signUp.clickNextButton()
await app.signUp.clickNextButton() //Skip optional information
await app.profile.clickCloseButton()
await app.onboarding.clickRefineProfileButton()
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyDisplayName(fakerAccount.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(fakerAccount)

View File

@@ -2,12 +2,6 @@ import {userInformationFromDb} from '../../utils/databaseUtils'
import {seedUser} from '../../utils/seedDatabase'
import {expect, test} from '../fixtures/signInFixture'
import {testAccounts} from '../utils/accountInformation'
import {
deleteProfileFromSettings,
registerWithEmail,
signinWithEmail,
skipOnboardingHeadToProfile,
} from '../utils/testCleanupHelpers'
//Seed the account
test.beforeAll(async () => {
@@ -26,30 +20,21 @@ test.beforeAll(async () => {
})
test.describe('when given valid input', () => {
test('should be able to sign in to an available account', async ({
homePage,
authPage,
dev_one_account,
}) => {
await signinWithEmail(homePage, authPage, dev_one_account)
await homePage.goToHomePage()
await homePage.verifySignedInHomePage(dev_one_account.display_name)
test('should be able to sign in to an available account', async ({app, dev_one_account}) => {
await app.signinWithEmail(dev_one_account)
await app.home.goToHomePage()
await app.home.verifySignedInHomePage(dev_one_account.display_name)
})
test('should successfully delete an account created via email and password', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
settingsPage,
app,
fakerAccount,
}) => {
await registerWithEmail(homePage, authPage, fakerAccount)
await skipOnboardingHeadToProfile(onboardingPage, signUpPage, profilePage, fakerAccount)
await app.registerWithEmail(fakerAccount)
await app.skipOnboardingHeadToProfile(fakerAccount)
//Verify displayed information is correct
await profilePage.verifyDisplayName(fakerAccount.display_name)
await app.profile.verifyDisplayName(fakerAccount.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(fakerAccount)
@@ -57,31 +42,26 @@ test.describe('when given valid input', () => {
await expect(dbInfo.user.name).toContain(fakerAccount.display_name)
await expect(dbInfo.user.username).toContain(fakerAccount.username)
await deleteProfileFromSettings(homePage, settingsPage)
await app.deleteProfileFromSettings()
})
test('should successfully delete an account created via google auth', async ({
homePage,
onboardingPage,
signUpPage,
authPage,
profilePage,
settingsPage,
app,
googleAccountTwo,
headless,
}) => {
test.skip(headless, 'Google popup auth test requires headed mode')
await homePage.goToRegisterPage()
await authPage.fillPasswordField('') //The test only passes when this is added...something is weird here
await authPage.signInToGoogleAccount(
await app.home.goToRegisterPage()
await app.auth.fillPasswordField('') //The test only passes when this is added...something is weird here
await app.auth.signInToGoogleAccount(
googleAccountTwo.email,
googleAccountTwo.display_name,
googleAccountTwo.username,
)
await skipOnboardingHeadToProfile(onboardingPage, signUpPage, profilePage, googleAccountTwo)
await app.skipOnboardingHeadToProfile(googleAccountTwo)
//Verify displayed information is correct
await profilePage.verifyDisplayName(googleAccountTwo.display_name)
await app.profile.verifyDisplayName(googleAccountTwo.display_name)
//Verify database info
const dbInfo = await userInformationFromDb(googleAccountTwo)
@@ -89,18 +69,17 @@ test.describe('when given valid input', () => {
await expect(dbInfo.user.name).toContain(googleAccountTwo.display_name)
await expect(dbInfo.user.username).toContain(googleAccountTwo.username)
await deleteProfileFromSettings(homePage, settingsPage)
await app.deleteProfileFromSettings()
})
})
test.describe('when given invalid input', () => {
test('should not be able to sign in to an available account', async ({
homePage,
authPage,
app,
dev_one_account,
page,
}) => {
await signinWithEmail(homePage, authPage, dev_one_account.email, 'ThisPassword')
await app.signinWithEmail(dev_one_account.email, 'ThisPassword')
await expect(
page.getByText('Failed to sign in with your email and password', {exact: true}),
).toBeVisible()

View File

@@ -1,5 +1,4 @@
import {expect, test} from '../fixtures/base'
import {registerWithEmail} from '../utils/testCleanupHelpers'
// test.describe('when given valid input', () => {
// test('placeholder', async () => {})
@@ -8,31 +7,25 @@ import {registerWithEmail} from '../utils/testCleanupHelpers'
test.describe('when an error occurs', () => {
test('should disable the button "Next" when the display name field is empty', async ({
specAccount,
homePage,
authPage,
onboardingPage,
signUpPage,
app,
}) => {
await registerWithEmail(homePage, authPage, specAccount)
await onboardingPage.clickSkipOnboardingButton()
await signUpPage.fillDisplayName('')
await signUpPage.fillUsername(specAccount.username)
await signUpPage.verifyDisplayNameError()
await expect(signUpPage.nextButtonLocator).toBeDisabled()
await app.registerWithEmail(specAccount)
await app.onboarding.clickSkipOnboardingButton()
await app.signUp.fillDisplayName('')
await app.signUp.fillUsername(specAccount.username)
await app.signUp.verifyDisplayNameError()
await expect(app.signUp.nextButtonLocator).toBeDisabled()
})
test('should disable the button "Next" when the username field is empty', async ({
specAccount,
homePage,
authPage,
onboardingPage,
signUpPage,
app,
}) => {
await registerWithEmail(homePage, authPage, specAccount)
await onboardingPage.clickSkipOnboardingButton()
await signUpPage.fillDisplayName(specAccount.display_name)
await signUpPage.fillUsername('')
await signUpPage.verifyUsernameError()
await expect(signUpPage.nextButtonLocator).toBeDisabled()
await app.registerWithEmail(specAccount)
await app.onboarding.clickSkipOnboardingButton()
await app.signUp.fillDisplayName(specAccount.display_name)
await app.signUp.fillUsername('')
await app.signUp.verifyUsernameError()
await expect(app.signUp.nextButtonLocator).toBeDisabled()
})
})

View File

@@ -1,64 +0,0 @@
import {AuthPage} from '../pages/AuthPage'
import {HomePage} from '../pages/homePage'
import { OnboardingPage } from '../pages/onboardingPage'
import { ProfilePage } from '../pages/profilePage'
import { SettingsPage } from '../pages/settingsPage'
import { SignUpPage } from '../pages/signUpPage'
import {UserAccountInformation} from '../utils/accountInformation'
export async function registerWithEmail(
homePage: HomePage,
authPage: AuthPage,
account: UserAccountInformation,
) {
await homePage.goToRegisterPage()
await authPage.fillEmailField(account.email)
await authPage.fillPasswordField(account.password)
await authPage.clickSignUpWithEmailButton()
}
export async function signinWithEmail(
homePage: HomePage,
authPage: AuthPage,
accountOrEmail: UserAccountInformation | string,
password?: string,
) {
const email = typeof accountOrEmail === 'string' ? accountOrEmail : accountOrEmail.email
const resolvedPassword = typeof accountOrEmail === 'string' ? password : accountOrEmail.password
if (!email || !resolvedPassword) {
throw new Error('Provide either an `account` or `email` and `password`.')
}
await homePage.goToSigninPage()
await authPage.fillEmailField(email)
await authPage.fillPasswordField(resolvedPassword)
await authPage.clickSignInWithEmailButton()
}
export async function skipOnboardingHeadToProfile(
onboardingPage: OnboardingPage,
signUpPage: SignUpPage,
profilePage: ProfilePage,
account: UserAccountInformation,
) {
await onboardingPage.clickSkipOnboardingButton()
await signUpPage.fillDisplayName(account.display_name)
await signUpPage.fillUsername(account.username)
await signUpPage.clickNextButton()
await signUpPage.clickNextButton()
await profilePage.clickCloseButton()
await onboardingPage.clickRefineProfileButton()
}
export async function deleteProfileFromSettings(
homePage: HomePage,
settingsPage: SettingsPage,
) {
await homePage.clickSettingsLink()
await settingsPage.clickDeleteAccountButton()
await settingsPage.fillDeleteAccountSurvey('Delete me')
await settingsPage.clickDeleteAccountButton()
await homePage.verifyHomePageLinks()
}