Repository navigation
e2e: run Detox suite against local Worker + local D1 - #102
tpaulshippy wants to merge 1 commit into
Conversation
- worker/scripts/seed-local-e2e.sql: seeds ONLY e2e users 60/61 (testpassword123, pbkdf2 10k) + PIN-less accounts + default AI model. Load: wrangler d1 execute syft-db --local --file=./scripts/seed-local-e2e.sql - front/e2e/seedHelpers.js: shared REST + D1-direct helpers. D1-direct helpers shell out to wrangler d1 execute --local on 127.0.0.1:8787 bases, use Cloudflare D1 REST on workers.dev, and throw Django seed hints on localhost:8000.
There was a problem hiding this comment.
3 issues found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="front/e2e/seedHelpers.js">
<violation number="1" location="front/e2e/seedHelpers.js:426">
P1: The manifest keys tokens by `API_BASE_URL`, but the app looks them up by `EXPO_PUBLIC_API_BASE_URL`. The documented local-worker invocation sets only `API_BASE_URL`, so the injected session is invisible unless the native app was separately built with the identical URL; make the helper use and validate the app's base URL, and document setting it for the Detox build.</violation>
</file>
<file name="worker/scripts/seed-local-e2e.sql">
<violation number="1" location="worker/scripts/seed-local-e2e.sql:35">
P2: `OR REPLACE` deletes each conflicting row before reinserting it. The schema cascades user deletion to profiles, bots, chats, and messages; account deletion also removes usage-limit rows. Rerunning this seed therefore erases E2E data; use `ON CONFLICT ... DO UPDATE` for both statements.</violation>
<violation number="2" location="worker/scripts/seed-local-e2e.sql:45">
P2: If local D1 already has another default model, this `OR IGNORE` is skipped by the `unique_default_model` partial index. Onboarding then assigns that existing model instead of the seeded Nova Micro; clear or update the old default before inserting.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
| function tokensManifest(tokens, opts = {}) { | ||
| const { profile = null, bot = null, initialRoute = null } = opts; | ||
| const manifest = { | ||
| tokens: JSON.stringify({ [apiBase()]: tokens }), |
There was a problem hiding this comment.
P1: The manifest keys tokens by API_BASE_URL, but the app looks them up by EXPO_PUBLIC_API_BASE_URL. The documented local-worker invocation sets only API_BASE_URL, so the injected session is invisible unless the native app was separately built with the identical URL; make the helper use and validate the app's base URL, and document setting it for the Detox build.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At front/e2e/seedHelpers.js, line 426:
<comment>The manifest keys tokens by `API_BASE_URL`, but the app looks them up by `EXPO_PUBLIC_API_BASE_URL`. The documented local-worker invocation sets only `API_BASE_URL`, so the injected session is invisible unless the native app was separately built with the identical URL; make the helper use and validate the app's base URL, and document setting it for the Detox build.</comment>
<file context>
@@ -0,0 +1,521 @@
+function tokensManifest(tokens, opts = {}) {
+ const { profile = null, bot = null, initialRoute = null } = opts;
+ const manifest = {
+ tokens: JSON.stringify({ [apiBase()]: tokens }),
+ e2eTestMode: 'true',
+ };
</file context>
| (60, NULL, 0, NULL, 0, 'UTC', NULL), | ||
| (61, NULL, 0, NULL, 0, 'UTC', NULL); | ||
|
|
||
| INSERT OR IGNORE INTO bots_aimodel (model_id, name, input_token_cost, output_token_cost, is_default, supported_input_modalities, created_at, modified_at) |
There was a problem hiding this comment.
P2: If local D1 already has another default model, this OR IGNORE is skipped by the unique_default_model partial index. Onboarding then assigns that existing model instead of the seeded Nova Micro; clear or update the old default before inserting.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At worker/scripts/seed-local-e2e.sql, line 45:
<comment>If local D1 already has another default model, this `OR IGNORE` is skipped by the `unique_default_model` partial index. Onboarding then assigns that existing model instead of the seeded Nova Micro; clear or update the old default before inserting.</comment>
<file context>
@@ -0,0 +1,46 @@
+ (60, NULL, 0, NULL, 0, 'UTC', NULL),
+ (61, NULL, 0, NULL, 0, 'UTC', NULL);
+
+INSERT OR IGNORE INTO bots_aimodel (model_id, name, input_token_cost, output_token_cost, is_default, supported_input_modalities, created_at, modified_at)
+VALUES ('us.amazon.nova-micro-v1:0', 'Nova Micro', 0.000035, 0.00014, 1, '["text"]', '2026-01-01T00:00:00.000Z', '2026-01-01T00:00:00.000Z');
</file context>
| INSERT OR IGNORE INTO bots_aimodel (model_id, name, input_token_cost, output_token_cost, is_default, supported_input_modalities, created_at, modified_at) | |
| UPDATE bots_aimodel SET is_default = 0 WHERE is_default = 1 AND model_id <> 'us.amazon.nova-micro-v1:0'; | |
| INSERT INTO bots_aimodel (model_id, name, input_token_cost, output_token_cost, is_default, supported_input_modalities, created_at, modified_at) | |
| VALUES ('us.amazon.nova-micro-v1:0', 'Nova Micro', 0.000035, 0.00014, 1, '["text"]', '2026-01-01T00:00:00.000Z', '2026-01-01T00:00:00.000Z') | |
| ON CONFLICT(model_id) DO UPDATE SET name = excluded.name, input_token_cost = excluded.input_token_cost, output_token_cost = excluded.output_token_cost, is_default = 1, supported_input_modalities = excluded.supported_input_modalities; |
| -- cd worker && npx wrangler d1 execute syft-db --local --file=./scripts/seed-local-e2e.sql | ||
| -- Idempotent: safe to re-run (INSERT OR REPLACE / OR IGNORE). | ||
|
|
||
| INSERT OR REPLACE INTO auth_user (id, password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined) |
There was a problem hiding this comment.
P2: OR REPLACE deletes each conflicting row before reinserting it. The schema cascades user deletion to profiles, bots, chats, and messages; account deletion also removes usage-limit rows. Rerunning this seed therefore erases E2E data; use ON CONFLICT ... DO UPDATE for both statements.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At worker/scripts/seed-local-e2e.sql, line 35:
<comment>`OR REPLACE` deletes each conflicting row before reinserting it. The schema cascades user deletion to profiles, bots, chats, and messages; account deletion also removes usage-limit rows. Rerunning this seed therefore erases E2E data; use `ON CONFLICT ... DO UPDATE` for both statements.</comment>
<file context>
@@ -0,0 +1,46 @@
+-- cd worker && npx wrangler d1 execute syft-db --local --file=./scripts/seed-local-e2e.sql
+-- Idempotent: safe to re-run (INSERT OR REPLACE / OR IGNORE).
+
+INSERT OR REPLACE INTO auth_user (id, password, last_login, is_superuser, username, first_name, last_name, email, is_staff, is_active, date_joined)
+VALUES
+ (60, 'pbkdf2_sha256$10000$6WsxRJUeouaLspEo$tJ39t8OBwf/CeM9+7EZCU4d78HQC1fg9LaJGKzlpftE=', NULL, 0, 'e2e-test-user', '', '', '', 0, 1, '2026-01-01T00:00:00.000Z'),
</file context>
|
Superseded by #111, which consolidates this branch's seedHelpers.js (byte-identical) and seed SQL (plus a Nova Lite vision row) with the fixed Detox specs, verified 22/22 on a local worker + local D1 stack. |
Makes the Detox E2E suite runnable against a LOCAL Worker (wrangler dev + local D1) instead of local Django or prod workers.dev. DO NOT MERGE yet — orchestrator coordinates merge with the detox lane (they hold an untracked file at front/e2e/seedHelpers.js).
Runbook:
Terminal 1: cd worker && npx wrangler dev (needs worker/.dev.vars with JWT_SECRET — gitignored, local-only; then migrations + seed below)
Terminal 2: API_BASE_URL=http://127.0.0.1:8787/api npx detox test -c ios.sim.debug
What changed (2 new files, +567):
Verification (no simulator; wrangler dev + migrations + seed loaded locally): node script logging in as both users, resetOnboardingFresh, ensurePin/reauth-wrong-then-right/resetPinLockoutState/ensureNoPin round-trip, deleteAllChatsD1, renames, deleteExtra helpers, getDefaultModelId, completeOnboarding, helper /login, Django-hint error — 19/19 PASS (one wrangler --json quirk: NULL TEXT reads back as string 'null'; harmless, worker treats it as unlocked).
Specs will need beyond seedHelpers: specs currently inline their own token/profile/bot fetching (no seedHelpers import on main) — adopting them to require('./seedHelpers') is the detox lane's call; helper PIN default is '1234'; teen-delegated minting (01 spec shells to Django venv) has no Worker equivalent yet — GET /api/login with the helper session returns delegated tokens only when a parent-owned profile binds maya@school.edu.
Summary by cubic
Makes the Detox E2E suite runnable against a local Worker (
wrangler dev+ local D1) instead of Django or prod workers.dev, via two new files: a Worker SQL seed and shared front-end helpers. Do not merge yet — the orchestrator coordinates with the detox lane, which holds an untracked copy offront/e2e/seedHelpers.js.What changed
worker/scripts/seed-local-e2e.sqlseeds only the two E2E users (ids 60/61, passwordtestpassword123via cheap 10k-iteration pbkdf2 hashes) with PIN-less accounts and one default AI model; re-runs are idempotent.front/e2e/seedHelpers.jsadds REST plus D1-direct helpers: local bases shell out towrangler d1 execute --local, workers.dev bases use the Cloudflare D1 REST API, and Django bases throw a seed-command hint.wrangler dev; specs still inline their own token/profile/bot fetching, and adopting them torequire('./seedHelpers')is the detox lane's call.Migration (local runbook)
cd worker && npx wrangler dev; first time, createworker/.dev.varswith aJWT_SECRET, apply local migrations, and loadworker/scripts/seed-local-e2e.sqlvianpx wrangler d1 execute syft-db --local --file=./scripts/seed-local-e2e.sql.API_BASE_URL=http://127.0.0.1:8787/api npx detox test -c ios.sim.debug <spec>.Written for commit ccae46e. Summary will update on new commits.