Skip to content

Implement test realm management for AI-generated tests#4265

Draft
habdelra wants to merge 5 commits intomainfrom
worktree-cs-10419
Draft

Implement test realm management for AI-generated tests#4265
habdelra wants to merge 5 commits intomainfrom
worktree-cs-10419

Conversation

@habdelra
Copy link
Copy Markdown
Contributor

@habdelra habdelra commented Mar 27, 2026

Summary

  • Implement factory-test-realm.ts — test execution orchestration, TestRun card lifecycle, resume logic, and result parsing
  • Add test-results.gts — TestRun CardDef + TestResultEntry FieldDef with status enums, CodeRefField, and UI templates
  • Add realm-operations.ts — shared realm HTTP operations (search, read, write, pull, cancel indexing)
  • Auto-create test artifacts realm from Project card name
  • Extend _cancel-indexing-job to cancel pending jobs (runtime-common)
  • Combined cache:prepare infrastructure for multiple realms (--combined flag)
  • Rename card instance folders to plural display names (Projects/, Tickets/, Knowledge Articles/, etc.)
  • Move test specs and TestRun cards to target realm (not test realm)
  • Fix 401 auth flake in multi-worker Playwright tests
  • Relax assertUsableHostDist to accept dev host builds
  • Bump Postgres max_connections from 20 to 40

Try it out

Prerequisites

  • mise run dev-all running

Run the smoke test

The smoke test simulates the full factory workflow — the LLM implementation phase followed by the testing phase.

Phase 1 — Simulate LLM implementation output. The smoke test creates a realm and writes what the LLM would have produced during the implementation phase:

  • A HelloCard card definition (.gts)
  • A Spec card instance (from packages/base/spec.gts) pointing to the HelloCard definition
  • A Playwright test spec in the Tests/ folder that exercises the card

Phase 2 — Run the testing phase. The smoke test calls executeTestRunFromRealm which runs the full pipeline:

  • Creates a TestRun card with status: running in the target realm's Test Runs/ folder
  • Pulls the target realm locally and starts a test harness realm server
  • Runs the Playwright spec against the harness
  • Any card instances created by the spec during execution land in the test artifacts realm
  • Completes the TestRun card with pass/fail results and timing
cd packages/software-factory

MATRIX_URL=http://localhost:8008 \
MATRIX_USERNAME=your-username \
MATRIX_PASSWORD=your-password \
pnpm smoke:test-realm -- \
  --target-realm-url http://localhost:4201/your-username/smoke-test-realm/

Note: The realm smoke-test-realm does not need to exist beforehand — the smoke test creates it and populates it. If the realm already exists from a previous run, the new content will be written into the existing realm.

What to expect on the command line:

=== Factory Test Realm Smoke Test ===

Target realm: http://localhost:4201/your-username/smoke-test-realm/
Auth: authenticated

--- Phase 1: Writing LLM implementation output to target realm ---

  Writing hello.gts (HelloCard definition)...
  ✓ hello.gts
  Writing Spec/hello-card.json (Spec card for HelloCard)...
  ✓ Spec/hello-card.json
  Writing Tests/hello-smoke.spec.ts (Playwright spec)...
  ✓ Tests/hello-smoke.spec.ts

--- Phase 2: Running executeTestRunFromRealm (testing phase) ---

  This will:
    1. Create a TestRun card (status: running) in Test Runs/
    2. Pull the target realm locally
    3. Start a test harness realm server
    4. Run the Playwright spec against the harness
    5. Complete the TestRun card with results

--- Results ---

  TestRun ID:  Test Runs/hello-smoke-1
  Status:      passed

  View in Boxel: http://localhost:4201/your-username/smoke-test-realm/Test Runs/hello-smoke-1

✓ All tests passed!

What to expect in the Boxel app:

  • Navigate to your smoke-test-realm workspace
  • You'll see the HelloCard definition (hello.gts), the Spec card (Spec/hello-card) pointing to it, and the Tests/ folder with the Playwright spec
  • In Test Runs/ you'll find hello-smoke-1 — the TestRun card produced by the testing phase
  • The fitted view shows: status badge (passed/failed), sequence number (Bring in a demo from ember-animated #1), pass/fail counts, duration
  • The isolated view shows: full test results with individual test names, status per test, and failure details (if any)

Linear tickets

  • CS-10419 — Implement test realm management for AI-generated tests
  • CS-10530 — Extract shared realm operations into a common lib
  • CS-10536 — Extend _cancel-indexing-job to cancel pending jobs
  • CS-10537 — Combined cache:prepare template DB for multiple realms
  • CS-10538 — Restructure test execution: specs + TestRun in target realm, auto-create test artifacts realm
  • CS-10540 — Relax assertUsableHostDist to accept dev host builds

Test plan

  • pnpm test:node — 316/316 unit tests pass
  • pnpm test:playwright — 13/13 Playwright tests pass (0 flakes)
  • pnpm lint:glint — 0 errors in changed files
  • Bootstrap spec passes in parallel (2 workers) — 401 flake fixed
  • Template rebuild works with renamed folders
  • Combined cache:prepare builds single template DB

🤖 Generated with Claude Code

@habdelra habdelra marked this pull request as draft March 27, 2026 15:12
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 27, 2026

Host Test Results

    1 files  ±  0      1 suites  ±0   2h 12m 27s ⏱️ + 9m 42s
2 062 tests +119  2 046 ✅ +117  15 💤 +1  0 ❌ ±0  1 🔥 +1 
2 077 runs  +120  2 060 ✅ +117  15 💤 +1  1 ❌ +1  1 🔥 +1 

For more details on these errors, see this check.

Results for commit 5abb98e. ± Comparison against base commit 5d48ebc.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3da0aad612

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1 @@
/home/hassan/codez/boxel/packages/host/dist No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove machine-specific host dist symlink

This commit adds packages/host/dist as a symlink to an absolute local path (/home/hassan/codez/...), which is not portable to other developer machines or CI. Any workflow that relies on packages/host/dist will now see a dangling or incorrect path outside the repository, causing non-reproducible failures when the harness/tests try to use host assets.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

let's git ignore this instead

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — removed the symlink from git (git rm --cached) and added packages/host/dist to .gitignore.


let realmUrl = new URL(projectCardUrl).origin + '/';
let cardPath = new URL(projectCardUrl).pathname.slice(1);
await writeCardSource(realmUrl, `${cardPath}.json`, readResult.document, fetchOptions);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Propagate failure when project card update does not persist

After creating a test artifacts realm, this path writes testArtifactsRealmUrl back to the Project card but ignores the writeCardSource result. If that write fails (auth, validation, network), the function still reports success, so subsequent runs will keep creating new realms because the Project card was never updated. This silently leaks realms and gives callers a false success state.

Useful? React with 👍 / 👎.

@github-actions
Copy link
Copy Markdown

Preview deployments

@habdelra habdelra force-pushed the worktree-cs-10419 branch 2 times, most recently from 20baf0c to dc22611 Compare March 27, 2026 15:29
- Add TestRun card definition (test-results.gts) with TestResultEntry FieldDef,
  status enums, CodeRefField, and fitted/isolated templates
- Add factory-test-realm.ts with test execution orchestration, card lifecycle
  (createTestRun, completeTestRun, resolveTestRun), resume logic, and
  executeTestRunFromRealm
- Add realm-operations.ts shared lib consolidating searchRealm, readCardSource,
  writeCardSource, pullRealmFiles, cancelAllIndexingJobs, ensureTrailingSlash
- Add ensureTestArtifactsRealm for auto-creating test realms from Project card
- Add testArtifactsRealmUrl field to Project card in darkfactory.gts
- Extend _cancel-indexing-job to cancel pending jobs via cancelPending body param
- Add combined cache:prepare infrastructure (--combined flag, additionalRealms,
  buildCombinedTemplateDatabase, ensureCombinedFactoryRealmTemplate)
- Rename card instance folders to plural display names: Projects/, Tickets/,
  Knowledge Articles/, Agent Profiles/, Test Runs/, Tests/
- Move test specs and TestRun cards to target realm (not test realm)
- Update all prompts to reference Tests/ in target realm
- Fix 401 auth flake by always rewriting template URLs in startFactoryRealmServer
- Relax assertUsableHostDist to accept dev host builds
- Bump Postgres max_connections from 20 to 40 for combined template support
- Add coveredRealmDirs to PreparedTemplateMetadata for combined template lookup
- Add test-realm-runner fixture with HelloCard + passing/failing specs
- Add smoke:test-realm script for manual verification

316/316 unit tests, 13/13 Playwright tests, 0 glint errors.

Tickets: CS-10419, CS-10530, CS-10536, CS-10537, CS-10538, CS-10540

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@habdelra habdelra force-pushed the worktree-cs-10419 branch from dc22611 to a699f1c Compare March 27, 2026 15:33
@habdelra habdelra requested a review from Copilot March 27, 2026 15:36
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements end-to-end “test realm management” for AI-generated Playwright tests by introducing TestRun card artifacts, shared realm HTTP operations, combined template DB caching, and updated fixture/layout conventions (pluralized folders, test specs in Tests/ in the target realm).

Changes:

  • Added factory-test-realm orchestration (TestRun creation/completion, resume logic, Playwright execution + parsing) and test-results.gts card/field definitions for durable test result storage.
  • Extracted shared realm HTTP helpers into scripts/lib/realm-operations.ts and updated scripts/tests to use it (including indexing job cancellation with optional pending-job cancellation).
  • Added combined cache/template support for multiple fixtures and updated tests/fixtures/prompts to match new conventions (plural instance folders, specs/results in target realm, new e2e fixtures/tests).

Reviewed changes

Copilot reviewed 60 out of 62 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
packages/software-factory/tests/index.ts Registers the new factory-test-realm unit test module.
packages/software-factory/tests/fixtures.ts Allows template metadata to cover multiple realm dirs (combined template support).
packages/software-factory/tests/factory-test-realm.test.ts Adds unit coverage for parsing, TestRun lifecycle, resume logic, and realm pulls.
packages/software-factory/tests/factory-test-realm.spec.ts Adds Playwright e2e tests for executing and completing a TestRun.
packages/software-factory/tests/factory-target-realm.spec.ts Updates expected card paths to pluralized folders.
packages/software-factory/tests/factory-skill-loader.test.ts Updates fixture IDs to pluralized folders.
packages/software-factory/tests/factory-prompt-loader.test.ts Updates prompt tests for pluralized IDs and removes test-realm mention.
packages/software-factory/tests/factory-entrypoint.test.ts Updates bootstrap expectations to pluralized folders.
packages/software-factory/tests/factory-entrypoint.integration.test.ts Updates integration expectations to pluralized folders.
packages/software-factory/tests/factory-brief.test.ts Updates darkfactory fixture path expectations to pluralized folders.
packages/software-factory/tests/factory-bootstrap.test.ts Updates bootstrap tests for pluralized folders and URL decoding.
packages/software-factory/tests/factory-bootstrap.spec.ts Updates e2e bootstrap expectations and navigation paths.
packages/software-factory/tests/factory-agent.test.ts Updates agent context IDs to pluralized folders.
packages/software-factory/tests/factory-agent.integration.test.ts Updates integration expectations for pluralized ticket IDs.
packages/software-factory/test-fixtures/test-realm-runner/index.json Adds a new realm fixture for running the test-realm e2e flow.
packages/software-factory/test-fixtures/test-realm-runner/home.gts Adds a simple Home card for the test realm runner fixture.
packages/software-factory/test-fixtures/test-realm-runner/hello.gts Adds a HelloCard used by e2e tests.
packages/software-factory/test-fixtures/test-realm-runner/Tests/hello-passing.spec.ts Adds a passing Playwright spec for e2e coverage.
packages/software-factory/test-fixtures/test-realm-runner/Tests/hello-failing.spec.ts Adds a failing Playwright spec for e2e error/failure coverage.
packages/software-factory/test-fixtures/test-realm-runner/HelloCard/sample.json Adds a sample card instance used by e2e specs.
packages/software-factory/test-fixtures/test-realm-runner/.realm.json Adds realm metadata for the new fixture realm.
packages/software-factory/test-fixtures/darkfactory-adopter/Ticket/ticket-001.json Updates relationship links to pluralized folders.
packages/software-factory/test-fixtures/darkfactory-adopter/Project/demo-project.json Updates relationship links to pluralized folders.
packages/software-factory/test-fixtures/darkfactory-adopter/KnowledgeArticle/agent-onboarding.json Updates relationship links to pluralized folders.
packages/software-factory/src/runtime-metadata.ts Extends prepared template metadata with coveredRealmDirs.
packages/software-factory/src/harness/support-services.ts Relaxes host dist validation to allow dev/prod builds.
packages/software-factory/src/harness/shared.ts Updates PG connection comment and adds combined fixture hashing.
packages/software-factory/src/harness/isolated-realm-stack.ts Adds support for mounting additional realms in isolated stacks.
packages/software-factory/src/harness/database.ts Adds combined template DB build for multiple fixtures.
packages/software-factory/src/harness/api.ts Exposes ensureCombinedFactoryRealmTemplate and fixes realm-server URL rewrite for cloned DBs.
packages/software-factory/src/harness.ts Re-exports combined template helpers and types.
packages/software-factory/src/factory-brief.ts Switches to shared cardSourceMimeType constant.
packages/software-factory/src/factory-bootstrap.ts Moves bootstrap artifacts to pluralized folder names.
packages/software-factory/src/cli/smoke-test-realm.ts Adds CLI smoke test for the full test-realm pipeline.
packages/software-factory/src/cli/cache-realm.ts Adds --combined support for multi-fixture template preparation.
packages/software-factory/scripts/run-realm-tests.ts Uses shared ensureTrailingSlash helper.
packages/software-factory/scripts/lib/realm-operations.ts Introduces shared realm HTTP operations (search/read/write/pull/cancel indexing).
packages/software-factory/scripts/lib/factory-tool-executor.ts Uses shared ensureTrailingSlash helper.
packages/software-factory/scripts/lib/factory-test-realm.ts Adds core orchestration logic for TestRun creation/completion, resume, artifacts realm, and Playwright execution.
packages/software-factory/scripts/lib/boxel.ts Uses shared ensureTrailingSlash helper.
packages/software-factory/scripts/factory-skill-smoke.ts Updates sample IDs to pluralized folders.
packages/software-factory/scripts/factory-prompt-smoke.ts Updates sample IDs to pluralized folders.
packages/software-factory/scripts/factory-agent-smoke.ts Updates sample IDs to pluralized folders.
packages/software-factory/realm/test-results.gts Adds TestRun/TestResultEntry definitions and UI templates.
packages/software-factory/realm/darkfactory.gts Adds testArtifactsRealmUrl field to Project.
packages/software-factory/prompts/ticket-test.md Updates guidance: tests live in target realm Tests/.
packages/software-factory/prompts/ticket-implement.md Updates guidance: tests live in target realm Tests/.
packages/software-factory/prompts/system.md Updates system rules and removes explicit test realm mention.
packages/software-factory/prompts/examples/iterate-fix.md Updates example to write tests to Tests/ in target realm.
packages/software-factory/prompts/examples/create-test.md Updates example to write tests to Tests/ in target realm.
packages/software-factory/prompts/examples/create-card.md Updates example to write tests to Tests/ in target realm.
packages/software-factory/prompts/action-schema.md Updates schema docs: create_test/update_test must target realm.
packages/software-factory/playwright.global-setup.ts Prepares template cache for the new test realm runner fixture.
packages/software-factory/package.json Adds smoke:test-realm script.
packages/software-factory/docs/one-shot-factory-go-plan.md Updates design doc to reflect new test artifacts & locations.
packages/runtime-common/realm.ts Extends _cancel-indexing-job to optionally cancel pending jobs.
packages/runtime-common/job-utils.ts Adds cancelAllJobsInConcurrencyGroup (running + pending).
packages/realm-server/tests/scripts/boot_preseeded.sh Increases Postgres max_connections to 40 for test stability.
packages/realm-server/tests/realm-endpoints/cancel-indexing-job-test.ts Adds coverage for cancelPending behavior and defaults.
packages/host/dist Adds a tracked file pointing at a local dist directory path.
Comments suppressed due to low confidence (3)

packages/host/dist:1

  • This looks like an accidentally committed local path placeholder (and potentially leaks a developer machine path). If this is meant to represent a build artifact location, it should not be tracked in git—remove this file from the repo and add the appropriate pattern to .gitignore (or replace with a documented config mechanism).
    packages/software-factory/tests/factory-brief.test.ts:1
  • The test now reads the fixture from test-fixtures/darkfactory-adopter/Tickets/ticket-001.json, but the diff shows the fixture file still lives under test-fixtures/darkfactory-adopter/Ticket/ticket-001.json (singular). This will fail at runtime with ENOENT. Rename/move the fixture directories/files to match the new pluralized folder conventions (e.g., Ticket/Tickets/, Project/Projects/, KnowledgeArticle/Knowledge Articles/) and update any remaining references accordingly.
    packages/software-factory/tests/fixtures.ts:1
  • resolvedRealmDir is never reassigned; it should be a const to better communicate intent and prevent accidental mutation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


let realmUrl = new URL(projectCardUrl).origin + '/';
let cardPath = new URL(projectCardUrl).pathname.slice(1);
await writeCardSource(realmUrl, `${cardPath}.json`, readResult.document, fetchOptions);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

ensureTestArtifactsRealm ignores whether persisting testArtifactsRealmUrl back to the Project card succeeded. If the write fails, subsequent runs may keep creating new realms and the returned created: true becomes misleading. Capture the result of writeCardSource(...), and return { created: false, error: ... } (or at least surface a warning/error) when it fails.

Suggested change
await writeCardSource(realmUrl, `${cardPath}.json`, readResult.document, fetchOptions);
try {
await writeCardSource(realmUrl, `${cardPath}.json`, readResult.document, fetchOptions);
} catch (err) {
return {
testArtifactsRealmUrl: '',
created: false,
error: `Failed to persist testArtifactsRealmUrl to Project card: ${
err instanceof Error ? err.message : String(err)
}`,
};
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — now captures the writeCardSource result and returns { created: false, error } when the Project card update fails.

authorization?: string;
fetch?: typeof globalThis.fetch;
realmServerUrl: string;
darkfactoryModuleUrl: string;
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

darkfactoryModuleUrl is accepted in ensureTestArtifactsRealm options but is never used in the function body. Remove it from the signature to avoid confusion, or use it (e.g., for writing an adoptsFrom value or any darkfactory-specific behavior if intended).

Suggested change
darkfactoryModuleUrl: string;

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed from the signature.

Comment on lines +970 to +985
/**
* Find spec files within a local directory, filtering by the requested
* spec paths. If specPaths are relative paths like `TestSpec/hello.spec.ts`,
* resolve them within the local dir. Falls back to finding all `.spec.ts`
* files if no specPaths match.
*/
function findSpecFiles(localDir: string, specPaths: string[]): string[] {
let found: string[] = [];
for (let specPath of specPaths) {
let fullPath = resolve(localDir, specPath);
if (existsSync(fullPath)) {
found.push(fullPath);
}
}
return found;
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The doc comment says this function falls back to finding all .spec.ts files if none of specPaths match, but the implementation currently only returns matched paths (or an empty list). Either implement the fallback (e.g., walk localDir and collect *.spec.ts) or update the comment to match the actual behavior.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Updated the doc comment to match actual behavior — no fallback walk, only returns matched paths.

Comment on lines +684 to +688
let pullTargetResult = await pullRealmFiles(
options.targetRealmUrl,
targetLocalDir,
{ authorization: options.authorization, fetch: options.fetch },
);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

executeTestRunFromRealm pulls the same target realm twice (once into targetLocalDir and again into specsLocalDir), which doubles the network I/O and disk writes since pullRealmFiles downloads all realm files discovered via _mtimes. Consider pulling once and either (a) point Playwright at the spec files under targetLocalDir, or (b) enhance pullRealmFiles to support an include-prefix filter so only Tests/ is downloaded for the specs directory.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed — single pull into targetLocalDir, specs discovered from the same directory.

Comment on lines +708 to +729
// Step 6: Pull test specs from target realm to local temp dir.
// Specs now live in the target realm's Tests/ folder.
// TODO: Refactor to use `boxel pull` CLI once it supports --jwt.
let pullSpecsResult = await pullRealmFiles(
options.targetRealmUrl,
specsLocalDir,
{ authorization: options.authorization, fetch: options.fetch },
);
if (pullSpecsResult.error) {
let errorMessage = `Failed to pull test specs: ${pullSpecsResult.error}`;
await completeTestRun(testRunId, {
status: 'error',
passedCount: 0,
failedCount: 0,
errorMessage,
results: [],
}, realmOptions);
return { testRunId, status: 'error', errorMessage };
}

// Find spec files in the pulled test realm.
let specFiles = findSpecFiles(specsLocalDir, options.specPaths);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

executeTestRunFromRealm pulls the same target realm twice (once into targetLocalDir and again into specsLocalDir), which doubles the network I/O and disk writes since pullRealmFiles downloads all realm files discovered via _mtimes. Consider pulling once and either (a) point Playwright at the spec files under targetLocalDir, or (b) enhance pullRealmFiles to support an include-prefix filter so only Tests/ is downloaded for the specs directory.

Suggested change
// Step 6: Pull test specs from target realm to local temp dir.
// Specs now live in the target realm's Tests/ folder.
// TODO: Refactor to use `boxel pull` CLI once it supports --jwt.
let pullSpecsResult = await pullRealmFiles(
options.targetRealmUrl,
specsLocalDir,
{ authorization: options.authorization, fetch: options.fetch },
);
if (pullSpecsResult.error) {
let errorMessage = `Failed to pull test specs: ${pullSpecsResult.error}`;
await completeTestRun(testRunId, {
status: 'error',
passedCount: 0,
failedCount: 0,
errorMessage,
results: [],
}, realmOptions);
return { testRunId, status: 'error', errorMessage };
}
// Find spec files in the pulled test realm.
let specFiles = findSpecFiles(specsLocalDir, options.specPaths);
// Step 6: Find spec files in the pulled test realm.
// Specs live in the target realm's Tests/ folder, which has already
// been pulled into targetLocalDir.
let specFiles = findSpecFiles(targetLocalDir, options.specPaths);

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same fix as above — using targetLocalDir for both card content and spec discovery.

const markdownListReplacePattern = /^\s*[-*+]\s+/gm;
const whitespacePattern = /\s+/g;
const cardSourceMimeType = 'application/vnd.card+source';
import { cardSourceMimeType } from '../scripts/lib/realm-operations';
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

This introduces a dependency from src/ (library/runtime code) onto scripts/lib/*. That layering can cause bundling/build issues (scripts are often ts-node/CLI-only and not part of the shipped runtime surface). Prefer moving cardSourceMimeType (or a small shared constants module) into src/ (or another clearly shared package/module) and importing it from there, rather than from scripts/.

Suggested change
import { cardSourceMimeType } from '../scripts/lib/realm-operations';
const cardSourceMimeType = 'application/vnd.card+json';

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reverted — factory-brief.ts and factory-bootstrap.ts now use local constants with a comment referencing SupportedMimeType.CardSource. Cannot import the runtime value because Playwright ts-node crashes on runtime-common decorators (tracked in CS-10550).

* Cancel ALL jobs in a concurrency group — both running (active reservations)
* and pending (unfulfilled, no active reservation).
*/
export async function cancelAllJobsInConcurrencyGroup(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

why are we not sharing code with job-utils.ts. this seem slike it overlaps with forceCancelJobById

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

cancelAllJobsInConcurrencyGroup does share code — it calls cancelRunningJobsInConcurrencyGroup (which calls forceCancelJobById) for running jobs, then calls forceCancelJobById again for each remaining pending job. It composes the existing primitives.

Comment on lines +104 to +105
@field passedCount = contains(NumberField);
@field failedCount = contains(NumberField);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

these should probably just be computeds that operate over the results field

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — passedCount and failedCount are now computed fields on the TestRun card, derived from the results array.

@field ticket = linksTo(() => Ticket);
@field specRef = contains(CodeRefField);
@field status = contains(TestRunStatusField);
@field passedCount = contains(NumberField);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

these should probably just be computeds that operate over the results field

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done — both are now computed fields.

Comment on lines +176 to +177
passedCount: 0,
failedCount: 0,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i think these can be inferred from the results field--which means we shouldnt have to specify them

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Agreed — removed from the card document builder. The card computes these from the results array.

Comment on lines +191 to +192
passedCount: 0,
failedCount: 0,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ditto on the inference

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed here too.

Comment on lines +210 to +211
passedCount: 0,
failedCount: 0,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ditto on the inference

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed here too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

factory-test-realm is pretty monolithic. lets split this down into smaller more cohesive files.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Split into 4 cohesive modules: test-run-types.ts (types), test-run-parsing.ts (result parsing), test-run-cards.ts (card lifecycle), test-run-execution.ts (orchestration/resume). factory-test-realm.ts is now a barrel re-export.

habdelra and others added 2 commits March 30, 2026 11:57
- Split factory-test-realm.ts into cohesive modules:
  test-run-types.ts, test-run-parsing.ts, test-run-cards.ts,
  test-run-execution.ts (barrel re-export in factory-test-realm.ts)
- Make passedCount/failedCount computed fields on TestRun card
  (derived from results array, not stored)
- Fix double-pull: pull target realm once, find specs in same dir
- Remove unused darkfactoryModuleUrl param from ensureTestArtifactsRealm
- Fix findSpecFiles doc comment to match actual behavior (no fallback)
- Propagate write failure in ensureTestArtifactsRealm
- Revert src/ → scripts/lib/ import for cardSourceMimeType (keep
  local constants in factory-brief.ts and factory-bootstrap.ts)
- Make combined cache:prepare the default for multiple realms
  (remove --combined flag requirement)
- Fix formatting (prettier)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The symlink was accidentally committed and breaks CI builds
(ember-cli can't mkdir dist/ when a dangling symlink exists).
The symlink is a worktree convenience — gitignored so it stays
local only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants