Test infrastructure helpers for Colibri packages.
The main public API is StellarTestLedger, a Docker-backed harness that starts,
reuses, inspects, stops, and destroys a Stellar Quickstart instance for
integration tests.
deno add jsr:@colibri/test-tooling- A reachable Docker daemon such as Docker Desktop or OrbStack
- Permission to pull the
stellar/quickstartimage - An environment where local Docker-backed integration tests are allowed to run
import { StellarTestLedger } from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger();
try {
await ledger.start();
const details = await ledger.getNetworkDetails();
console.log(details.rpcUrl);
} finally {
await ledger.stop();
await ledger.destroy();
}By default, StellarTestLedger starts a local standalone Quickstart container
with:
containerImageVersion: "latest"network: NetworkEnv.LOCALlimits: ResourceLimits.TESTNETenabledServices: ["core", "horizon", "rpc"]- ephemeral storage
start() waits only for the services implied by the selected network and
enabled services. For the default local setup, that means Horizon, Soroban RPC,
and Friendbot are ready before start() resolves.
Use containerImageVersion for any Quickstart tag string.
For the common moving tags, use QuickstartImageTags:
import {
QuickstartImageTags,
StellarTestLedger,
} from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger({
containerImageVersion: QuickstartImageTags.TESTING,
});For pinned builds or older tag shapes, pass the tag directly:
const ledger = new StellarTestLedger({
containerImageVersion: "v632-b942.1-testing",
});This package intentionally does not allow-list all tag formats. Quickstart publishes moving aliases, immutable build tags, and may introduce new tag shapes over time.
Quickstart network mode is selected with network:
import {
NetworkEnv,
QuickstartServices,
StellarTestLedger,
} from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger({
network: NetworkEnv.TESTNET,
enabledServices: [
QuickstartServices.HORIZON,
QuickstartServices.RPC,
QuickstartServices.LAB,
] as const,
});Supported network modes:
NetworkEnv.LOCAL: fastest and best for deterministic testsNetworkEnv.TESTNET: supported, but startup can take longer because Quickstart must sync external network stateNetworkEnv.FUTURENET: supported, but startup can also take longer for the same reason
limits only applies to NetworkEnv.LOCAL.
Use enabledServices to control the Quickstart --enable set:
import {
QuickstartServices,
StellarTestLedger,
} from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger({
enabledServices: [
QuickstartServices.RPC,
QuickstartServices.GALEXIE,
] as const,
});
await ledger.start();
const details = await ledger.getNetworkDetails();
console.log(details.rpcUrl);
console.log(details.horizonUrl);
console.log(details.friendbotUrl);
console.log(details.ledgerMetaUrl);The returned getNetworkDetails() shape follows the selected network and
service tuple. To keep the narrowest TypeScript type, pass enabledServices as
const.
Quickstart service URLs are exposed through published HTTP ports, so
getNetworkDetails() always includes allowHttp: true.
Examples:
- Local default services return
horizonUrl,rpcUrl, andfriendbotUrl - Local
enabledServices: [QuickstartServices.RPC] as constreturnshorizonUrl,rpcUrl, andfriendbotUrl - Local
enabledServices: [QuickstartServices.RPC, QuickstartServices.GALEXIE] as constalso returnsledgerMetaUrl - Futurenet
enabledServices: [QuickstartServices.LAB] as constreturnslabUrl,transactionsExplorerUrl, andfriendbotUrl
Notes:
QuickstartServices.GALEXIEis local-onlyQuickstartServices.GALEXIEmust be paired withQuickstartServices.RPC- core-only service selections are rejected because this harness resolves the Quickstart HTTP surface, not raw Stellar Core admin ports
When Lab is enabled, getNetworkDetails() includes:
labUrltransactionsExplorerUrl
When Galexie is enabled on local mode, getNetworkDetails() includes:
ledgerMetaUrl
Use storage to switch from the default ephemeral container to a mounted
persistent volume:
import {
QuickstartStorageModes,
StellarTestLedger,
} from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger({
storage: {
mode: QuickstartStorageModes.PERSISTENT,
hostPath: "/absolute/path/to/stellar-data",
},
});Persistent mode mounts hostPath into /opt/stellar.
Use it carefully:
- Quickstart's on-disk layout can change between image releases
- first-time initialization of an empty persistent directory can be more operationally sensitive than ephemeral mode
- pinned image tags are safer than moving tags when reusing persistent data
If you already have a matching quickstart container running, you can attach to it by name instead of starting a new one:
import { StellarTestLedger } from "jsr:@colibri/test-tooling";
const ledger = new StellarTestLedger({
containerName: "colibri-stellar-test-ledger",
useRunningLedger: true,
});
await ledger.start();
const details = await ledger.getNetworkDetails();
console.log(details.horizonUrl);When useRunningLedger is enabled:
start()fails if the named container does not exist, is not running, or uses a different imagestop()anddestroy()become no-ops so the harness does not shut down or delete a container it did not create
StellarTestLedger resolves Docker in this order:
- Explicit
dockerOptions - Explicit
dockerSocketPath DOCKER_HOST- Auto-detected local sockets such as
/var/run/docker.sockand OrbStack
Example with an explicit socket:
const ledger = new StellarTestLedger({
dockerSocketPath: "/var/run/docker.sock",
});You can also provide explicit Dockerode connection options:
const ledger = new StellarTestLedger({
dockerOptions: {
socketPath: "/var/run/docker.sock",
},
});containerNamecontrols the Docker container name used for create/reusecontainerImageNameandcontainerImageVersionselect the Quickstart imagenetworkselects local, testnet, or futurenet modelimitsselects the local standalone resource profileenabledServicescontrols the Quickstart--enableliststorageswitches between ephemeral and persistent modeuseRunningLedgerattaches to an existing named container instead of creating onedockerOptionsanddockerSocketPathoverride Docker endpoint discoveryemitContainerLogsforwards container stdout/stderr into the configured loggerloggeraccepts a custom logger withtrace,debug,info,warn, anderrormethodslogLevelconfigures the built-in fallback logger and is ignored whenloggeris provided
new StellarTestLedger(options)creates a quickstart ledger managerledger.start(omitPull?)starts or reuses the Docker container and waits until the requested services are readyledger.getNetworkDetails()returns the plain service payload for the running ledgerledger.getNetworkConfiguration()is an alias ofgetNetworkDetails()ledger.getContainer()returns the Dockerode container instanceledger.getContainerIpAddress()returns the container IP reported by Dockerledger.stop()stops the tracked container without deleting itledger.destroy()removes the tracked container and its named volumes
If you want to integrate with your own logger, pass a LoggerLike
implementation:
const logger = {
trace: (...msg: unknown[]) => console.debug("[ledger:trace]", ...msg),
debug: (...msg: unknown[]) => console.debug("[ledger:debug]", ...msg),
info: (...msg: unknown[]) => console.info("[ledger:info]", ...msg),
warn: (...msg: unknown[]) => console.warn("[ledger:warn]", ...msg),
error: (...msg: unknown[]) => console.error("[ledger:error]", ...msg),
};
const ledger = new StellarTestLedger({
logger,
emitContainerLogs: true,
});The package standardizes its runtime failures with quickstart-specific error subclasses exported from the package root:
INVALID_CONFIGURATIONDOCKER_CONFIGURATION_ERRORCONTAINER_ERRORIMAGE_ERRORREADINESS_ERROR
These errors include stable codes, a source of
@colibri/test-tooling/quickstart, and metadata with the original cause and
structured payload.