@hasna/testers 0.0.38 → 0.0.39
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/dist/cli/index.js +14 -6
- package/dist/index.js +14 -4
- package/dist/lib/screenshotter.d.ts +1 -1
- package/dist/lib/screenshotter.d.ts.map +1 -1
- package/dist/mcp/index.js +14 -6
- package/dist/server/index.js +15 -5
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16697,12 +16697,19 @@ var init_personas = __esm(() => {
|
|
|
16697
16697
|
// src/lib/screenshotter.ts
|
|
16698
16698
|
import { mkdirSync as mkdirSync7, existsSync as existsSync8, writeFileSync as writeFileSync2 } from "fs";
|
|
16699
16699
|
import { join as join10 } from "path";
|
|
16700
|
-
function
|
|
16701
|
-
|
|
16700
|
+
function truncateSlug(slug, maxLength) {
|
|
16701
|
+
if (slug.length <= maxLength)
|
|
16702
|
+
return slug;
|
|
16703
|
+
const truncated = slug.slice(0, maxLength).replace(/-+$/g, "");
|
|
16704
|
+
return truncated || slug.slice(0, maxLength);
|
|
16705
|
+
}
|
|
16706
|
+
function slugify(text, maxLength) {
|
|
16707
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
16708
|
+
return maxLength ? truncateSlug(slug, maxLength) : slug;
|
|
16702
16709
|
}
|
|
16703
16710
|
function generateFilename(stepNumber, action) {
|
|
16704
16711
|
const padded = String(stepNumber).padStart(3, "0");
|
|
16705
|
-
const slug = slugify(action);
|
|
16712
|
+
const slug = slugify(action, MAX_ACTION_SLUG_LENGTH);
|
|
16706
16713
|
return `${padded}_${slug}.png`;
|
|
16707
16714
|
}
|
|
16708
16715
|
function formatDate(date) {
|
|
@@ -16716,7 +16723,8 @@ function getScreenshotDir(baseDir, runId, scenarioSlug, projectName, timestamp)
|
|
|
16716
16723
|
const project = projectName ?? "default";
|
|
16717
16724
|
const dateDir = formatDate(now2);
|
|
16718
16725
|
const timeDir = `${formatTime(now2)}_${runId.slice(0, 8)}`;
|
|
16719
|
-
|
|
16726
|
+
const safeScenarioSlug = slugify(scenarioSlug, MAX_SCENARIO_SLUG_LENGTH) || "scenario";
|
|
16727
|
+
return join10(baseDir, project, dateDir, timeDir, safeScenarioSlug);
|
|
16720
16728
|
}
|
|
16721
16729
|
function ensureDir(dirPath) {
|
|
16722
16730
|
if (!existsSync8(dirPath)) {
|
|
@@ -16874,7 +16882,7 @@ class Screenshotter {
|
|
|
16874
16882
|
};
|
|
16875
16883
|
}
|
|
16876
16884
|
}
|
|
16877
|
-
var DEFAULT_BASE_DIR;
|
|
16885
|
+
var MAX_ACTION_SLUG_LENGTH = 80, MAX_SCENARIO_SLUG_LENGTH = 96, DEFAULT_BASE_DIR;
|
|
16878
16886
|
var init_screenshotter = __esm(() => {
|
|
16879
16887
|
init_paths();
|
|
16880
16888
|
DEFAULT_BASE_DIR = join10(getTestersDir(), "screenshots");
|
|
@@ -93989,7 +93997,7 @@ import chalk6 from "chalk";
|
|
|
93989
93997
|
// package.json
|
|
93990
93998
|
var package_default = {
|
|
93991
93999
|
name: "@hasna/testers",
|
|
93992
|
-
version: "0.0.
|
|
94000
|
+
version: "0.0.39",
|
|
93993
94001
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
93994
94002
|
type: "module",
|
|
93995
94003
|
main: "dist/index.js",
|
package/dist/index.js
CHANGED
|
@@ -13880,12 +13880,21 @@ init_browser_lightpanda();
|
|
|
13880
13880
|
init_paths();
|
|
13881
13881
|
import { mkdirSync as mkdirSync7, existsSync as existsSync8, writeFileSync as writeFileSync2 } from "fs";
|
|
13882
13882
|
import { join as join10 } from "path";
|
|
13883
|
-
|
|
13884
|
-
|
|
13883
|
+
var MAX_ACTION_SLUG_LENGTH = 80;
|
|
13884
|
+
var MAX_SCENARIO_SLUG_LENGTH = 96;
|
|
13885
|
+
function truncateSlug(slug, maxLength) {
|
|
13886
|
+
if (slug.length <= maxLength)
|
|
13887
|
+
return slug;
|
|
13888
|
+
const truncated = slug.slice(0, maxLength).replace(/-+$/g, "");
|
|
13889
|
+
return truncated || slug.slice(0, maxLength);
|
|
13890
|
+
}
|
|
13891
|
+
function slugify(text, maxLength) {
|
|
13892
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
13893
|
+
return maxLength ? truncateSlug(slug, maxLength) : slug;
|
|
13885
13894
|
}
|
|
13886
13895
|
function generateFilename(stepNumber, action) {
|
|
13887
13896
|
const padded = String(stepNumber).padStart(3, "0");
|
|
13888
|
-
const slug = slugify(action);
|
|
13897
|
+
const slug = slugify(action, MAX_ACTION_SLUG_LENGTH);
|
|
13889
13898
|
return `${padded}_${slug}.png`;
|
|
13890
13899
|
}
|
|
13891
13900
|
function formatDate(date) {
|
|
@@ -13899,7 +13908,8 @@ function getScreenshotDir(baseDir, runId, scenarioSlug, projectName, timestamp)
|
|
|
13899
13908
|
const project = projectName ?? "default";
|
|
13900
13909
|
const dateDir = formatDate(now2);
|
|
13901
13910
|
const timeDir = `${formatTime(now2)}_${runId.slice(0, 8)}`;
|
|
13902
|
-
|
|
13911
|
+
const safeScenarioSlug = slugify(scenarioSlug, MAX_SCENARIO_SLUG_LENGTH) || "scenario";
|
|
13912
|
+
return join10(baseDir, project, dateDir, timeDir, safeScenarioSlug);
|
|
13903
13913
|
}
|
|
13904
13914
|
function ensureDir(dirPath) {
|
|
13905
13915
|
if (!existsSync8(dirPath)) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Page } from "playwright";
|
|
2
|
-
export declare function slugify(text: string): string;
|
|
2
|
+
export declare function slugify(text: string, maxLength?: number): string;
|
|
3
3
|
export declare function generateFilename(stepNumber: number, action: string): string;
|
|
4
4
|
/**
|
|
5
5
|
* Build the screenshot directory for a run:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screenshotter.d.ts","sourceRoot":"","sources":["../../src/lib/screenshotter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"screenshotter.d.ts","sourceRoot":"","sources":["../../src/lib/screenshotter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAgBvC,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAI3E;AAUD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,MAAM,EACpB,SAAS,CAAC,EAAE,IAAI,GACf,MAAM,CAOR;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAID,UAAU,oBAAoB;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,cAAc;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAuBD,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC5G,IAAI,CAON;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACxH,IAAI,CAON;AAkCD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,YAAY,CAAO;gBAEf,OAAO,GAAE,oBAAyB;IASxC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAmDpE,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAiD5E,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CA6CpG"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var package_default;
|
|
|
52
52
|
var init_package = __esm(() => {
|
|
53
53
|
package_default = {
|
|
54
54
|
name: "@hasna/testers",
|
|
55
|
-
version: "0.0.
|
|
55
|
+
version: "0.0.39",
|
|
56
56
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
57
57
|
type: "module",
|
|
58
58
|
main: "dist/index.js",
|
|
@@ -19805,12 +19805,19 @@ var init_personas = __esm(() => {
|
|
|
19805
19805
|
// src/lib/screenshotter.ts
|
|
19806
19806
|
import { mkdirSync as mkdirSync7, existsSync as existsSync8, writeFileSync as writeFileSync2 } from "fs";
|
|
19807
19807
|
import { join as join10 } from "path";
|
|
19808
|
-
function
|
|
19809
|
-
|
|
19808
|
+
function truncateSlug(slug, maxLength) {
|
|
19809
|
+
if (slug.length <= maxLength)
|
|
19810
|
+
return slug;
|
|
19811
|
+
const truncated = slug.slice(0, maxLength).replace(/-+$/g, "");
|
|
19812
|
+
return truncated || slug.slice(0, maxLength);
|
|
19813
|
+
}
|
|
19814
|
+
function slugify(text, maxLength) {
|
|
19815
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
19816
|
+
return maxLength ? truncateSlug(slug, maxLength) : slug;
|
|
19810
19817
|
}
|
|
19811
19818
|
function generateFilename(stepNumber, action) {
|
|
19812
19819
|
const padded = String(stepNumber).padStart(3, "0");
|
|
19813
|
-
const slug = slugify(action);
|
|
19820
|
+
const slug = slugify(action, MAX_ACTION_SLUG_LENGTH);
|
|
19814
19821
|
return `${padded}_${slug}.png`;
|
|
19815
19822
|
}
|
|
19816
19823
|
function formatDate(date) {
|
|
@@ -19824,7 +19831,8 @@ function getScreenshotDir(baseDir, runId, scenarioSlug, projectName, timestamp)
|
|
|
19824
19831
|
const project = projectName ?? "default";
|
|
19825
19832
|
const dateDir = formatDate(now2);
|
|
19826
19833
|
const timeDir = `${formatTime(now2)}_${runId.slice(0, 8)}`;
|
|
19827
|
-
|
|
19834
|
+
const safeScenarioSlug = slugify(scenarioSlug, MAX_SCENARIO_SLUG_LENGTH) || "scenario";
|
|
19835
|
+
return join10(baseDir, project, dateDir, timeDir, safeScenarioSlug);
|
|
19828
19836
|
}
|
|
19829
19837
|
function ensureDir(dirPath) {
|
|
19830
19838
|
if (!existsSync8(dirPath)) {
|
|
@@ -19982,7 +19990,7 @@ class Screenshotter {
|
|
|
19982
19990
|
};
|
|
19983
19991
|
}
|
|
19984
19992
|
}
|
|
19985
|
-
var DEFAULT_BASE_DIR;
|
|
19993
|
+
var MAX_ACTION_SLUG_LENGTH = 80, MAX_SCENARIO_SLUG_LENGTH = 96, DEFAULT_BASE_DIR;
|
|
19986
19994
|
var init_screenshotter = __esm(() => {
|
|
19987
19995
|
init_paths();
|
|
19988
19996
|
DEFAULT_BASE_DIR = join10(getTestersDir(), "screenshots");
|
package/dist/server/index.js
CHANGED
|
@@ -46910,7 +46910,7 @@ import { join as join14 } from "path";
|
|
|
46910
46910
|
// package.json
|
|
46911
46911
|
var package_default = {
|
|
46912
46912
|
name: "@hasna/testers",
|
|
46913
|
-
version: "0.0.
|
|
46913
|
+
version: "0.0.39",
|
|
46914
46914
|
description: "AI-powered QA testing CLI \u2014 spawns cheap AI agents to test web apps with headless browsers",
|
|
46915
46915
|
type: "module",
|
|
46916
46916
|
main: "dist/index.js",
|
|
@@ -48303,12 +48303,21 @@ init_browser();
|
|
|
48303
48303
|
init_paths();
|
|
48304
48304
|
import { mkdirSync as mkdirSync5, existsSync as existsSync7, writeFileSync as writeFileSync2 } from "fs";
|
|
48305
48305
|
import { join as join9 } from "path";
|
|
48306
|
-
|
|
48307
|
-
|
|
48306
|
+
var MAX_ACTION_SLUG_LENGTH = 80;
|
|
48307
|
+
var MAX_SCENARIO_SLUG_LENGTH = 96;
|
|
48308
|
+
function truncateSlug(slug, maxLength) {
|
|
48309
|
+
if (slug.length <= maxLength)
|
|
48310
|
+
return slug;
|
|
48311
|
+
const truncated = slug.slice(0, maxLength).replace(/-+$/g, "");
|
|
48312
|
+
return truncated || slug.slice(0, maxLength);
|
|
48313
|
+
}
|
|
48314
|
+
function slugify(text, maxLength) {
|
|
48315
|
+
const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
48316
|
+
return maxLength ? truncateSlug(slug, maxLength) : slug;
|
|
48308
48317
|
}
|
|
48309
48318
|
function generateFilename(stepNumber, action) {
|
|
48310
48319
|
const padded = String(stepNumber).padStart(3, "0");
|
|
48311
|
-
const slug = slugify(action);
|
|
48320
|
+
const slug = slugify(action, MAX_ACTION_SLUG_LENGTH);
|
|
48312
48321
|
return `${padded}_${slug}.png`;
|
|
48313
48322
|
}
|
|
48314
48323
|
function formatDate(date) {
|
|
@@ -48322,7 +48331,8 @@ function getScreenshotDir(baseDir, runId, scenarioSlug, projectName, timestamp)
|
|
|
48322
48331
|
const project = projectName ?? "default";
|
|
48323
48332
|
const dateDir = formatDate(now2);
|
|
48324
48333
|
const timeDir = `${formatTime(now2)}_${runId.slice(0, 8)}`;
|
|
48325
|
-
|
|
48334
|
+
const safeScenarioSlug = slugify(scenarioSlug, MAX_SCENARIO_SLUG_LENGTH) || "scenario";
|
|
48335
|
+
return join9(baseDir, project, dateDir, timeDir, safeScenarioSlug);
|
|
48326
48336
|
}
|
|
48327
48337
|
function ensureDir(dirPath) {
|
|
48328
48338
|
if (!existsSync7(dirPath)) {
|