-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Brief
Problem
Lowdefy e2e tests can verify UI state and client-side request responses, but cannot verify that data actually persisted correctly in MongoDB. After a form submission, tests can check ldf.expect.request() succeeded, but not that the database contains the right document with the right fields. This forces developers to either trust the UI layer or write separate integration tests.
Additionally:
- Tests currently require a real MongoDB instance, which complicates CI/CD and local development
- Atlas-specific features (Atlas Search, vector search, etc.) can't be tested against mongodb-memory-server
Requirements
MongoDB In-Memory Server:
- Use
mongodb-memory-serverfor test database — no external MongoDB instance required - Each Playwright worker gets an isolated in-memory database
- Tests run without network dependencies, faster execution, works offline
Database Operations:
- The mdb package should export fixture definitions (not a pre-built
testobject) so developers compose it themselves viatest.extend(mdbFixtures)in their locale2e/fixtures.js - The mdb package should have no dependency on
@lowdefy/e2e-utils— it's a standalone Playwright fixture that works with any project - Users should be able to assert MongoDB document state within Playwright e2e tests via an
mdbfixture - Users should be able to load snap files (YAML) to set up known database state before tests
- Users should be able to create/update snap files from current database state
- Snap files should live in
e2e/snaps/<name>/<collection>.yaml - Assertions should auto-poll with configurable timeout (matching Playwright's expect.poll pattern) since DB writes from Lowdefy requests are async
- Users should be able to seed collections inline with JavaScript objects as an alternative to snap files
- Users should have direct MongoDB collection access (findOne, insertOne, aggregate) as an escape hatch
Request Mocking for Atlas Features:
- For Atlas-specific features (Atlas Search, vector search, etc.) that mongodb-memory-server doesn't support, provide request mocking
- Developers configure which Lowdefy requests to mock via config file (e.g.,
e2e/mocks.yamlor similar) - May require changes to Lowdefy build output to support request interception in e2e mode
- Mock responses can be static (from config) or dynamic (based on test setup)
API Shape (Reference)
Developer's e2e/fixtures.js after adding mdb plugin:
import { test as ldfTest, expect } from '@lowdefy/e2e-utils/fixtures';
import { mdbFixtures } from '@lowdefy/community-plugin-e2e-mdb';
export const test = ldfTest.extend(mdbFixtures);
export { expect };Test files import locally (unchanged when adding plugins):
import { test, expect } from './fixtures.js';
test('creates ticket', async ({ ldf, mdb }) => {
// Setup: load snap or seed inline (uses in-memory MongoDB)
await mdb.load('clean-tickets');
// or: await mdb.seed('tickets', [{ name: 'Existing', status: 'open' }]);
// Act via UI
await ldf.goto('/tickets/new');
await ldf.do.blocks['name_input'].fill('John Doe');
await ldf.do.blocks['priority_select'].select('High');
await ldf.do.blocks['submit_btn'].click();
// Assert DB state (auto-polls)
await mdb.expect('tickets').toContainDocument({ name: 'John Doe', priority: 'high' });
await mdb.expect('tickets').toHaveDocumentCount(2);
await mdb.expect('tickets').not.toContainDocument({ _id: 'deleted-id' });
// Direct access escape hatch
const doc = await mdb.collection('tickets').findOne({ name: 'John Doe' });
expect(doc.tags).toContain('urgent');
});Request mocking config (conceptual — TBD during implementation):
# e2e/mocks.yaml
mocks:
- requestId: search_products
response:
- _id: prod-1
name: "Widget"
score: 0.95
- requestId: vector_search_docs
response: [] # empty results for this test scenarioAcceptance Criteria
MongoDB in-memory:
- Package created as
@lowdefy/community-plugin-e2e-mdb - Package exports
mdbFixturesobject for use withtest.extend(mdbFixtures) - Package has no dependency on
@lowdefy/e2e-utils - Uses
mongodb-memory-server— no external MongoDB required - Each Playwright worker gets isolated in-memory database instance
-
mdb.load('name')reads YAML snap files frome2e/snaps/<name>/and restores collections -
mdb.snap('name')creates/updates snap files from current database state -
mdb.seed(collection, docs)clears collection and inserts provided documents -
mdb.expect(collection).toContainDocument(filter)polls until document found or timeout -
mdb.expect(collection).toHaveDocumentCount(n)polls until count matches -
mdb.expect(collection).not.toContainDocument(filter)polls until document absent -
mdb.collection(name)returns raw MongoDB collection for direct operations - Snap YAML format supports query match/project, replace/merge modes, and optional cleanup
Request mocking:
- Developers can configure which Lowdefy requests to mock via config
- Mocked requests return configured responses instead of hitting the (non-existent) Atlas features
- Build/runtime changes in Lowdefy core (if needed) to support request interception in e2e mode
Related Work
- Parent work: Create @lowdefy/e2e-utils package for app developers lowdefy#1970 - @lowdefy/e2e-utils package
- Tracking issue: Add MongoDB data testing (mdb fixture) to @lowdefy/e2e-utils lowdefy#1975 - MongoDB data testing brief
- Inspiration: mdb-snapper tool (YAML snap format, replace/merge modes, cleanup)
Source
Brainstorm discussion about integrating MongoDB data tests into e2e testing. User wants to verify database state within the same e2e test — assert documents exist after UI actions, load/restore snapshots for test setup, seed data inline. Key decisions:
- Community plugin package (not in core repo since it only supports MongoDB)
- Fully decoupled from e2e-utils (exports fixture definitions, no dependency)
- Use mongodb-memory-server for isolation, speed, and no external dependencies
- Built-in request mocking for Atlas Search and other unsupported features (requires Lowdefy build changes + developer config)
Brief Agent - Created: 2026-02-04 CAT