Skip to content

Commit 1994697

Browse files
Adding onboarding E2E foundations and first tests (#30)
* . * Centralizing config details * Added data-testId attributes where necessary and started the onboarding flow scaffolding * Continued onboarding test scaffolding * Continued work on tests for the Onboarding flow * . * Updated "Want kids" options to be less flaky Updated playwright.config so that expect timeout matching test timeout * Continued updating front-end scaffolding * . * . * . * . * Updated fixture function deleteUser: to also remove the database user information * Rm * Fix * Fixes --------- Co-authored-by: MartinBraquet <martin.braquet@gmail.com>
1 parent 1c26b63 commit 1994697

27 files changed

Lines changed: 3738 additions & 2313 deletions

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,8 @@
7474
"@capacitor/status-bar": "7.0.3",
7575
"@capawesome/capacitor-live-update": "7.2.2",
7676
"@capgo/capacitor-social-login": "7.14.9",
77-
"@playwright/test": "1.55.0",
78-
"colorette": "2.0.20",
79-
"prismjs": "1.30.0",
77+
"colorette": "^2.0.20",
78+
"prismjs": "^1.30.0",
8079
"react": "18.2.0",
8180
"react-dom": "18.2.0",
8281
"react-markdown": "10.1.0",
@@ -88,10 +87,11 @@
8887
"@capacitor/assets": "3.0.5",
8988
"@capacitor/cli": "7.4.4",
9089
"@faker-js/faker": "10.1.0",
91-
"@testing-library/dom": "10.4.1",
92-
"@testing-library/jest-dom": "6.8.0",
93-
"@testing-library/react": "16.3.0",
94-
"@testing-library/user-event": "14.6.1",
90+
"@playwright/test": "1.58.2",
91+
"@testing-library/dom": "^10.0.0",
92+
"@testing-library/jest-dom": "^6.6.4",
93+
"@testing-library/react": "^16.3.0",
94+
"@testing-library/user-event": "^14.6.1",
9595
"@types/jest": "29.2.4",
9696
"@types/node": "20.12.11",
9797
"@typescript-eslint/eslint-plugin": "^8",

playwright.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@ export default defineConfig({
2727
// },
2828
],
2929
timeout: 60000,
30+
expect: {
31+
timeout: 120000,
32+
},
3033

3134
});

scripts/setup-auth.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import axios from 'axios';
22
import { config } from '../tests/e2e/web/SPEC_CONFIG.js';
33

44
async function createAuth() {
5-
const base = 'http://localhost:9099/identitytoolkit.googleapis.com/v1';
5+
// const base = 'http://localhost:9099/identitytoolkit.googleapis.com/v1';
66

7-
await axios.post(`${base}/accounts:signUp?key=fake-api-key`, {
7+
await axios.post(`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.SIGNUP}`, {
88
email: config.USERS.DEV_1.EMAIL,
99
password: config.USERS.DEV_1.PASSWORD,
1010
returnSecureToken: true

tests/e2e/backend/utils/database.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ class DatabaseTestingUtilities {
77
`;
88
const userResults = await page.db.query(queryUserById,[name])
99
return userResults[0]
10-
}
10+
};
1111

1212
findProfileById = async (page: any, user_id: string) => {
1313
const queryProfileById = `
@@ -20,8 +20,8 @@ class DatabaseTestingUtilities {
2020
`;
2121
const profileResults = await page.db.query(queryProfileById,[user_id])
2222
return profileResults[0]
23-
}
23+
};
2424

25-
}
25+
};
2626

2727
export const databaseUtils = new DatabaseTestingUtilities();

tests/e2e/web/SPEC_CONFIG.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
export const config = {
22
BASE_URL: 'http://localhost:3000',
3-
3+
FIREBASE_URL: {
4+
BASE: 'http://localhost:9099/identitytoolkit.googleapis.com/v1',
5+
SIGNUP: '/accounts:signUp?key=fake-api-key',
6+
SIGN_IN_PASSWORD: '/accounts:signInWithPassword?key=fake-api-key',
7+
DELETE: '/accounts:delete?key=fake-api-key',
8+
},
49
USERS: {
510
DEV_1: {
611
EMAIL: 'dev_1@compass.com',
@@ -10,6 +15,10 @@ export const config = {
1015
EMAIL: 'dev_2@compass.com',
1116
PASSWORD: 'dev_2Password',
1217
},
18+
ONBOARDING: {
19+
EMAIL: 'onboarding@compass.com',
20+
PASSWORD: 'compassConnections1!',
21+
},
1322
SPEC: {
1423
EMAIL: 'spec@compass.com',
1524
PASSWORD: 'compassConnections1!',

tests/e2e/web/fixtures/base.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { test as base } from "@playwright/test";
2+
import { deleteUser } from "../utils/deleteUser";
3+
import { onboarding, OnboardingUser } from "../utils/accountInformation";
4+
import { OnboardingPage } from "../pages/onboardingPage";
5+
import { HomePage } from "../pages/homePage";
6+
import { ProfilePage } from "../pages/profilePage";
7+
import { SignUpPage } from "../pages/signUpPage";
8+
import { AuthPage } from "../pages/AuthPage";
9+
10+
export const test = base.extend<{
11+
homePage: HomePage,
12+
onboardingPage: OnboardingPage,
13+
signUpPage: SignUpPage,
14+
profilePage: ProfilePage,
15+
authPage: AuthPage,
16+
cleanUpUsers: void;
17+
testAccount: OnboardingUser
18+
fakerAccount: OnboardingUser
19+
}>({
20+
testAccount: async({}, use) => {
21+
await use(onboarding.account_one)
22+
},
23+
fakerAccount: async({}, use) => {
24+
await use(onboarding.faker_account)
25+
},
26+
onboardingPage: async ({page}, use) => {
27+
const onboardingPage = new OnboardingPage(page);
28+
await use(onboardingPage);
29+
},
30+
homePage: async ({page}, use) => {
31+
const homePage = new HomePage(page);
32+
await use(homePage);
33+
},
34+
signUpPage: async ({page}, use) => {
35+
const signUpPage = new SignUpPage(page);
36+
await use(signUpPage);
37+
},
38+
authPage: async ({page}, use) => {
39+
const authPage = new AuthPage(page);
40+
await use(authPage);
41+
},
42+
profilePage: async ({page}, use) => {
43+
const profilePage = new ProfilePage(page);
44+
await use(profilePage);
45+
},
46+
cleanUpUsers: [
47+
async ({ }, use) => {
48+
await use();
49+
await deleteUser(onboarding.account_one.email, onboarding.account_one.password);
50+
await deleteUser(onboarding.faker_account.email, onboarding.faker_account.password);
51+
},
52+
{ auto: true },
53+
],
54+
});
55+
56+
export { expect } from "@playwright/test"

tests/e2e/web/fixtures/deleteUserFixture.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import {test as base} from '@playwright/test';
22
import axios from 'axios';
33
import {config} from '../SPEC_CONFIG';
44

5-
const baseUrl = 'http://localhost:9099/identitytoolkit.googleapis.com/v1';
5+
// const baseUrl = 'http://localhost:9099/identitytoolkit.googleapis.com/v1';
66

77
async function deleteUser(email: string, password: string) {
88
try {
99
const login = await axios.post(
10-
`${baseUrl}/accounts:signInWithPassword?key=fake-api-key`,
10+
`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.SIGN_IN_PASSWORD}`,
1111
{
1212
email,
1313
password,
@@ -16,7 +16,7 @@ async function deleteUser(email: string, password: string) {
1616
);
1717

1818
await axios.post(
19-
`${baseUrl}/accounts:delete?key=fake-api-key`,
19+
`${config.FIREBASE_URL.BASE}${config.FIREBASE_URL.DELETE}`,
2020
{ idToken: login.data.idToken }
2121
);
2222
} catch (err: any) {

tests/e2e/web/pages/AuthPage.ts

Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,54 @@
11
import { expect, Locator, Page } from '@playwright/test';
22

33
//sets up of all the functions that signin tests will use.
4-
export class AuthPage{
5-
private readonly signInLink: Locator;
6-
private readonly signUpButton: Locator;
7-
private readonly emailField: Locator;
8-
private readonly passwordField: Locator;
9-
private readonly signInWithEmailButton: Locator;
10-
private readonly signInWithGoogleButton: Locator;
11-
private readonly signUpWithEmailButton: Locator;
12-
13-
constructor(public readonly page: Page) {
14-
this.signInLink=page.getByRole('link', { name: 'Sign in' });
15-
this.signUpButton=page.getByRole('button', {name: 'Sign up'});
16-
this.emailField=page.getByLabel('Email');
17-
this.passwordField=page.getByLabel('Password');
18-
this.signInWithEmailButton=page.getByRole('button', {name: 'Sign in with Email'});
19-
this.signInWithGoogleButton=page.getByRole('button', {name: 'Google'});
20-
this.signUpWithEmailButton=page.getByRole('button', {name: 'Sign up with Email'});
21-
}
22-
23-
async clickSignInLink() {
24-
await this.signInLink.click();
25-
}
26-
27-
async clickSignUpButton() {
28-
await this.signUpButton.click();
29-
}
30-
31-
async clickSignInWithEmailButton() {
32-
await this.signInWithEmailButton.click();
33-
}
34-
35-
async clickSignInWithGoogleButton() {
36-
await this.signInWithGoogleButton.click();
37-
}
38-
39-
async clickSignUpWithEmailButton() {
40-
await this.signUpWithEmailButton.click();
41-
}
42-
43-
async fillEmailField(email: string) {
44-
await expect(this.emailField).toBeVisible();
45-
await this.emailField.fill(email);
46-
}
47-
48-
async fillPasswordField(password: string) {
49-
await expect(this.passwordField).toBeVisible();
50-
await this.passwordField.fill(password);
51-
}
52-
53-
}
4+
export class AuthPage {
5+
private readonly signInLink: Locator;
6+
private readonly signUpButton: Locator;
7+
private readonly emailField: Locator;
8+
private readonly passwordField: Locator;
9+
private readonly signInWithEmailButton: Locator;
10+
private readonly signInWithGoogleButton: Locator;
11+
private readonly signUpWithEmailButton: Locator;
12+
13+
constructor(public readonly page: Page) {
14+
this.signInLink = page.getByRole('link', { name: 'Sign in' });
15+
this.signUpButton = page.getByRole('button', { name: 'Sign up' });
16+
this.emailField = page.getByLabel('Email');
17+
this.passwordField = page.getByLabel('Password');
18+
this.signInWithEmailButton = page.getByRole('button', { name: 'Sign in with Email' });
19+
this.signInWithGoogleButton = page.getByRole('button', { name: 'Google' });
20+
this.signUpWithEmailButton = page.getByRole('button', { name: 'Sign up with Email' });
21+
}
22+
23+
async clickSignInLink() {
24+
await this.signInLink.click();
25+
}
26+
27+
async clickSignUpButton() {
28+
await this.signUpButton.click();
29+
}
30+
31+
async clickSignInWithEmailButton() {
32+
await this.signInWithEmailButton.click();
33+
}
34+
35+
async clickSignInWithGoogleButton() {
36+
await this.signInWithGoogleButton.click();
37+
}
38+
39+
async clickSignUpWithEmailButton() {
40+
await this.signUpWithEmailButton.click();
41+
}
42+
43+
async fillEmailField(email: string) {
44+
await expect(this.emailField).toBeVisible();
45+
await this.emailField.fill(email);
46+
}
47+
48+
async fillPasswordField(password: string) {
49+
await expect(this.passwordField).toBeVisible();
50+
await this.passwordField.fill(password);
51+
}
52+
53+
};
5454

tests/e2e/web/pages/homePage.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect, Locator, Page } from "@playwright/test";
2+
3+
export class HomePage {
4+
private readonly homePageLink: Locator;
5+
private readonly aboutLink: Locator;
6+
private readonly faqLink: Locator;
7+
private readonly voteLink: Locator;
8+
private readonly signUpButton: Locator;
9+
private readonly signInLink: Locator;
10+
private readonly closeButton: Locator;
11+
12+
constructor(public readonly page: Page) {
13+
this.homePageLink = page.getByText('Compass dev', { exact: true });
14+
this.aboutLink = page.locator('span:has-text("About")');
15+
this.faqLink = page.getByText('FAQ', { exact: true });
16+
this.voteLink = page.getByText('Vote', { exact: true });
17+
this.signUpButton = page.locator('button').filter({ hasText: 'Sign up' }).first();
18+
this.signInLink = page.locator('span:has-text("Sign in")');
19+
this.closeButton = page.getByRole('button', { name: 'Close' });
20+
};
21+
22+
async gotToHomePage() {
23+
await this.page.goto('/');
24+
};
25+
26+
async clickSignUpButton() {
27+
await expect(this.signUpButton).toBeVisible();
28+
await this.signUpButton.click();
29+
};
30+
};
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { expect, Locator, Page } from "@playwright/test";
2+
3+
export class OnboardingPage {
4+
private readonly continueButton: Locator;
5+
private readonly skipOnboardingLink: Locator;
6+
private readonly backButton: Locator;
7+
private readonly getStartedButton: Locator;
8+
private readonly exploreProfilesNowButton: Locator;
9+
private readonly refineProfileButton: Locator;
10+
11+
constructor(public readonly page: Page) {
12+
this.continueButton = page.getByRole('button', { name: 'Continue', exact: true });
13+
this.skipOnboardingLink = page.getByRole('button', { name: 'Skip onboarding', exact: true });
14+
this.backButton = page.getByRole('button', { name: 'Back' });
15+
this.getStartedButton = page.getByRole('button', { name: 'Get started' });
16+
this.exploreProfilesNowButton = page.getByRole('button', { name: 'Explore Profiles Now', exact: true });
17+
this.refineProfileButton = page.getByRole('button', { name: 'Refine Profile', exact: true });
18+
};
19+
20+
async clickContinueButton() {
21+
await expect(this.continueButton).toBeVisible();
22+
await this.continueButton.click();
23+
};
24+
25+
async clickBackButton() {
26+
await expect(this.backButton).toBeVisible();
27+
await this.backButton.click();
28+
};
29+
30+
async clickSkipOnboardingButton() {
31+
await expect(this.skipOnboardingLink).toBeVisible();
32+
await this.skipOnboardingLink.click();
33+
};
34+
35+
async clickGetStartedButton() {
36+
await expect(this.getStartedButton).toBeVisible();
37+
await this.getStartedButton.click();
38+
};
39+
40+
async clickExploreProfilesNowButton() {
41+
await expect(this.exploreProfilesNowButton).toBeVisible();
42+
await this.exploreProfilesNowButton.click();
43+
};
44+
45+
async clickRefineProfileButton() {
46+
await expect(this.refineProfileButton).toBeVisible();
47+
await this.refineProfileButton.click();
48+
};
49+
};

0 commit comments

Comments
 (0)