Skip to content

Feat/apex test runner - #2005

Merged
paustint merged 10 commits into
mainfrom
feat/apex-test-runner
Aug 30, 2026
Merged

Feat/apex test runner#2005
paustint merged 10 commits into
mainfrom
feat/apex-test-runner

Conversation

@paustint

Copy link
Copy Markdown
Contributor

fix(apex-tests): correct issues found during live browser verification

  • The org-wide coverage tooling object is ApexOrgWideCoverage, not
    OrgWideApexCoverage (query 400'd against a real org).
  • MethodsCompleted already includes failed methods, so progress no
    longer double-counts failures ("3 of 2 methods run").
  • The capped runs table now disables fillHeight — its viewport-based
    min-height beats max-height in CSS, pushing run detail off screen.
  • The coverage source modal explains when Salesforce returns empty
    covered/uncovered line arrays for stale aggregate rows, and shows the
    freshly fetched aggregate counts instead of the possibly-stale table
    row.

Verified end-to-end in the browser against a live org: run launch,
polling, failure detail, abort path, suite create/membership/run, and
green/red coverage line decorations.

Refs #1256

Copilot AI lite review requested due to automatic review settings August 26, 2026 02:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds the new Apex Test Runner feature to Jetstream (UI + routing + docs), incorporating fixes identified during live-org browser verification (coverage object name, run progress counting, table height behavior, and coverage source modal behavior).

Changes:

  • Introduces a new @jetstream/feature/apex-test-runner library with test selection, suite management, run monitoring (polling + abort), and coverage viewing (including Monaco line decorations).
  • Wires the feature into app routing + navigation (web app, desktop client, canvas, and browser extension), plus analytics/constants.
  • Adds documentation + landing-page marketing copy and updates e2e routing coverage.

Reviewed changes

Copilot reviewed 48 out of 56 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tsconfig.json Adds TS project reference for the new feature lib.
tsconfig.base.json Adds path alias for @jetstream/feature/apex-test-runner.
libs/types/src/lib/salesforce/apex.types.ts Adds strongly-typed Salesforce Tooling API records for test runs/results/coverage/suites.
libs/shared/ui-router/src/lib/ui-router.ts Adds APEX_TESTS route metadata (path, docs link, “new until”).
libs/shared/ui-core/src/app/HeaderNavbarItems.tsx Adds Apex Test Runner to the header “Developer Tools” menu.
libs/shared/ui-core/src/app/AppHome/AppHome.tsx Adds Apex Test Runner to the home page Developer Tools cards.
libs/shared/constants/src/lib/shared-constants.ts Adds IndexedDB key, analytics events, and page title for Apex Tests.
libs/features/apex-test-runner/vite.config.mts Adds Vitest/Vite config for the feature library.
libs/features/apex-test-runner/tsconfig.spec.json Adds TS config for tests.
libs/features/apex-test-runner/tsconfig.lib.json Adds TS config for library build/typechecking + references.
libs/features/apex-test-runner/tsconfig.json Adds base TS project config for the library.
libs/features/apex-test-runner/src/useApexTestSuites.ts Hook for loading/managing test suites + memberships.
libs/features/apex-test-runner/src/useApexTestRunsList.ts Hook for polling recent test runs and merging optimistic rows.
libs/features/apex-test-runner/src/useApexTestRun.ts Hook for polling a single run’s detail + abort/resume behavior.
libs/features/apex-test-runner/src/useApexTestClasses.ts Hook for discovering/caching org test classes + methods via SymbolTable.
libs/features/apex-test-runner/src/selection/TestSuiteManagerModal.tsx UI for creating/renaming/deleting suites and managing memberships.
libs/features/apex-test-runner/src/selection/TestClassSelectionRow.tsx Row UI for selecting a class and (optionally) individual methods.
libs/features/apex-test-runner/src/selection/TestClassSelection.tsx UI for filtering/selecting test classes (including “unknown” classes).
libs/features/apex-test-runner/src/selection/RunTestsTab.tsx “Run Tests” tab: selection + launching runs + suite execution.
libs/features/apex-test-runner/src/runs/TestRunsTable.tsx Runs list table with progress and selection behavior (capped height support).
libs/features/apex-test-runner/src/runs/TestRunsTab.tsx “Test Runs” tab: refresh/pause, selection, and detail display.
libs/features/apex-test-runner/src/runs/TestRunResultsTable.tsx Per-method results table for a selected run.
libs/features/apex-test-runner/src/runs/TestRunDetail.tsx Selected run detail header, abort/resume controls, queue badges, results.
libs/features/apex-test-runner/src/runs/TestResultDetailModal.tsx Modal for full test failure message/stack trace + debug log link.
libs/features/apex-test-runner/src/runs/test-run-utils.tsx Shared status/outcome badge mapping + duration formatting.
libs/features/apex-test-runner/src/index.ts Public export surface for the feature.
libs/features/apex-test-runner/src/coverage/useCoverageDecorations.ts Monaco editor line/gutter decoration management for coverage.
libs/features/apex-test-runner/src/coverage/CoverageTable.tsx Coverage aggregates table with quick-filter support.
libs/features/apex-test-runner/src/coverage/CoverageTab.tsx “Code Coverage” tab: org-wide + per-class coverage listing + refresh.
libs/features/apex-test-runner/src/coverage/CoverageSourceModal.tsx Fetches and displays source + line-level coverage, with stale-row guidance.
libs/features/apex-test-runner/src/coverage/coverage-utils.ts Coverage percentage calculation helper.
libs/features/apex-test-runner/src/ApexTestRunner.tsx Feature page container (tabs + optimistic run handling + route wiring).
libs/features/apex-test-runner/src/apex-test-runner-types.ts View models and selection/cache types.
libs/features/apex-test-runner/src/apex-test-runner-symbol-table.utils.ts SymbolTable distillation into cached test metadata.
libs/features/apex-test-runner/src/apex-test-runner-data.utils.ts Tooling API query builders + fetch/mutate helpers (runs, suites, coverage, abort).
libs/features/apex-test-runner/src/tests/coverage-utils.spec.ts Unit tests for coverage percentage helper.
libs/features/apex-test-runner/src/tests/apex-test-runner-symbol-table.utils.spec.ts Unit tests for SymbolTable distillation behavior.
libs/features/apex-test-runner/src/tests/apex-test-runner-data.utils.spec.ts Unit tests for payload building + SOQL builder behavior.
libs/features/apex-test-runner/README.md Nx-generated library README.
libs/features/apex-test-runner/project.json Nx project definition for the new feature library.
libs/features/apex-test-runner/.babelrc Nx React Babel preset config for the library.
apps/landing/components/landing/feature-data.ts Updates landing-page developer tooling bullets/cards to include test runner.
apps/jetstream/tsconfig.app.json Adds reference to apex-test-runner lib for the main app build.
apps/jetstream/src/app/AppRoutes.tsx Adds lazy-loaded route for /apex-tests in the main app.
apps/jetstream-web-extension/tsconfig.app.json Adds reference to apex-test-runner for extension build.
apps/jetstream-web-extension/src/pages/app/App.tsx Adds extension route for Apex Test Runner.
apps/jetstream-web-extension/src/components/SfdcPageButton.tsx Adds extension quick link to Apex Test Runner.
apps/jetstream-e2e/src/tests/app/routing.spec.ts Adds routing test case for Apex Test Runner menu item.
apps/jetstream-desktop-client/tsconfig.app.json Adds reference to apex-test-runner for desktop client build.
apps/jetstream-desktop-client/src/app/AppRoutes.tsx Adds lazy-loaded route for Apex Test Runner in desktop client.
apps/jetstream-canvas/tsconfig.app.json Adds reference to apex-test-runner for canvas build.
apps/jetstream-canvas/src/app/AppRoutes.tsx Adds lazy-loaded route for Apex Test Runner in canvas app.
apps/docs/sidebars.ts Adds Apex Test Runner doc page to Developer Tools sidebar.
apps/docs/docs/developer/apex-tests.mdx Adds end-user documentation for running tests, suites, runs, and coverage.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread libs/features/apex-test-runner/src/useApexTestRun.ts
Comment thread libs/features/apex-test-runner/src/runs/TestRunsTable.tsx Outdated
Comment thread libs/features/apex-test-runner/src/runs/TestRunResultsTable.tsx Outdated
Comment thread libs/features/apex-test-runner/src/runs/TestResultDetailModal.tsx Outdated
Comment thread libs/features/apex-test-runner/src/useApexTestRunsList.ts
Copilot AI review requested due to automatic review settings August 26, 2026 13:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 48 out of 56 changed files in this pull request and generated no new comments.

Suppressed comments (5)

Previously missed (3) — in code that hasn't changed since the last review.

libs/features/apex-test-runner/src/runs/TestRunResultsTable.tsx:113

  • Row selection in the results table is click-only for keyboard users: the wrapper has role="button" with tabIndex={-1} and no Enter/Space handling.
    libs/features/apex-test-runner/src/runs/TestRunsTable.tsx:107
  • The clickable cell wrapper is not keyboard-accessible: it uses role="button" with tabIndex={-1} and has no Enter/Space handler, so users who rely on keyboard navigation can’t select a row.
    libs/features/apex-test-runner/src/useApexTestRunsList.ts:121
  • Polling error cutoff is off by one: intervalDelay stops polling only when numPollErrors.current > MAX_POLL_ERRORS, meaning it will continue polling at exactly the max error count. If the intent is to stop after hitting the maximum, this should use >=.

libs/features/apex-test-runner/src/runs/TestRunsTable.tsx:113

  • columns is memoized with an empty dependency array but closes over onRowSelection. If the parent ever passes a new handler, the table will keep calling the stale one. Include onRowSelection in the dependency list and remove the exhaustive-deps suppression.
    libs/features/apex-test-runner/src/runs/TestRunResultsTable.tsx:119
  • columns is memoized with [] but references onRowSelection, so the click handler can become stale if onRowSelection changes. Add onRowSelection to the dependency array and drop the eslint suppression.

@jetstream-bot

jetstream-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Went through Copilot's suppressed (low-confidence) comments — one was valid:

  • libs/features/apex-test-runner/src/useApexTestRunsList.ts:121 — fixed, the poll-error cutoff used > so polling continued one extra cycle past MAX_POLL_ERRORS; now >= to match useApexTestRun.

The keyboard-accessibility comments on the two tables don't apply — the grid's built-in keyboard navigation activates role="button" cell content via Enter/Space (tabIndex={-1} is the intended pattern for in-cell controls, which stay out of the page tab order).

Copilot AI review requested due to automatic review settings August 26, 2026 14:38
@paustint
paustint force-pushed the feat/apex-test-runner branch from 6ebef03 to 265b880 Compare August 26, 2026 14:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 49 out of 57 changed files in this pull request and generated 1 comment.

Comment thread libs/features/apex-test-runner/src/selection/RunTestsTab.tsx Outdated
Copilot AI review requested due to automatic review settings August 26, 2026 15:36
@paustint
paustint force-pushed the feat/apex-test-runner branch from 265b880 to 8f28a02 Compare August 26, 2026 15:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

New features-apex-test-runner lib with a placeholder tabbed page at
/apex-tests, wired into the route registry, all four app routers, the
Developer Tools navbar menu, and the home page card. Feature work lands
in follow-up commits.

Refs #1256
Tooling API access for runTestsAsynchronous, run/queue/result polling
queries, coverage aggregates, suite CRUD, and abort (queue items PATCHed
to Aborted). Test-class discovery distills SymbolTables to method lists;
null SymbolTables (class needs recompile) fall back to class-level runs.

Verified live against a dev org: runTestsAsynchronous returns a bare
JSON-quoted job id, and compile failures surface as a CompileFail result
row with MethodName "<compile>".

Refs #1256
Runs list polls all users' ApexTestRunResult rows (5s while a run is
active, 30s idle) so runs started from Dev Console, VS Code, or CI are
visible while in progress. Selecting a run polls status, per-class queue
progress, and per-method results with backoff, stops after a terminal
status, and pauses with a resume button rather than erroring if the run
outlives the polling window. Abort PATCHes remaining queue items.

Refs #1256
Test classes are discovered from a cheap ApexClass manifest query plus
chunked SymbolTable fetches for new/changed classes only, distilled to
method lists and cached per-org in IndexedDB. Classes with a null
SymbolTable (need recompile) allow class-level runs from a collapsed
section. Launching inserts an optimistic Queued row, switches to the
Test Runs tab, and swaps to the real run record once polling finds it.

Refs #1256
Suites and memberships come from ApexTestSuite/TestSuiteMembership
tooling CRUD; membership edits are applied as a composite diff. The
manager modal supports create, rename, delete, and class membership;
the Run Tests toolbar gains a suite picker that runs via suiteids.

Refs #1256
Coverage table computes per-class percentages from
ApexCodeCoverageAggregate (line detail excluded from the list query to
keep the payload small) alongside the org-wide percentage. Clicking a
row opens the class/trigger source in a read-only Monaco editor with
covered/uncovered whole-line decorations plus gutter bars for
color-blind redundancy — decorations are net-new in this repo via
createDecorationsCollection, themed off the slds-color-scheme body
class like MonacoEditor itself.

Refs #1256
- The org-wide coverage tooling object is ApexOrgWideCoverage, not
  OrgWideApexCoverage (query 400'd against a real org).
- MethodsCompleted already includes failed methods, so progress no
  longer double-counts failures ("3 of 2 methods run").
- The capped runs table now disables fillHeight — its viewport-based
  min-height beats max-height in CSS, pushing run detail off screen.
- The coverage source modal explains when Salesforce returns empty
  covered/uncovered line arrays for stale aggregate rows, and shows the
  freshly fetched aggregate counts instead of the possibly-stale table
  row.

Verified end-to-end in the browser against a live org: run launch,
polling, failure detail, abort path, suite create/membership/run, and
green/red coverage line decorations.

Refs #1256
Copilot AI review requested due to automatic review settings August 27, 2026 00:54
@paustint
paustint force-pushed the feat/apex-test-runner branch from 8f28a02 to f835a5c Compare August 27, 2026 00:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 51 out of 59 changed files in this pull request and generated 1 comment.

Comment thread libs/test/e2e-utils/src/lib/pageObjectModels/QueryPage.model.ts
- Select All checkbox (tri-state) above both the test class list and the
  suite membership list, applying only to the visible filtered rows.
- Run options: stop-after-N-failures (maxFailedTests) and skip code
  coverage, passed to runTestsAsynchronous for class and suite runs.
- Suite names validated against Salesforce API-name rules (letters/
  numbers/underscores, starts with a letter, no trailing or double
  underscore, unique) with inline errors.
- Suite rename tunnels PATCH through POST ?_HttpMethod=PATCH — some
  orgs reject a direct PATCH on ApexTestSuite with "MediaType of 'json'
  is not supported" (Dev Console tunnels for the same reason).
- Suite list uses the standard List component (full-row click, standard
  selected styling) and auto-selects the first suite; Manage Suites is
  disabled while suites load after an org change.
- Runs tables: Failures column red/green via slds text color classes,
  Test Time widened, Message column widened with wrapped text and
  dynamic row height via getWrappedTextRowHeight.

Refs #1256
@paustint
paustint force-pushed the feat/apex-test-runner branch from f835a5c to be07b7b Compare August 27, 2026 14:18
Copilot AI review requested due to automatic review settings August 27, 2026 14:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 52 out of 60 changed files in this pull request and generated 3 comments.

Suppressed comments (1)

libs/test/e2e-utils/src/lib/pageObjectModels/QueryPage.model.ts:34

  • Playwright Locator.filter() does not support a { visible: true } option, so this will not compile / will fail at runtime. To scope to the currently visible field list, use a :visible selector (or another supported visibility filter).

Comment thread libs/features/apex-test-runner/src/selection/TestSuitesPopover.tsx
Comment thread libs/features/apex-test-runner/src/runs/TestRunsTab.tsx
@jetstream-bot

jetstream-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Went through Copilot's suppressed (low-confidence) comments from the 8/26 review — the three that never resurfaced as review threads all check out fine against the current branch, so no changes needed:

  • libs/features/apex-test-runner/src/useApexTestRunsList.ts:121 — the polling off-by-one is already fixed: the cutoff now reads numPollErrors.current >= MAX_POLL_ERRORS.
  • libs/features/apex-test-runner/src/runs/TestRunsTable.tsx:107 — keyboard row selection works by design: the grid is a single tab stop, and Enter/Space in navigation mode activates the cell's [role="button"] wrapper via activateCell (ACTIVATABLE_SELECTOR explicitly matches it; tabIndex={-1} is the grid's required in-cell-control pattern per useGridKeyboardNavigation.ts).
  • libs/features/apex-test-runner/src/runs/TestRunResultsTable.tsx:113 — same as above; arrow to any cell in the row and Enter/Space selects it.

The remaining suppressed items duplicated review threads that are already resolved.

@paustint
paustint merged commit 0b47180 into main Aug 30, 2026
17 checks passed
@paustint
paustint deleted the feat/apex-test-runner branch August 30, 2026 22:04
paustint added a commit that referenced this pull request Sep 1, 2026
…etch

A slow, superseded fetch failing after a newer one succeeded could bump
the error counter toward the polling cutoff. Also reword the allOrNone
comment - atomicity is per 25-item batch, not across the whole diff.

Refs #2005
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