Skip to content

Commit ef7665c

Browse files
Add firebase emulator, Add registration script, Add signup spec (#22)
* add firebase emulator, add registration script, add signup spec * Upgrade firebase emulator and make it pass the E2E tests --------- Co-authored-by: MartinBraquet <[email protected]>
1 parent 348a557 commit ef7665c

File tree

18 files changed

+2860
-141
lines changed

18 files changed

+2860
-141
lines changed

.env.example

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2+
# use firebase emulator for running e2e tests
3+
NEXT_PUBLIC_FIREBASE_EMULATOR=false
4+
FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9099
5+
FIREBASE_STORAGE_EMULATOR_HOST=127.0.0.1:9199
6+
17
# You already have access to basic local functionality (UI, authentication, database read access).
28

39
# openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 -in backend/shared/src/googleApplicationCredentials-dev.json -out secrets/googleApplicationCredentials-dev.json.enc

.github/workflows/ci.yml

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -45,37 +45,18 @@ jobs:
4545
# "common/coverage/lcov.info" \
4646
# "web/coverage/lcov.info" \
4747
# > coverage/lcov.info
48-
49-
50-
51-
# - name: Build app
52-
# env:
53-
# DATABASE_URL: ${{ secrets.DATABASE_URL }}
54-
# run: npm run build
5548

5649
# Optional: Playwright E2E tests
5750
- name: Install Playwright deps
5851
run: |
59-
npx playwright install --with-deps
52+
npx playwright install chromium
53+
# npx playwright install --with-deps
6054
# npm install @playwright/test
6155

6256
- name: Run E2E tests
63-
env:
64-
NEXT_PUBLIC_API_URL: localhost:8088
65-
NEXT_PUBLIC_FIREBASE_ENV: DEV
66-
NEXT_PUBLIC_FIREBASE_API_KEY: ${{ secrets.NEXT_PUBLIC_FIREBASE_API_KEY }}
67-
NEXT_PUBLIC_SUPABASE_KEY: ${{ secrets.NEXT_PUBLIC_SUPABASE_KEY }}
6857
run: |
69-
npx nyc --reporter=lcov yarn --cwd=web serve &
70-
npx nyc --reporter=lcov yarn --cwd=backend/api dev &
71-
npx wait-on http://localhost:3000
72-
npx playwright test tests/e2e
73-
SERVER_PID=$(fuser -k 3000/tcp)
74-
echo $SERVER_PID
75-
kill $SERVER_PID
76-
SERVER_PID=$(fuser -k 8088/tcp)
77-
echo $SERVER_PID
78-
kill $SERVER_PID
58+
chmod +x scripts/e2e.sh
59+
./scripts/e2e.sh
7960
8061
- name: Upload coverage to Codecov
8162
uses: codecov/codecov-action@v5

backend/api/src/helpers/endpoint.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ export const parseCredentials = async (req: Request): Promise<Credentials> => {
7676
try {
7777
return {kind: 'jwt', data: await auth.verifyIdToken(payload)}
7878
} catch (err) {
79+
const raw = payload.split(".")[0];
80+
console.log("JWT header:", JSON.parse(Buffer.from(raw, "base64").toString()));
7981
// This is somewhat suspicious, so get it into the firebase console
8082
console.error('Error verifying Firebase JWT: ', err, scheme, payload)
8183
throw new APIError(500, 'Error validating token.')

backend/shared/src/init-admin.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import * as admin from 'firebase-admin'
2-
3-
42
import {getServiceAccountCredentials} from "shared/firebase-utils";
53
import {IS_LOCAL} from "common/hosting/constants";
4+
import {IS_FIREBASE_EMULATOR} from "common/envs/constants";
65

7-
// Locally initialize Firebase Admin.
86
export const initAdmin = () => {
7+
8+
if (IS_LOCAL && IS_FIREBASE_EMULATOR) {
9+
console.log("Using Firebase Emulator Suite.")
10+
return admin.initializeApp({
11+
projectId: "compass-57c3c",
12+
storageBucket: "compass-130ba-public",
13+
})
14+
}
15+
916
if (IS_LOCAL) {
1017
try {
1118
const serviceAccount = getServiceAccountCredentials()
12-
// console.debug(serviceAccount)
19+
1320
if (!serviceAccount.project_id) {
1421
console.debug(`GOOGLE_APPLICATION_CREDENTIALS not set, skipping admin firebase init.`)
1522
return
@@ -27,4 +34,4 @@ export const initAdmin = () => {
2734

2835
console.debug(`Initializing connection to default Firebase...`)
2936
return admin.initializeApp()
30-
}
37+
}

common/src/envs/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ console.debug(`Running in ${HOSTING_ENV} (${ENV})`,);
4141
// throw new MissingKeyError('firebaseConfig.apiKey')
4242
// }
4343

44+
export const IS_FIREBASE_EMULATOR = process.env.NEXT_PUBLIC_FIREBASE_EMULATOR === "true"
45+
if (IS_FIREBASE_EMULATOR) console.log("Using Firebase emulator.")
46+
4447
export const LOCAL_WEB_DOMAIN = `localhost:3000`
4548
export const LOCAL_BACKEND_DOMAIN = `${IS_WEBVIEW_DEV_PHONE ? '192.168.1.3' : IS_LOCAL_ANDROID ? '10.0.2.2' : 'localhost'}:8088`
4649

firebase.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,14 @@
88
"bucket": "compass-130ba-private",
99
"rules": "private-storage.rules"
1010
}
11-
]
11+
],
12+
"emulators": {
13+
"auth": {
14+
"port": 9099
15+
},
16+
"ui": {
17+
"enabled": true,
18+
"port": 4000
19+
}
1220
}
21+
}

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"playwright:ui": "playwright test --ui",
3030
"playwright:debug": "playwright test --debug",
3131
"playwright:report": "npx playwright show-report tests/reports/playwright-report",
32-
"postinstall": "./scripts/post_install.sh"
32+
"postinstall": "./scripts/post_install.sh",
33+
"emulate": "firebase emulators:start --only auth --project compass-57c3c"
3334
},
3435
"dependencies": {
3536
"@capacitor/app": "7.1.0",
@@ -65,6 +66,7 @@
6566
"eslint": "8.57.0",
6667
"eslint-plugin-lodash": "^7.4.0",
6768
"eslint-plugin-unused-imports": "4.1.4",
69+
"firebase-tools": "^14.26.0",
6870
"jest": "29.3.1",
6971
"nodemon": "2.0.20",
7072
"prettier": "3.6.2",

playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { defineConfig, devices } from '@playwright/test';
2-
import path from 'path';
32

43
export default defineConfig({
54
testDir: './tests/e2e',
@@ -27,5 +26,6 @@ export default defineConfig({
2726
// use: { ...devices['Desktop Safari'] },
2827
// },
2928
],
29+
timeout: 60000,
3030

3131
});

scripts/e2e.sh

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,42 @@
11
#!/bin/bash
22

3-
# set -e
3+
set -euo pipefail
4+
5+
# Function to clean up background processes
6+
cleanup() {
7+
echo "Stopping background processes..."
8+
for pid in "${PIDS[@]:-}"; do
9+
if kill -0 "$pid" 2>/dev/null; then
10+
kill "$pid" || true
11+
wait "$pid" 2>/dev/null || true
12+
echo "Killed PID $pid"
13+
fi
14+
done
15+
}
16+
17+
# Trap EXIT, INT, TERM to run cleanup automatically
18+
trap cleanup EXIT INT TERM
419

520
cd "$(dirname "$0")"/..
621

722
npx playwright install chromium
823

924
export NEXT_PUBLIC_API_URL=localhost:8088
1025
export NEXT_PUBLIC_FIREBASE_ENV=DEV
26+
export NEXT_PUBLIC_FIREBASE_EMULATOR=true
27+
export FIREBASE_AUTH_EMULATOR_HOST=127.0.0.1:9099
28+
export FIREBASE_STORAGE_EMULATOR_HOST=127.0.0.1:9199
29+
30+
# Start servers in background and store their PIDs
31+
PIDS=()
32+
npx nyc --reporter=lcov yarn --cwd=web serve & PIDS+=($!)
33+
npx nyc --reporter=lcov yarn --cwd=backend/api dev & PIDS+=($!)
34+
yarn emulate & PIDS+=($!)
1135

12-
npx nyc --reporter=lcov yarn --cwd=web serve &
13-
npx nyc --reporter=lcov yarn --cwd=backend/api dev &
1436
npx wait-on http://localhost:3000
15-
npx playwright test tests/e2e --headed
16-
SERVER_PID=$(fuser -k 3000/tcp)
17-
echo $SERVER_PID
18-
kill $SERVER_PID
19-
20-
SERVER_PID=$(fuser -k 8088/tcp)
21-
echo $SERVER_PID
22-
kill $SERVER_PID
37+
38+
npx tsx scripts/setup-auth.ts
39+
40+
npx playwright test tests/e2e
41+
42+
exit ${TEST_FAILED:-0}

scripts/setup-auth.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import axios from 'axios';
2+
import { config } from '../tests/e2e/web/SPEC_CONFIG.js';
3+
4+
async function createAuth() {
5+
const base = 'http://localhost:9099/identitytoolkit.googleapis.com/v1';
6+
7+
await axios.post(`${base}/accounts:signUp?key=fake-api-key`, {
8+
email: config.USERS.DEV_1.EMAIL,
9+
password: config.USERS.DEV_1.PASSWORD,
10+
returnSecureToken: true
11+
});
12+
13+
console.log('Auth created', config.USERS.DEV_1.EMAIL)
14+
15+
}
16+
createAuth();

0 commit comments

Comments
 (0)