Skip to content

Commit 5b8f61a

Browse files
committed
02/01: add problem
1 parent 48b95ce commit 5b8f61a

File tree

452 files changed

+34295
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

452 files changed

+34295
-3
lines changed
Lines changed: 11 additions & 0 deletions

exercises/02.test-setup/01.solution.fixtures/package.json renamed to exercises/02.test-setup/01.problem.custom-fixtures/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "exercises_02.test-setup_01.solution.fixtures",
2+
"name": "exercises_02.test-setup_01.problem.custom-fixtures",
33
"private": true,
44
"sideEffects": false,
55
"type": "module",
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// 💣 Remove this import.
2+
// You will be using your custom `test` and `expect` functions.
3+
import { test, expect } from '@playwright/test'
4+
5+
// 🐨 Import `test` and `expect` from the "#tests/test-extend.ts" module.
6+
// 💰 import { this, that } from 'somewhere'
7+
8+
test('displays the welcome heading', async ({
9+
// 🐨 Import the newly created `navigate` fixture from the test context.
10+
page,
11+
}) => {
12+
// 🐨 Replace the `page.goto()` call with `navigate()`.
13+
// Explore the path argument to `navigate()`. See how it provides route suggestions?
14+
await page.goto('/')
15+
16+
await expect(
17+
page.getByRole('heading', { name: 'The Epic Stack' }),
18+
).toBeVisible()
19+
})
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// 🐨 Import `test` and `expect` from the "@playwright/test" package.
2+
// Alias the `test` import as `testBase`, you will need it in the future.
3+
// 💰 import { this as that, another } from 'package'
4+
//
5+
// 🐨 Import `href` and `type Register` from "react-router".
6+
// 💰 import { this, typeof that } from 'package'
7+
//
8+
// 🐨 Declare a new interface called "Fixtures".
9+
// In that interface, declare a "navigate" function with the following type:
10+
// 💰 navigate: <T extends keyof Register['pages']>(...args: Parameters<typeof href<T>>) => Promise<void>
11+
// 💰 interface Fixtures {}
12+
//
13+
// 🐨 Declare and export a new variable called "test".
14+
// Assign it the result of calling `testBase.extend()`.
15+
// Provide the `Fixtures` interface as a type argument to the `testBase.extend()` call.
16+
// 💰 export const test = value
17+
// 💰 testBase.extend<Arg>()
18+
//
19+
// 🐨 Provide an object as the first argument to the `testBase.extend()`.
20+
// In that object, declare an asynchronous function called "navigate"
21+
// with the following call signature:
22+
// 💰 { async navigate({ page }, use) {} }
23+
//
24+
// 🐨 Inside the `navigate` function, call and await the `use()` function.
25+
// 💰 await use()
26+
//
27+
// 📜 The `use()` function expects the implementation of your custom fixture.
28+
// Whatever you provide it as an argument will be exposed as the value of "navigate"
29+
// in your tests.
30+
// 🐨 Provide the implementation of the fixture as the first argument to the
31+
// `use()` function. The fixture must do the following:
32+
// - Get the arguments past by it as "...args";
33+
// - Call `page.goto()` and await that call.
34+
// - Pass `href(...args)` as the argument to `page.goto()`.
35+
//
36+
// 🐨 Finally, export the `expect` function from this module.
37+
// 💰 export { something }
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
LITEFS_DIR="/litefs/data"
2+
DATABASE_PATH="./prisma/data.db"
3+
DATABASE_URL="file:./data.db?connection_limit=1"
4+
CACHE_DATABASE_PATH="./other/cache.db"
5+
SESSION_SECRET="super-duper-s3cret"
6+
HONEYPOT_SECRET="super-duper-s3cret"
7+
RESEND_API_KEY="re_blAh_blaHBlaHblahBLAhBlAh"
8+
SENTRY_DSN="your-dsn"
9+
10+
# this is set to a random value in the Dockerfile
11+
INTERNAL_COMMAND_TOKEN="some-made-up-token"
12+
13+
# the mocks and some code rely on these two being prefixed with "MOCK_"
14+
# if they aren't then the real github api will be attempted
15+
GITHUB_CLIENT_ID="MOCK_GITHUB_CLIENT_ID"
16+
GITHUB_CLIENT_SECRET="MOCK_GITHUB_CLIENT_SECRET"
17+
GITHUB_TOKEN="MOCK_GITHUB_TOKEN"
18+
GITHUB_REDIRECT_URI="https://example.com/auth/github/callback"
19+
20+
# set this to false to prevent search engines from indexing the website
21+
# default to allow indexing for seo safety
22+
ALLOW_INDEXING="true"
23+
24+
# Tigris Object Storage (S3-compatible) Configuration
25+
AWS_ACCESS_KEY_ID="mock-access-key"
26+
AWS_SECRET_ACCESS_KEY="mock-secret-key"
27+
AWS_REGION="auto"
28+
AWS_ENDPOINT_URL_S3="https://fly.storage.tigris.dev"
29+
BUCKET_NAME="mock-bucket"
Lines changed: 15 additions & 0 deletions
Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
name: 🚀 Deploy
2+
on:
3+
push:
4+
branches:
5+
- main
6+
- dev
7+
pull_request: {}
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
permissions:
14+
actions: write
15+
contents: read
16+
17+
jobs:
18+
lint:
19+
name: ⬣ ESLint
20+
runs-on: ubuntu-22.04
21+
steps:
22+
- name: ⬇️ Checkout repo
23+
uses: actions/checkout@v4
24+
25+
- name: ⎔ Setup node
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: 22
29+
30+
- name: 📥 Download deps
31+
uses: bahmutov/npm-install@v1
32+
33+
- name: 🏄 Copy test env vars
34+
run: cp .env.example .env
35+
36+
- name: 🛠 Setup Database
37+
run: npx prisma migrate deploy && npx prisma generate --sql
38+
39+
- name: 🔬 Lint
40+
run: npm run lint
41+
42+
typecheck:
43+
name: ʦ TypeScript
44+
runs-on: ubuntu-22.04
45+
steps:
46+
- name: ⬇️ Checkout repo
47+
uses: actions/checkout@v4
48+
49+
- name: ⎔ Setup node
50+
uses: actions/setup-node@v4
51+
with:
52+
node-version: 22
53+
54+
- name: 📥 Download deps
55+
uses: bahmutov/npm-install@v1
56+
57+
- name: 🏗 Build
58+
run: npm run build
59+
60+
- name: 🏄 Copy test env vars
61+
run: cp .env.example .env
62+
63+
- name: 🛠 Setup Database
64+
run: npx prisma migrate deploy && npx prisma generate --sql
65+
66+
- name: 🔎 Type check
67+
run: npm run typecheck --if-present
68+
69+
vitest:
70+
name: ⚡ Vitest
71+
runs-on: ubuntu-22.04
72+
steps:
73+
- name: ⬇️ Checkout repo
74+
uses: actions/checkout@v4
75+
76+
- name: ⎔ Setup node
77+
uses: actions/setup-node@v4
78+
with:
79+
node-version: 22
80+
81+
- name: 📥 Download deps
82+
uses: bahmutov/npm-install@v1
83+
84+
- name: 🏄 Copy test env vars
85+
run: cp .env.example .env
86+
87+
- name: 🛠 Setup Database
88+
run: npx prisma migrate deploy && npx prisma generate --sql
89+
90+
- name: ⚡ Run vitest
91+
run: npm run test -- --coverage
92+
93+
playwright:
94+
name: 🎭 Playwright
95+
runs-on: ubuntu-22.04
96+
timeout-minutes: 60
97+
steps:
98+
- name: ⬇️ Checkout repo
99+
uses: actions/checkout@v4
100+
101+
- name: 🏄 Copy test env vars
102+
run: cp .env.example .env
103+
104+
- name: ⎔ Setup node
105+
uses: actions/setup-node@v4
106+
with:
107+
node-version: 22
108+
109+
- name: 📥 Download deps
110+
uses: bahmutov/npm-install@v1
111+
112+
- name: 📥 Install Playwright Browsers
113+
run: npm run test:e2e:install
114+
115+
- name: 🛠 Setup Database
116+
run: npx prisma migrate deploy && npx prisma generate --sql
117+
118+
- name: 🏦 Cache Database
119+
id: db-cache
120+
uses: actions/cache@v4
121+
with:
122+
path: prisma/data.db
123+
key:
124+
db-cache-schema_${{ hashFiles('./prisma/schema.prisma')
125+
}}-migrations_${{ hashFiles('./prisma/migrations/*/migration.sql')
126+
}}
127+
128+
- name: 🌱 Seed Database
129+
if: steps.db-cache.outputs.cache-hit != 'true'
130+
run: npx prisma migrate reset --force
131+
132+
- name: 🏗 Build
133+
run: npm run build
134+
135+
- name: 🎭 Playwright tests
136+
run: npx playwright test
137+
138+
- name: 📊 Upload report
139+
uses: actions/upload-artifact@v4
140+
if: always()
141+
with:
142+
name: playwright-report
143+
path: playwright-report/
144+
retention-days: 30
145+
146+
container:
147+
name: 📦 Prepare Container
148+
runs-on: ubuntu-24.04
149+
# only prepare container on pushes
150+
if: ${{ github.event_name == 'push' }}
151+
steps:
152+
- name: ⬇️ Checkout repo
153+
uses: actions/checkout@v4
154+
with:
155+
fetch-depth: 50
156+
157+
- name: 👀 Read app name
158+
uses: SebRollen/[email protected]
159+
id: app_name
160+
with:
161+
file: 'fly.toml'
162+
field: 'app'
163+
164+
- name: 🎈 Setup Fly
165+
uses: superfly/flyctl-actions/[email protected]
166+
167+
- name: 📦 Build Staging Container
168+
if: ${{ github.ref == 'refs/heads/dev' }}
169+
run: |
170+
flyctl deploy \
171+
--build-only \
172+
--push \
173+
--image-label ${{ github.sha }} \
174+
--build-arg COMMIT_SHA=${{ github.sha }} \
175+
--app ${{ steps.app_name.outputs.value }}-staging
176+
env:
177+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
178+
179+
- name: 📦 Build Production Container
180+
if: ${{ github.ref == 'refs/heads/main' }}
181+
run: |
182+
flyctl deploy \
183+
--build-only \
184+
--push \
185+
--image-label ${{ github.sha }} \
186+
--build-arg COMMIT_SHA=${{ github.sha }} \
187+
--build-secret SENTRY_AUTH_TOKEN=${{ secrets.SENTRY_AUTH_TOKEN }} \
188+
--app ${{ steps.app_name.outputs.value }}
189+
env:
190+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
191+
192+
deploy:
193+
name: 🚀 Deploy
194+
runs-on: ubuntu-24.04
195+
needs: [lint, typecheck, vitest, playwright, container]
196+
# only deploy on pushes
197+
if: ${{ github.event_name == 'push' }}
198+
steps:
199+
- name: ⬇️ Checkout repo
200+
uses: actions/checkout@v4
201+
with:
202+
fetch-depth: '50'
203+
204+
- name: 👀 Read app name
205+
uses: SebRollen/[email protected]
206+
id: app_name
207+
with:
208+
file: 'fly.toml'
209+
field: 'app'
210+
211+
- name: 🎈 Setup Fly
212+
uses: superfly/flyctl-actions/[email protected]
213+
214+
- name: 🚀 Deploy Staging
215+
if: ${{ github.ref == 'refs/heads/dev' }}
216+
run: |
217+
flyctl deploy \
218+
--image "registry.fly.io/${{ steps.app_name.outputs.value }}-staging:${{ github.sha }}" \
219+
--app ${{ steps.app_name.outputs.value }}-staging
220+
env:
221+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
222+
223+
- name: 🚀 Deploy Production
224+
if: ${{ github.ref == 'refs/heads/main' }}
225+
run: |
226+
flyctl deploy \
227+
--image "registry.fly.io/${{ steps.app_name.outputs.value }}:${{ github.sha }}"
228+
env:
229+
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
node_modules
2+
.DS_store
3+
4+
/build
5+
/server-build
6+
.env
7+
.cache
8+
9+
/prisma/data.db
10+
/prisma/data.db-journal
11+
/tests/prisma
12+
13+
/test-results/
14+
/playwright-report/
15+
/playwright/.cache/
16+
/tests/fixtures/email/
17+
/tests/fixtures/uploaded/
18+
/tests/fixtures/openimg/
19+
/coverage
20+
21+
/other/cache.db
22+
23+
# Easy way to create temporary files/folders that won't accidentally be added to git
24+
*.local.*
25+
26+
# generated files
27+
/app/components/ui/icons
28+
.react-router/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
legacy-peer-deps=true
2+
registry=https://registry.npmjs.org/

0 commit comments

Comments
 (0)