@glubean/cli 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/gb.js +2 -0
- package/dist/commands/init.d.ts +19 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +842 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +10 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +75 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/patch.d.ts +8 -0
- package/dist/commands/patch.d.ts.map +1 -0
- package/dist/commands/patch.js +73 -0
- package/dist/commands/patch.js.map +1 -0
- package/dist/commands/run.d.ts +26 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +1093 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/scan.d.ts +6 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +62 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/spec_split.d.ts +5 -0
- package/dist/commands/spec_split.d.ts.map +1 -0
- package/dist/commands/spec_split.js +56 -0
- package/dist/commands/spec_split.js.map +1 -0
- package/dist/commands/sync.d.ts +13 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +252 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/trigger.d.ts +13 -0
- package/dist/commands/trigger.d.ts.map +1 -0
- package/dist/commands/trigger.js +213 -0
- package/dist/commands/trigger.js.map +1 -0
- package/dist/commands/validate_metadata.d.ts +6 -0
- package/dist/commands/validate_metadata.d.ts.map +1 -0
- package/dist/commands/validate_metadata.js +103 -0
- package/dist/commands/validate_metadata.js.map +1 -0
- package/dist/commands/worker.d.ts +14 -0
- package/dist/commands/worker.d.ts.map +1 -0
- package/dist/commands/worker.js +10 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/lib/auth.d.ts +39 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +82 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/ci.d.ts +12 -0
- package/dist/lib/ci.d.ts.map +1 -0
- package/dist/lib/ci.js +42 -0
- package/dist/lib/ci.js.map +1 -0
- package/dist/lib/config.d.ts +116 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +264 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/constants.d.ts +6 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +6 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/env.d.ts +19 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +40 -0
- package/dist/lib/env.js.map +1 -0
- package/dist/lib/git.d.ts +8 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +68 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/openapi_patch.d.ts +23 -0
- package/dist/lib/openapi_patch.d.ts.map +1 -0
- package/dist/lib/openapi_patch.js +232 -0
- package/dist/lib/openapi_patch.js.map +1 -0
- package/dist/lib/openapi_split.d.ts +16 -0
- package/dist/lib/openapi_split.d.ts.map +1 -0
- package/dist/lib/openapi_split.js +188 -0
- package/dist/lib/openapi_split.js.map +1 -0
- package/dist/lib/upload.d.ts +44 -0
- package/dist/lib/upload.d.ts.map +1 -0
- package/dist/lib/upload.js +297 -0
- package/dist/lib/upload.js.map +1 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +319 -0
- package/dist/main.js.map +1 -0
- package/dist/metadata.d.ts +17 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +61 -0
- package/dist/metadata.js.map +1 -0
- package/dist/update_check.d.ts +14 -0
- package/dist/update_check.d.ts.map +1 -0
- package/dist/update_check.js +130 -0
- package/dist/update_check.js.map +1 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +34 -0
- package/templates/AI-INSTRUCTIONS.md +163 -0
- package/templates/README.md +226 -0
- package/templates/claude-skill-glubean-test.md +382 -0
- package/templates/data/create-user.json +14 -0
- package/templates/data/endpoints.csv +5 -0
- package/templates/data/scenarios.yaml +19 -0
- package/templates/data/search-examples.json +14 -0
- package/templates/data/users.json +17 -0
- package/templates/data-driven.test.ts.tpl +118 -0
- package/templates/demo.test.result.json +398 -0
- package/templates/demo.test.ts.tpl +226 -0
- package/templates/explore-api.test.result.json +79 -0
- package/templates/minimal/README.md +42 -0
- package/templates/minimal-api.test.ts.tpl +42 -0
- package/templates/minimal-auth.test.ts.tpl +45 -0
- package/templates/minimal-search.test.ts.tpl +34 -0
- package/templates/openapi.sample.json +97 -0
- package/templates/pick.test.result.json +165 -0
- package/templates/pick.test.ts.tpl +126 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"target": "/Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts",
|
|
3
|
+
"files": [
|
|
4
|
+
"packages/cli/templates/pick.test.ts"
|
|
5
|
+
],
|
|
6
|
+
"runAt": "2026-02-16 13:46:18",
|
|
7
|
+
"summary": {
|
|
8
|
+
"total": 3,
|
|
9
|
+
"passed": 0,
|
|
10
|
+
"failed": 3,
|
|
11
|
+
"skipped": 0,
|
|
12
|
+
"durationMs": 101,
|
|
13
|
+
"stats": {
|
|
14
|
+
"httpRequestTotal": 0,
|
|
15
|
+
"httpErrorTotal": 0,
|
|
16
|
+
"assertionTotal": 0,
|
|
17
|
+
"assertionFailed": 0,
|
|
18
|
+
"warningTotal": 0,
|
|
19
|
+
"warningTriggered": 0,
|
|
20
|
+
"stepTotal": 0,
|
|
21
|
+
"stepPassed": 0,
|
|
22
|
+
"stepFailed": 0
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"tests": [
|
|
26
|
+
{
|
|
27
|
+
"testId": "add-product-basic",
|
|
28
|
+
"testName": "add-product-basic",
|
|
29
|
+
"success": false,
|
|
30
|
+
"durationMs": 34,
|
|
31
|
+
"events": [
|
|
32
|
+
{
|
|
33
|
+
"type": "log",
|
|
34
|
+
"message": "Loading test module: file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"type": "start",
|
|
38
|
+
"id": "add-product-premium",
|
|
39
|
+
"name": "add-product-premium"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"type": "summary",
|
|
43
|
+
"data": {
|
|
44
|
+
"httpRequestTotal": 0,
|
|
45
|
+
"httpErrorTotal": 0,
|
|
46
|
+
"httpErrorRate": 0,
|
|
47
|
+
"assertionTotal": 0,
|
|
48
|
+
"assertionFailed": 0,
|
|
49
|
+
"warningTotal": 0,
|
|
50
|
+
"warningTriggered": 0,
|
|
51
|
+
"schemaValidationTotal": 0,
|
|
52
|
+
"schemaValidationFailed": 0,
|
|
53
|
+
"schemaValidationWarnings": 0,
|
|
54
|
+
"stepTotal": 0,
|
|
55
|
+
"stepPassed": 0,
|
|
56
|
+
"stepFailed": 0,
|
|
57
|
+
"stepSkipped": 0
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"type": "status",
|
|
62
|
+
"status": "failed",
|
|
63
|
+
"error": "Missing required var: BASE_URL",
|
|
64
|
+
"stack": "Error: Missing required var: BASE_URL\n at Object.require (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:360:15)\n at file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts:84:26\n at Object.fn (file:///Users/peisong/glubean/oss/packages/sdk/mod.ts:1011:36)\n at executeNewTest (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:1192:18)\n at file:///Users/peisong/glubean/oss/packages/runner/harness.ts:971:11"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"type": "error",
|
|
68
|
+
"message": "Process exited with code 1"
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"testId": "create-user-normal",
|
|
74
|
+
"testName": "create-user-normal",
|
|
75
|
+
"success": false,
|
|
76
|
+
"durationMs": 34,
|
|
77
|
+
"events": [
|
|
78
|
+
{
|
|
79
|
+
"type": "log",
|
|
80
|
+
"message": "Loading test module: file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts"
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"type": "start",
|
|
84
|
+
"id": "create-user-young",
|
|
85
|
+
"name": "create-user-young"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "summary",
|
|
89
|
+
"data": {
|
|
90
|
+
"httpRequestTotal": 0,
|
|
91
|
+
"httpErrorTotal": 0,
|
|
92
|
+
"httpErrorRate": 0,
|
|
93
|
+
"assertionTotal": 0,
|
|
94
|
+
"assertionFailed": 0,
|
|
95
|
+
"warningTotal": 0,
|
|
96
|
+
"warningTriggered": 0,
|
|
97
|
+
"schemaValidationTotal": 0,
|
|
98
|
+
"schemaValidationFailed": 0,
|
|
99
|
+
"schemaValidationWarnings": 0,
|
|
100
|
+
"stepTotal": 0,
|
|
101
|
+
"stepPassed": 0,
|
|
102
|
+
"stepFailed": 0,
|
|
103
|
+
"stepSkipped": 0
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"type": "status",
|
|
108
|
+
"status": "failed",
|
|
109
|
+
"error": "Missing required var: BASE_URL",
|
|
110
|
+
"stack": "Error: Missing required var: BASE_URL\n at Object.require (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:360:15)\n at file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts:112:26\n at Object.fn (file:///Users/peisong/glubean/oss/packages/sdk/mod.ts:1011:36)\n at executeNewTest (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:1192:18)\n at file:///Users/peisong/glubean/oss/packages/runner/harness.ts:971:11"
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
"type": "error",
|
|
114
|
+
"message": "Process exited with code 1"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"testId": "search-products-by-category",
|
|
120
|
+
"testName": "search-products-by-category",
|
|
121
|
+
"success": false,
|
|
122
|
+
"durationMs": 33,
|
|
123
|
+
"events": [
|
|
124
|
+
{
|
|
125
|
+
"type": "log",
|
|
126
|
+
"message": "Loading test module: file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"type": "start",
|
|
130
|
+
"id": "search-products-by-category",
|
|
131
|
+
"name": "search-products-by-category"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"type": "summary",
|
|
135
|
+
"data": {
|
|
136
|
+
"httpRequestTotal": 0,
|
|
137
|
+
"httpErrorTotal": 0,
|
|
138
|
+
"httpErrorRate": 0,
|
|
139
|
+
"assertionTotal": 0,
|
|
140
|
+
"assertionFailed": 0,
|
|
141
|
+
"warningTotal": 0,
|
|
142
|
+
"warningTriggered": 0,
|
|
143
|
+
"schemaValidationTotal": 0,
|
|
144
|
+
"schemaValidationFailed": 0,
|
|
145
|
+
"schemaValidationWarnings": 0,
|
|
146
|
+
"stepTotal": 0,
|
|
147
|
+
"stepPassed": 0,
|
|
148
|
+
"stepFailed": 0,
|
|
149
|
+
"stepSkipped": 0
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"type": "status",
|
|
154
|
+
"status": "failed",
|
|
155
|
+
"error": "Missing required var: BASE_URL",
|
|
156
|
+
"stack": "Error: Missing required var: BASE_URL\n at Object.require (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:360:15)\n at file:///Users/peisong/glubean/oss/packages/cli/templates/pick.test.ts:47:26\n at Object.fn (file:///Users/peisong/glubean/oss/packages/sdk/mod.ts:1011:36)\n at executeNewTest (file:///Users/peisong/glubean/oss/packages/runner/harness.ts:1192:18)\n at file:///Users/peisong/glubean/oss/packages/runner/harness.ts:971:11"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"type": "error",
|
|
160
|
+
"message": "Process exited with code 1"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example selection with test.pick — run one example at a time.
|
|
3
|
+
*
|
|
4
|
+
* Unlike test.each (which runs every row), test.pick randomly selects one
|
|
5
|
+
* example from a named map. This is ideal when you have multiple request
|
|
6
|
+
* variations for the same API and want lightweight smoke coverage without
|
|
7
|
+
* running all of them every time.
|
|
8
|
+
*
|
|
9
|
+
* The data inside each example can be anything — query params, JSON body,
|
|
10
|
+
* headers, expected status, or all of the above. You decide the shape.
|
|
11
|
+
*
|
|
12
|
+
* Three patterns are shown:
|
|
13
|
+
*
|
|
14
|
+
* 1. Query-only — different search params for a GET endpoint
|
|
15
|
+
* 2. Body-only — different JSON payloads for a POST endpoint
|
|
16
|
+
* 3. Body + Query — both in one example, loaded from a JSON file
|
|
17
|
+
*
|
|
18
|
+
* In VS Code, CodeLens buttons appear above each test.pick() call,
|
|
19
|
+
* letting you click a specific example to run.
|
|
20
|
+
*
|
|
21
|
+
* Run: glubean run pick.test.ts
|
|
22
|
+
* Pick one: glubean run pick.test.ts --pick by-category
|
|
23
|
+
* Pick N: glubean run pick.test.ts --pick normal,edge-case
|
|
24
|
+
*/
|
|
25
|
+
import { test } from "@glubean/sdk";
|
|
26
|
+
|
|
27
|
+
// Named examples from JSON — each contains body + query together
|
|
28
|
+
import createUserExamples from "../data/create-user.json" with { type: "json" };
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Pattern 1: Query params — different search variations for GET
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Each example defines query params and an expected result.
|
|
36
|
+
* The data shape is entirely up to you — here it's { q, minPrice, expected }.
|
|
37
|
+
*
|
|
38
|
+
* Try: glubean run pick.test.ts --pick by-category
|
|
39
|
+
*/
|
|
40
|
+
export const searchProducts = test.pick({
|
|
41
|
+
"by-name": { q: "phone", minPrice: 0, expected: "phone" },
|
|
42
|
+
"by-category": { q: "laptop", minPrice: 500, expected: "laptop" },
|
|
43
|
+
"empty-query": { q: "", minPrice: 0, expected: "" },
|
|
44
|
+
})(
|
|
45
|
+
"search-products-$_pick",
|
|
46
|
+
async ({ http, vars, expect, log }, { q, minPrice, expected }) => {
|
|
47
|
+
const baseUrl = vars.require("BASE_URL");
|
|
48
|
+
|
|
49
|
+
const res = await http
|
|
50
|
+
.get(`${baseUrl}/products/search`, {
|
|
51
|
+
searchParams: { q, ...(minPrice > 0 && { minPrice }) },
|
|
52
|
+
})
|
|
53
|
+
.json<{ products: { title: string; price: number }[]; total: number }>();
|
|
54
|
+
|
|
55
|
+
expect(res.total).toBeType("number");
|
|
56
|
+
if (expected && res.total > 0) {
|
|
57
|
+
expect(res.products[0].title.toLowerCase()).toContain(expected);
|
|
58
|
+
if (minPrice > 0) {
|
|
59
|
+
expect(res.products[0].price).toBeGreaterThan(minPrice);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
log(`Search "${q}" → ${res.total} results`);
|
|
64
|
+
},
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Pattern 2: JSON body — different payloads for POST
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Each example is a request body for POST /products/add.
|
|
73
|
+
* Notice: no query params here — examples can be any shape you need.
|
|
74
|
+
*
|
|
75
|
+
* Try: glubean run pick.test.ts --pick premium
|
|
76
|
+
*/
|
|
77
|
+
export const addProduct = test.pick({
|
|
78
|
+
"basic": { title: "USB Cable", price: 9.99, category: "accessories" },
|
|
79
|
+
"premium": { title: "Pro Monitor", price: 1299, category: "laptops" },
|
|
80
|
+
"free-tier": { title: "Trial Pack", price: 0, category: "misc" },
|
|
81
|
+
})(
|
|
82
|
+
"add-product-$_pick",
|
|
83
|
+
async ({ http, vars, expect, log }, body) => {
|
|
84
|
+
const baseUrl = vars.require("BASE_URL");
|
|
85
|
+
|
|
86
|
+
const res = await http
|
|
87
|
+
.post(`${baseUrl}/products/add`, { json: body })
|
|
88
|
+
.json<{ id: number; title: string; price: number }>();
|
|
89
|
+
|
|
90
|
+
expect(res.id).toBeDefined();
|
|
91
|
+
expect(res.title).toBe(body.title);
|
|
92
|
+
expect(res.price).toBe(body.price);
|
|
93
|
+
|
|
94
|
+
log(`Created product: ${res.title} ($${res.price}) → id ${res.id}`);
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Pattern 3: Body + Query from JSON file — full request variations
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Each example in create-user.json contains both `body` and `query`,
|
|
104
|
+
* showing that a single example can carry everything needed for a request.
|
|
105
|
+
* You design the data shape — test.pick just selects which one to run.
|
|
106
|
+
*
|
|
107
|
+
* Try: glubean run pick.test.ts --pick edge-case
|
|
108
|
+
*/
|
|
109
|
+
export const createUser = test.pick(createUserExamples)(
|
|
110
|
+
"create-user-$_pick",
|
|
111
|
+
async ({ http, vars, expect, log }, { body, query }) => {
|
|
112
|
+
const baseUrl = vars.require("BASE_URL");
|
|
113
|
+
|
|
114
|
+
const res = await http
|
|
115
|
+
.post(`${baseUrl}/users/add`, {
|
|
116
|
+
json: body,
|
|
117
|
+
searchParams: query,
|
|
118
|
+
})
|
|
119
|
+
.json<{ id: number; firstName: string }>();
|
|
120
|
+
|
|
121
|
+
expect(res.id).toBeDefined();
|
|
122
|
+
expect(res.firstName).toBe(body.firstName);
|
|
123
|
+
|
|
124
|
+
log(`Created user: ${res.firstName || "(empty)"} → id ${res.id}`);
|
|
125
|
+
},
|
|
126
|
+
);
|