Skip to content

Commit 0ee293f

Browse files
committed
feat: add Cypress e2e app and tighten local Docker + seed workflow
- Add @nbw/e2e (Cypress, smoke spec, shared clock from @nbw/config); root cy:open / test:cy and apps/e2e postinstall for the Cypress binary. - Docker: minio-init profile + root docker:* scripts; disable flaky MailDev healthcheck so compose --wait can finish; document flow in CONTRIBUTING. - Backend: deterministic seed API, tests, UserService.update plain $set; move seed constants and SeedDevOptions into @nbw/config for reuse with Cypress.
1 parent 0bc3436 commit 0ee293f

15 files changed

Lines changed: 364 additions & 37 deletions

File tree

apps/backend/src/seed/seed.controller.spec.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import { BadRequestException } from '@nestjs/common';
22
import { Test, TestingModule } from '@nestjs/testing';
33

4-
import { SeedController } from './seed.controller';
5-
import { SeedService } from './seed.service';
64
import {
75
DEFAULT_SEED_DATA_TIME_CAP,
86
DEFAULT_SEED_FAKER,
97
SEED_USER_COUNT_MAX,
10-
} from './seed.types';
8+
} from '@nbw/config';
9+
10+
import { SeedController } from './seed.controller';
11+
import { SeedService } from './seed.service';
1112

1213
describe('SeedController', () => {
1314
let controller: SeedController;

apps/backend/src/seed/seed.controller.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import {
77
} from '@nestjs/common';
88
import { ApiOperation, ApiQuery, ApiTags } from '@nestjs/swagger';
99

10-
import { SeedService } from './seed.service';
1110
import {
1211
DEFAULT_SEED_DATA_TIME_CAP,
1312
DEFAULT_SEED_FAKER,
1413
SEED_USER_COUNT_MAX,
1514
SEED_USER_COUNT_MIN,
1615
type SeedDevOptions,
17-
} from './seed.types';
16+
} from '@nbw/config';
17+
18+
import { SeedService } from './seed.service';
1819

1920
@Controller('seed')
2021
@ApiTags('seed')

apps/backend/src/seed/seed.service.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { Test, TestingModule } from '@nestjs/testing';
22

3+
import { DEFAULT_SEED_FAKER } from '@nbw/config';
34
import type { UserDocument } from '@nbw/database';
45
import { SongService } from '@server/song/song.service';
56
import { UserService } from '@server/user/user.service';
67

78
import { SeedService } from './seed.service';
8-
import { DEFAULT_SEED_FAKER } from './seed.types';
99

1010
describe('SeedService', () => {
1111
let service: SeedService;

apps/backend/src/seed/seed.service.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import { Instrument, Note, Song } from '@encode42/nbs.js';
22
import { faker } from '@faker-js/faker';
33
import { Inject, Injectable, Logger } from '@nestjs/common';
44

5-
import { UPLOAD_CONSTANTS } from '@nbw/config';
5+
import {
6+
DEFAULT_SEED_DATA_TIME_CAP,
7+
DEFAULT_SEED_FAKER,
8+
SEED_USER_COUNT_MAX,
9+
SEED_USER_COUNT_MIN,
10+
type SeedDevOptions,
11+
UPLOAD_CONSTANTS,
12+
} from '@nbw/config';
613
import { SongDocument, type UserDocument } from '@nbw/database';
714
import type {
815
CategoryType,
@@ -13,14 +20,6 @@ import type {
1320
import { SongService } from '@server/song/song.service';
1421
import { UserService } from '@server/user/user.service';
1522

16-
import {
17-
DEFAULT_SEED_DATA_TIME_CAP,
18-
DEFAULT_SEED_FAKER,
19-
SEED_USER_COUNT_MAX,
20-
SEED_USER_COUNT_MIN,
21-
type SeedDevOptions,
22-
} from './seed.types';
23-
2423
@Injectable()
2524
export class SeedService {
2625
public readonly logger = new Logger(SeedService.name);

apps/e2e/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
cypress/downloads/
2+
cypress/screenshots/
3+
cypress/videos/

apps/e2e/cypress.config.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* E2E tests hit the Next app (default http://localhost:3000).
3+
* Start the frontend before `cy:open` / `cy:run`. Many routes also need the API
4+
* (see apps/frontend/.env.local.example: NEXT_PUBLIC_API_URL).
5+
*
6+
* Docker deps (Mongo, MinIO, MailDev): from repo root run `bun run docker:reset`
7+
* before backend/tests when you need a clean stack; use `docker:reset:fresh` to
8+
* wipe volumes as well.
9+
*
10+
* Browser time in specs can align with backend seed caps via `@nbw/config`
11+
* (`DEFAULT_SEED_DATA_TIME_CAP`, `SEED_E2E_BROWSER_CLOCK_MS`).
12+
*/
13+
import { defineConfig } from 'cypress';
14+
15+
const baseUrl =
16+
process.env.CYPRESS_BASE_URL?.replace(/\/$/, '') ?? 'http://localhost:3000';
17+
18+
export default defineConfig({
19+
e2e: {
20+
baseUrl,
21+
supportFile: 'cypress/support/e2e.ts',
22+
specPattern: 'cypress/e2e/**/*.cy.ts',
23+
video: false,
24+
screenshotOnRunFailure: true,
25+
},
26+
});

apps/e2e/cypress/e2e/smoke.cy.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { SEED_E2E_BROWSER_CLOCK_MS } from '@nbw/config';
2+
3+
describe('smoke', () => {
4+
it('loads the home page', () => {
5+
cy.clock(SEED_E2E_BROWSER_CLOCK_MS, ['Date']);
6+
cy.visit('/');
7+
cy.get('body').should('be.visible');
8+
});
9+
});

apps/e2e/cypress/support/e2e.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// Global setup for Cypress e2e runs (hooks and commands can be added here).

apps/e2e/package.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"name": "@nbw/e2e",
3+
"version": "0.1.0",
4+
"private": true,
5+
"description": "Cypress end-to-end tests for NoteBlockWorld",
6+
"license": "ISC",
7+
"scripts": {
8+
"postinstall": "cypress install",
9+
"build": "exit 0",
10+
"start": "exit 0",
11+
"dev": "exit 0",
12+
"cy:open": "cypress open",
13+
"cy:run": "cypress run"
14+
},
15+
"dependencies": {
16+
"@nbw/config": "workspace:*"
17+
},
18+
"devDependencies": {
19+
"cypress": "^14.3.0",
20+
"typescript": "^5.9.2"
21+
}
22+
}

apps/e2e/tsconfig.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"baseUrl": ".",
5+
"lib": ["ES2022", "DOM"],
6+
"module": "ESNext",
7+
"moduleResolution": "bundler",
8+
"noEmit": true,
9+
"isolatedModules": true,
10+
"esModuleInterop": true,
11+
"types": ["cypress", "node"]
12+
},
13+
"include": ["cypress/**/*.ts", "cypress.config.ts"]
14+
}

0 commit comments

Comments
 (0)