@coldtea/qa 0.1.0 → 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.
Files changed (3) hide show
  1. package/README.md +6 -0
  2. package/dist/main.js +55 -35
  3. package/package.json +3 -2
package/README.md CHANGED
@@ -4,6 +4,10 @@ Run Coldtea QA from a terminal or CI: manage projects, tests and groups,
4
4
  start runs and follow them to a verdict, upload mobile builds, merge
5
5
  projects. Every command talks to the public `/v1` API and nothing else.
6
6
 
7
+ The package installs two names for the same binary: `coldtea-qa`, and
8
+ `cqa` for short — fewer tokens for the agents that call it most. Every
9
+ example below works with either spelling.
10
+
7
11
  ## Install
8
12
 
9
13
  The CLI is TypeScript with **zero runtime dependencies**, compiled to
@@ -194,6 +198,8 @@ coldtea-qa run test mqt_… --wait --timeout 10m
194
198
  coldtea-qa run group mqg_… --wait
195
199
  coldtea-qa runs list --project prj_… --status completed --outcome failed --since 2026-08-01
196
200
 
201
+ cqa runs list --environment env_… # only runs that opened in one place
202
+ cqa tests list --search "saved card" # search titles and descriptions
197
203
  coldtea-qa run test mqt_… --wait --environment env_… # run in one place
198
204
  coldtea-qa run test mqt_… --wait --environment none # run signed out
199
205
  coldtea-qa run group mqg_… --wait \
package/dist/main.js CHANGED
@@ -335,6 +335,37 @@ function renderTable(headers, rows) {
335
335
  return [renderRow(headers), ...rows.map(renderRow)].join("\n");
336
336
  }
337
337
 
338
+ // ../cli-core/src/duration.ts
339
+ var DURATION_PATTERN = /^(\d+)(ms|s|m|h|d)?$/;
340
+ var UNIT_MS = {
341
+ ms: 1,
342
+ s: 1e3,
343
+ m: 6e4,
344
+ h: 36e5,
345
+ d: 864e5
346
+ };
347
+ function parseDuration(raw) {
348
+ const match = DURATION_PATTERN.exec(raw.trim());
349
+ if (!match) {
350
+ return null;
351
+ }
352
+ const value = Number(match[1]);
353
+ const ms = value * UNIT_MS[match[2] ?? "s"];
354
+ return ms > 0 ? ms : null;
355
+ }
356
+ function formatDuration(ms) {
357
+ if (ms % 36e5 === 0) {
358
+ return `${ms / 36e5}h`;
359
+ }
360
+ if (ms % 6e4 === 0) {
361
+ return `${ms / 6e4}m`;
362
+ }
363
+ if (ms % 1e3 === 0) {
364
+ return `${ms / 1e3}s`;
365
+ }
366
+ return `${ms}ms`;
367
+ }
368
+
338
369
  // ../cli-core/src/config.ts
339
370
  var API_KEY_ENV_VAR = "COLDTEA_API_KEY";
340
371
  var API_KEY_PREFIX = "coldtea_sk_";
@@ -1180,7 +1211,8 @@ var projectCommands = [
1180
1211
  var TESTS_HELP = `coldtea-qa tests \u2014 manage QA tests
1181
1212
 
1182
1213
  Usage
1183
- coldtea-qa tests list [--group <groupId>] [--limit <n>] [--cursor <c>]
1214
+ coldtea-qa tests list [--group <groupId>] [--search <text>] [--limit <n>]
1215
+ [--cursor <c>]
1184
1216
  coldtea-qa tests create <description> (--url <url> | --deployment | --mobile <android|ios>)
1185
1217
  [--title <t>] [--group <groupId>]
1186
1218
  coldtea-qa tests get <testId>
@@ -1189,6 +1221,8 @@ Usage
1189
1221
  coldtea-qa tests delete <testId>
1190
1222
 
1191
1223
  Flags
1224
+ --search On list: only tests whose title or description contains
1225
+ this text, case-insensitively.
1192
1226
  --group On list: only this group's tests. On create/update: the
1193
1227
  group the test belongs to (update --group moves it).
1194
1228
  --url create: the page a static_url test opens.
@@ -1272,7 +1306,11 @@ var testsList = {
1272
1306
  words: ["tests", "list"],
1273
1307
  summary: "tests list List a project's tests",
1274
1308
  help: TESTS_HELP,
1275
- flags: { ...LIST_FLAGS, group: { type: "string" } },
1309
+ flags: {
1310
+ ...LIST_FLAGS,
1311
+ group: { type: "string" },
1312
+ search: { type: "string" }
1313
+ },
1276
1314
  async run(context, output, args) {
1277
1315
  const key = requireApiKey2(context, output);
1278
1316
  if (!key.ok) {
@@ -1286,6 +1324,9 @@ var testsList = {
1286
1324
  if (typeof args.values.group === "string") {
1287
1325
  query.push(`groupId=${encodeURIComponent(args.values.group)}`);
1288
1326
  }
1327
+ if (typeof args.values.search === "string") {
1328
+ query.push(`q=${encodeURIComponent(args.values.search)}`);
1329
+ }
1289
1330
  const suffix = query.length > 0 ? `?${query.join("&")}` : "";
1290
1331
  const result = await api(context, key.value, {
1291
1332
  method: "GET",
@@ -1821,36 +1862,6 @@ function deriveClientRequestId(testId, options = {}) {
1821
1862
  return `mqcr_${testId}_${suffix}`;
1822
1863
  }
1823
1864
 
1824
- // src/duration.ts
1825
- var DURATION_PATTERN = /^(\d+)(ms|s|m|h)?$/;
1826
- var UNIT_MS = {
1827
- ms: 1,
1828
- s: 1e3,
1829
- m: 6e4,
1830
- h: 36e5
1831
- };
1832
- function parseDuration(raw) {
1833
- const match = DURATION_PATTERN.exec(raw.trim());
1834
- if (!match) {
1835
- return null;
1836
- }
1837
- const value = Number(match[1]);
1838
- const ms = value * UNIT_MS[match[2] ?? "s"];
1839
- return ms > 0 ? ms : null;
1840
- }
1841
- function formatDuration(ms) {
1842
- if (ms % 36e5 === 0) {
1843
- return `${ms / 36e5}h`;
1844
- }
1845
- if (ms % 6e4 === 0) {
1846
- return `${ms / 6e4}m`;
1847
- }
1848
- if (ms % 1e3 === 0) {
1849
- return `${ms / 1e3}s`;
1850
- }
1851
- return `${ms}ms`;
1852
- }
1853
-
1854
1865
  // src/poll.ts
1855
1866
  var DEFAULT_POLL_INTERVAL_MS = 3e3;
1856
1867
  var FAILURE_TOLERANCE = 3;
@@ -2457,6 +2468,9 @@ Filters
2457
2468
  couldnt_verify, couldnt_run
2458
2469
  --since <when> Only runs created at/after this moment \u2014 epoch
2459
2470
  milliseconds or an ISO-8601 date/time
2471
+ --environment <id> Only runs that opened in this environment; combines
2472
+ with any scope. Filtered pages can run short \u2014 follow
2473
+ nextCursor, never row counts
2460
2474
 
2461
2475
  Newest first. With no scope, the whole organization's runs.
2462
2476
 
@@ -2547,7 +2561,8 @@ var runsList = {
2547
2561
  batch: { type: "string" },
2548
2562
  status: { type: "string" },
2549
2563
  outcome: { type: "string" },
2550
- since: { type: "string" }
2564
+ since: { type: "string" },
2565
+ environment: { type: "string" }
2551
2566
  },
2552
2567
  async run(context, output, args) {
2553
2568
  const explicitScopes = ["test", "group", "batch"].filter(
@@ -2571,6 +2586,11 @@ var runsList = {
2571
2586
  } else if (context.projectId !== null) {
2572
2587
  query.push(`projectId=${encodeURIComponent(context.projectId)}`);
2573
2588
  }
2589
+ if (typeof args.values.environment === "string") {
2590
+ query.push(
2591
+ `environmentId=${encodeURIComponent(args.values.environment)}`
2592
+ );
2593
+ }
2574
2594
  if (typeof args.values.status === "string") {
2575
2595
  query.push(`status=${encodeURIComponent(args.values.status)}`);
2576
2596
  }
@@ -4640,7 +4660,7 @@ var skipsList = {
4640
4660
  var appCommands = [appsList, skipsList];
4641
4661
 
4642
4662
  // src/main.ts
4643
- var CLI_VERSION = "0.1.0";
4663
+ var CLI_VERSION = "0.1.2";
4644
4664
  var WHOAMI_HELP = `coldtea-qa whoami \u2014 show the organization and key
4645
4665
 
4646
4666
  Usage
@@ -4674,7 +4694,7 @@ var ALL_COMMANDS = [
4674
4694
  var USAGE = `coldtea-qa \u2014 Coldtea QA from the command line
4675
4695
 
4676
4696
  Usage
4677
- coldtea-qa <command> [flags]
4697
+ cqa <command> [flags] (cqa and coldtea-qa are the same binary)
4678
4698
 
4679
4699
  Start here
4680
4700
  1 coldtea-qa whoami who you are, and what your key can do
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@coldtea/qa",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "The coldtea-qa command line: run Coldtea QA from a terminal or CI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "bin": {
8
- "coldtea-qa": "./bin/coldtea-qa.mjs"
8
+ "coldtea-qa": "bin/coldtea-qa.mjs",
9
+ "cqa": "bin/coldtea-qa.mjs"
9
10
  },
10
11
  "scripts": {
11
12
  "build": "node build.mjs",