Use SDK when
Your verification needs are specific, but the result still needs to be readable by agents, CI, and Cloud.
Agents write plain TypeScript your team can review, refactor, debug, and keep in the repo.
Expose GraphQL, browser steps, auth helpers, or internal clients without teaching agents a second system.
Local runs, CI, browser steps, and Cloud share the same runtime, trace model, and verification structure.
The core SDK gives agents the parts that make tests auditable: requests, assertions, secrets, templating, structured traces, and useful failure diffs. Plugins add scope without removing those evidence surfaces.
import { test } from "@glubean/sdk";
test("list products", async (ctx) => {
const base = ctx.vars.require("BASE_URL");
const data = await ctx.http
.get(`${base}/products?limit=5`)
.json();
ctx.expect(data.products.length).toBe(5);
ctx.log(`Found ${data.total} products`);
});Use official packages when they fit, then add your own organization-specific capabilities without leaving the shared runtime. The point is not a pile of adapters. The point is one runtime that keeps evidence consistent as it absorbs more of your stack.
@glubean/graphql
Keep GraphQL queries and mutations inside the same traced evidence loop you already use for HTTP.
@glubean/browser
Extend evidence-backed verification into Puppeteer-powered browser steps without losing structure.
@glubean/grpc
Typed gRPC client with proto-first DX, full trace and metadata capture out of the box.
@glubean/auth
OAuth, API key, and custom auth flows as a shared plugin — configure once, use everywhere.
Your own plugin
Wrap internal services, auth flows, or domain helpers as shared capabilities for the whole team.
GraphQL stays inside the same trace model
import { test, configure } from "@glubean/sdk";
import { graphql } from "@glubean/graphql";
const { gql } = configure({
plugins: {
gql: graphql({
endpoint: "{{GRAPHQL_URL}}",
headers: { Authorization: "Bearer {{API_KEY}}" },
}),
},
});
export const getUser = test("get-user", async (ctx) => {
const { data } = await gql.query<{ user: { name: string } }>(`
query GetUser($id: ID!) {
user(id: $id) { name email }
}
`, { variables: { id: "1" } });
ctx.expect(data?.user.name).toBe("Alice");
});Browser steps stay inside the same evidence loop
import { test, configure } from "@glubean/sdk";
import { browser } from "@glubean/browser";
const { chrome } = configure({
plugins: { chrome: browser({ launch: true }) },
});
const ui = test.extend({
page: async (ctx, use) => {
const pg = await chrome.newPage(ctx);
try { await use(pg); }
finally { await pg.close(); }
},
});
export const login = ui("login-flow", async (ctx) => {
await ctx.page.goto("/login");
await ctx.page.type("#email", "user@test.com");
await ctx.page.type("#password", "secret");
await ctx.page.clickAndNavigate('button[type="submit"]');
await ctx.page.expectURL("/dashboard");
await ctx.page.expectText("h1", "Welcome back");
});Wrap an internal service client, auth helper, or domain-specific primitive once, then expose it as a shared capability. This is the difference between a convenient test file and a testing system that compounds.
import { definePlugin, configure, test } from "@glubean/sdk";
const payments = (opts: { baseUrlKey: string }) =>
definePlugin((runtime) => {
const client = runtime.http.extend({
prefixUrl: runtime.requireVar(opts.baseUrlKey),
headers: {
Authorization: `Bearer ${runtime.requireSecret("STRIPE_KEY")}`,
},
});
return {
charge: (amount: number) =>
client.post("charges", { json: { amount } }).json(),
refund: (id: string) =>
client.post(`charges/${id}/refund`).json(),
};
});
const { pay } = configure({
plugins: { pay: payments({ baseUrlKey: "PAYMENTS_URL" }) },
});
export const chargeAndRefund = test("charge-refund", async (ctx) => {
const charge = await pay.charge(2500);
ctx.expect(charge.status).toBe("succeeded");
const refund = await pay.refund(charge.id);
ctx.expect(refund.status).toBe("refunded");
});Official packages and custom plugins join in one configure() call. That keeps the evidence surface consistent across local runs, CI, and Cloud.
const { gql, chrome, pay } = configure({
plugins: {
gql: graphql({ endpoint: "{{GQL_URL}}" }),
chrome: browser({ launch: true }),
pay: payments({ baseUrlKey: "PAY_URL" }),
},
});Glubean runs on Node.js with native TypeScript support — no build step required. The entire npm ecosystem is available, so any package you already use works out of the box. The practical rule is simple: if you can import it, it is a good plugin candidate. When you need heavier browser coverage, keep Playwright where it fits and use Glubean where shared proof and evidence matter more.
When you want exact APIs, published packages, or product-specific surfaces, jump to the right layer.
API reference and deeper guides when you want exact surfaces and package details.
Read docsBrowse the published packages directly when you want the install surface and version history.
Open npmSee how the same SDK model supports local audit, browser scope, and Cloud diagnosis.
See extension