Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
db:
# Prisma 8 requires PostgreSQL 15 or newer.
image: postgres:16
restart: always
container_name: e2e-tests-node-prisma-8
ports:
- '5438:5432'
environment:
POSTGRES_USER: prisma
POSTGRES_PASSWORD: prisma
POSTGRES_DB: tests
# Dumped from `prisma-cli db init`; the Prisma 8 CLI needs Node 22.18+, so it isn't run at test time.
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U prisma -d tests']
interval: 2s
timeout: 3s
retries: 30
start_period: 5s
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { execSync } from 'child_process';
import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

export default async function globalSetup() {
// Start PostgreSQL via Docker Compose. `--wait` blocks until the healthcheck
// in docker-compose.yml passes, so the app can connect immediately.
execSync('docker compose up -d --wait', {
cwd: __dirname,
stdio: 'inherit',
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { execSync } from 'child_process';
import { dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

export default async function globalTeardown() {
execSync('docker compose down --volumes', {
cwd: __dirname,
stdio: 'inherit',
});
}
64 changes: 64 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-prisma-8/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
CREATE SCHEMA prisma_contract;
CREATE TABLE prisma_contract.contract (
core_hash text NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
contract_json jsonb NOT NULL
);
CREATE TABLE prisma_contract.ledger (
id bigint NOT NULL,
created_at timestamp with time zone DEFAULT now() NOT NULL,
space text NOT NULL,
migration_name text NOT NULL,
migration_hash text NOT NULL,
origin_core_hash text,
origin_profile_hash text,
destination_core_hash text NOT NULL,
destination_profile_hash text,
operations jsonb NOT NULL
);
CREATE SEQUENCE prisma_contract.ledger_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE prisma_contract.ledger_id_seq OWNED BY prisma_contract.ledger.id;
CREATE TABLE prisma_contract.marker (
space text DEFAULT 'app'::text NOT NULL,
core_hash text NOT NULL,
profile_hash text NOT NULL,
contract_json jsonb,
canonical_version integer,
updated_at timestamp with time zone DEFAULT now() NOT NULL,
app_tag text,
meta jsonb DEFAULT '{}'::jsonb NOT NULL,
invariants text[] DEFAULT '{}'::text[] NOT NULL
);
CREATE TABLE public."user" (
email text NOT NULL,
id integer NOT NULL,
name text
);
CREATE SEQUENCE public.user_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.user_id_seq OWNED BY public."user".id;
ALTER TABLE ONLY prisma_contract.ledger ALTER COLUMN id SET DEFAULT nextval('prisma_contract.ledger_id_seq'::regclass);
ALTER TABLE ONLY public."user" ALTER COLUMN id SET DEFAULT nextval('public.user_id_seq'::regclass);
INSERT INTO prisma_contract.contract VALUES ('f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5', '2026-09-09 09:15:28.369559+00', '{"meta": {}, "roots": {"user": {"model": "User", "namespace": "public"}}, "domain": {"namespaces": {"public": {"models": {"User": {"fields": {"id": {"type": {"kind": "scalar", "codecId": "pg/int4@1"}, "nullable": false}, "name": {"type": {"kind": "scalar", "codecId": "pg/text@1"}, "nullable": true}, "email": {"type": {"kind": "scalar", "codecId": "pg/text@1"}, "nullable": false}}, "storage": {"table": "user", "fields": {"id": {"column": "id"}, "name": {"column": "name"}, "email": {"column": "email"}}, "namespaceId": "public"}, "relations": {}}}}}}, "target": "postgres", "storage": {"namespaces": {"public": {"id": "public", "entries": {"table": {"user": {"columns": {"id": {"codecId": "pg/int4@1", "default": {"kind": "function", "expression": "autoincrement()"}, "nullable": false, "nativeType": "int4"}, "name": {"codecId": "pg/text@1", "nullable": true, "nativeType": "text"}, "email": {"codecId": "pg/text@1", "nullable": false, "nativeType": "text"}}, "indexes": [], "uniques": [{"columns": ["email"]}], "primaryKey": {"columns": ["id"]}, "foreignKeys": []}}}}}, "storageHash": "f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5"}, "extensions": {}, "profileHash": "3916f444a8a17ad749191acf9e08dad97d1a327b88c2f1d45d12f240296aa8b2", "capabilities": {"sql": {"enums": true, "lateral": true, "returning": true, "scalarList": true, "checkConstraint": true, "defaultInInsert": true}, "postgres": {"limit": true, "jsonAgg": true, "lateral": true, "orderBy": true, "returning": true, "distinctOn": true}}, "targetFamily": "sql"}');
INSERT INTO prisma_contract.ledger VALUES (1, '2026-09-09 09:15:28.369559+00', 'app', '', 'f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5', '', NULL, 'f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5', NULL, '[{"id": "table.user", "label": "Create table \"user\"", "target": {"id": "postgres", "details": {"name": "user", "schema": "public", "objectType": "table"}}, "execute": [{"sql": "CREATE TABLE \"public\".\"user\" (\n \"email\" text NOT NULL,\n \"id\" SERIAL NOT NULL,\n \"name\" text,\n PRIMARY KEY (\"id\")\n)", "params": [], "description": "create table \"user\""}], "summary": "Creates table \"user\"", "precheck": [{"sql": "SELECT (to_regclass($1)) IS NULL AS \"result\"", "params": ["\"public\".\"user\""], "description": "ensure table \"user\" does not exist"}], "postcheck": [{"sql": "SELECT (to_regclass($1)) IS NOT NULL AS \"result\"", "params": ["\"public\".\"user\""], "description": "verify table \"user\" exists"}], "operationClass": "additive"}, {"id": "unique.user.user_email_key", "label": "Add unique constraint on \"user\" (email)", "target": {"id": "postgres", "details": {"name": "user_email_key", "table": "user", "schema": "public", "objectType": "unique"}}, "execute": [{"sql": "ALTER TABLE \"public\".\"user\" ADD CONSTRAINT \"user_email_key\" UNIQUE (\"email\")", "description": "add unique constraint \"user_email_key\""}], "precheck": [{"sql": "SELECT NOT EXISTS (SELECT 1 AS \"one\" FROM \"pg_constraint\" AS \"c\" INNER JOIN \"pg_namespace\" AS \"n\" ON \"n\".\"oid\" = \"c\".\"connamespace\" WHERE (\"c\".\"conname\" = $1 AND \"n\".\"nspname\" = $2 AND \"c\".\"conrelid\" = to_regclass($3))) AS \"result\"", "params": ["user_email_key", "public", "\"public\".\"user\""], "description": "ensure constraint \"user_email_key\" does not exist"}], "postcheck": [{"sql": "SELECT EXISTS (SELECT 1 AS \"one\" FROM \"pg_constraint\" AS \"c\" INNER JOIN \"pg_namespace\" AS \"n\" ON \"n\".\"oid\" = \"c\".\"connamespace\" WHERE (\"c\".\"conname\" = $1 AND \"n\".\"nspname\" = $2 AND \"c\".\"conrelid\" = to_regclass($3))) AS \"result\"", "params": ["user_email_key", "public", "\"public\".\"user\""], "description": "verify constraint \"user_email_key\" exists"}], "operationClass": "additive"}]');
INSERT INTO prisma_contract.marker VALUES ('app', 'f4e1954fd8bed87828d13c3f1a02164dc9796ef1af76ed6f98184c01263169c5', '3916f444a8a17ad749191acf9e08dad97d1a327b88c2f1d45d12f240296aa8b2', NULL, NULL, '2026-09-09 09:15:28.369559+00', NULL, '{}', '{}');
ALTER TABLE ONLY prisma_contract.contract
ADD CONSTRAINT contract_pkey PRIMARY KEY (core_hash);
ALTER TABLE ONLY prisma_contract.ledger
ADD CONSTRAINT ledger_pkey PRIMARY KEY (id);
ALTER TABLE ONLY prisma_contract.marker
ADD CONSTRAINT marker_pkey PRIMARY KEY (space);
ALTER TABLE ONLY public."user"
ADD CONSTRAINT user_email_key UNIQUE (email);
ALTER TABLE ONLY public."user"
ADD CONSTRAINT user_pkey PRIMARY KEY (id);
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "node-prisma-8",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"build": "tsc",
"start": "node --import ./dist/instrument.js dist/app.js",
"test": "playwright test",
"clean": "npx rimraf node_modules pnpm-lock.yaml dist",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test"
},
"dependencies": {
"@prisma/orm-postgres": "8.0.0-rc.8",
"@sentry/node": "file:../../packed/sentry-node-packed.tgz",
"@types/express": "^4.17.21",
"@types/node": "^20.19.0",
"express": "^4.21.2",
"typescript": "~5.9.0"
},
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:../../../test-utils",
"@sentry/core": "file:../../packed/sentry-core-packed.tgz"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: `pnpm start`,
});

export default {
...config,
globalSetup: './global-setup.mjs',
globalTeardown: './global-teardown.mjs',
};
33 changes: 33 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-prisma-8/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { randomBytes } from 'node:crypto';
import postgres from '@prisma/orm-postgres/runtime';
import * as Sentry from '@sentry/node';
import express from 'express';
import type { Contract } from './prisma/contract.d.ts';
import contractJson from './prisma/contract.json' with { type: 'json' };

const db = postgres<Contract>({
contractJson,
url: 'postgresql://prisma:prisma@localhost:5438/tests',
});

const app = express();
const port = 3030;

app.get('/test-prisma', async (_req, res) => {
const created = await db.orm.public.User.create({
name: 'Tilda',
email: `tilda_${randomBytes(4).toString('hex')}@sentry.io`,
});

const users = await db.orm.public.User.all();

await db.orm.public.User.where(user => user.email.like('%sentry.io')).delete();

res.json({ created: created.id, count: users.length });
});

Sentry.setupExpressErrorHandler(app);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

l: I think this is not needed anymore. If it is needed it's a bug

Suggested change
Sentry.setupExpressErrorHandler(app);


app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as Sentry from '@sentry/node';

Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
debug: !!process.env.DEBUG,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1,
});
Loading
Loading