Testing Tkeron Projects

Overview

Tkeron provides a getBuildResult() function that lets you test your built projects programmatically. Verify that your components, pre-rendering scripts, and build output work correctly.

Setup

bun install -d tkeron

API

import { getBuildResult, type BuildResult } from "tkeron";

const result: BuildResult = await getBuildResult("./websrc");

BuildResult

getBuildResult() returns a Record<string, FileInfo> indexed by relative path:

interface FileInfo {
  fileName: string; // "index.html"
  filePath: string; // "styles" or "" for root
  path: string; // "styles/main.css" (the key)
  type: string; // MIME type
  size: number; // Size in bytes
  fileHash: string; // SHA-256 hash
  getContentAsString?: () => string; // Text files only
  dom?: Document; // HTML files only — parsed DOM
}

Test Structure

Always build once and share the result across tests:

import { describe, it, expect, beforeAll } from "bun:test";
import { getBuildResult, type BuildResult } from "tkeron";
import { join } from "path";

describe("my project", () => {
  const sourcePath = join(import.meta.dir, "src");
  let result: BuildResult;

  beforeAll(async () => {
    result = await getBuildResult(sourcePath);
  });

  it("should generate index.html", () => {
    expect(result?.["index.html"]).toBeDefined();
  });
});

Never call getBuildResult() inside each it() — causes race conditions in concurrent mode.

Testing Patterns

Verify File Existence

it("should generate expected files", () => {
  expect(result?.["index.html"]).toBeDefined();
  expect(result?.["index.js"]).toBeDefined();
  expect(result?.["styles/main.css"]).toBeDefined();
});

Verify DOM Elements

it("should have page title", () => {
  const dom = result?.["index.html"]?.dom;
  const title = dom?.querySelector("title");
  expect(title).toBeDefined();
  expect(title!.textContent).toBe("My App");
});

Verify Component Substitution

it("should have processed nav component", () => {
  const dom = result?.["index.html"]?.dom;
  const nav = dom?.querySelector("nav");
  expect(nav).toBeDefined();

  const links = dom?.querySelectorAll("nav a");
  expect(links!.length).toBeGreaterThan(0);
});

Verify Pre-rendering

it("should have pre-rendered content", () => {
  const dom = result?.["index.html"]?.dom;
  const generated = dom?.querySelector("#generated-content");
  expect(generated).toBeDefined();
  expect(generated!.textContent).not.toBe("");
});

Verify Script Injection

it("should have compiled script", () => {
  const dom = result?.["index.html"]?.dom;
  const script = dom?.querySelector('script[type="module"]');
  expect(script).toBeDefined();
  expect(script!.getAttribute("src")).toBe("./index.js");
});

Rules Summary

  1. Build once with beforeAll() — never inside individual tests
  2. Check existence firstexpect(element).toBeDefined() before properties
  3. Use optional chaining (?.) for safe access
  4. Test bounded content — Specific values, not full output strings
  5. Concurrent-safe — Tests must work with bun test --concurrent

Complete Example

import { describe, it, expect, beforeAll } from "bun:test";
import { getBuildResult, type BuildResult } from "tkeron";
import { join } from "path";

describe("my-website build", () => {
  const sourcePath = join(import.meta.dir, "websrc");
  let result: BuildResult;

  beforeAll(async () => {
    result = await getBuildResult(sourcePath);
  });

  it("should generate expected files", () => {
    expect(result?.["index.html"]).toBeDefined();
    expect(result?.["index.js"]).toBeDefined();
  });

  it("should have page title", () => {
    const title = result?.["index.html"]?.dom?.querySelector("title");
    expect(title).toBeDefined();
    expect(title!.textContent).toBe("My Website");
  });

  it("should have navigation from component", () => {
    const dom = result?.["index.html"]?.dom;
    const homeLink = dom?.querySelector('nav a[href="/"]');
    expect(homeLink).toBeDefined();
    expect(homeLink!.textContent).toBe("Home");
  });

  it("should have compiled JavaScript", () => {
    const js = result?.["index.js"]?.getContentAsString!();
    expect(js).toBeDefined();
    expect(js!.length).toBeGreaterThan(0);
  });
});

Next Steps