explorbot 0.1.20 → 0.1.21
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/explorbot-cli.ts +54 -25
- package/boat/doc-collector/src/ai/documentarian.ts +259 -84
- package/boat/doc-collector/src/ai/tools.ts +544 -0
- package/boat/doc-collector/src/cli.ts +1 -0
- package/boat/doc-collector/src/config.ts +2 -0
- package/boat/doc-collector/src/docbot.ts +64 -5
- package/boat/doc-collector/src/docs-renderer.ts +56 -2
- package/dist/bin/explorbot-cli.js +30 -4
- package/dist/boat/doc-collector/src/ai/documentarian.js +220 -71
- package/dist/boat/doc-collector/src/ai/tools.js +415 -0
- package/dist/boat/doc-collector/src/cli.js +1 -0
- package/dist/boat/doc-collector/src/config.js +1 -0
- package/dist/boat/doc-collector/src/docbot.js +57 -5
- package/dist/boat/doc-collector/src/docs-renderer.js +46 -0
- package/dist/package.json +1 -1
- package/dist/src/ai/navigator.js +82 -6
- package/dist/src/commands/index.js +2 -0
- package/dist/src/commands/plans-command.js +83 -0
- package/dist/src/commands/test-command.js +14 -8
- package/dist/src/playwright-recorder.js +19 -5
- package/package.json +1 -1
- package/src/ai/navigator.ts +79 -7
- package/src/commands/index.ts +2 -0
- package/src/commands/plans-command.ts +99 -0
- package/src/commands/test-command.ts +15 -8
- package/src/playwright-recorder.ts +19 -5
|
@@ -6,13 +6,20 @@ import { BaseCommand, type Suggestion } from './base-command.js';
|
|
|
6
6
|
export class TestCommand extends BaseCommand {
|
|
7
7
|
name = 'test';
|
|
8
8
|
description = 'Launch tester agent to execute test scenarios';
|
|
9
|
+
options = [{ flags: '--from-plan <file>', description: 'Load plan file before selecting tests' }];
|
|
9
10
|
suggestions: Suggestion[] = [
|
|
10
11
|
{ command: 'test', hint: 'run next test' },
|
|
11
12
|
{ command: 'plan', hint: 'create new plan' },
|
|
12
13
|
];
|
|
13
14
|
|
|
14
15
|
async execute(args: string): Promise<void> {
|
|
16
|
+
const { opts, args: remaining } = this.parseArgs(args);
|
|
17
|
+
if (opts.fromPlan) {
|
|
18
|
+
this.explorBot.loadPlan(String(opts.fromPlan));
|
|
19
|
+
}
|
|
20
|
+
|
|
15
21
|
const plan = this.explorBot.getCurrentPlan();
|
|
22
|
+
const selector = remaining.join(' ');
|
|
16
23
|
Stats.mode = 'test';
|
|
17
24
|
Stats.focus = plan?.title;
|
|
18
25
|
const toExecute: Test[] = [];
|
|
@@ -22,22 +29,22 @@ export class TestCommand extends BaseCommand {
|
|
|
22
29
|
return plan;
|
|
23
30
|
};
|
|
24
31
|
|
|
25
|
-
if (!
|
|
32
|
+
if (!selector) {
|
|
26
33
|
const pending = requirePlan().getPendingTests();
|
|
27
34
|
if (pending.length === 0) {
|
|
28
35
|
throw new Error('All tests are already complete. Please run /plan to create new test scenarios.');
|
|
29
36
|
}
|
|
30
37
|
toExecute.push(pending[0]);
|
|
31
|
-
} else if (
|
|
38
|
+
} else if (selector === '*' || selector === 'all') {
|
|
32
39
|
toExecute.push(...requirePlan().getPendingTests());
|
|
33
|
-
} else if (
|
|
40
|
+
} else if (selector.match(/^[\d,\-\s]+$/)) {
|
|
34
41
|
const visible = requirePlan().tests.filter((t) => t.enabled);
|
|
35
|
-
const indices = parseTestIndices(
|
|
42
|
+
const indices = parseTestIndices(selector, visible.length);
|
|
36
43
|
for (const idx of indices) {
|
|
37
44
|
toExecute.push(visible[idx]);
|
|
38
45
|
}
|
|
39
46
|
} else {
|
|
40
|
-
const matching = plan?.getPendingTests().filter((test) => test.scenario.toLowerCase().includes(
|
|
47
|
+
const matching = plan?.getPendingTests().filter((test) => test.scenario.toLowerCase().includes(selector.toLowerCase())) || [];
|
|
41
48
|
if (matching.length > 0) {
|
|
42
49
|
toExecute.push(...matching);
|
|
43
50
|
} else {
|
|
@@ -45,12 +52,12 @@ export class TestCommand extends BaseCommand {
|
|
|
45
52
|
if (!state) {
|
|
46
53
|
throw new Error('No page loaded. Please navigate to a page first.');
|
|
47
54
|
}
|
|
48
|
-
const newTest = new Test(
|
|
55
|
+
const newTest = new Test(selector, 'unknown', [], state.url);
|
|
49
56
|
if (plan) {
|
|
50
57
|
plan.addTest(newTest);
|
|
51
|
-
tag('info').log(`Created new test: "${
|
|
58
|
+
tag('info').log(`Created new test: "${selector}" and added to current plan.`);
|
|
52
59
|
} else {
|
|
53
|
-
tag('info').log(`Created ad-hoc test: "${
|
|
60
|
+
tag('info').log(`Created ad-hoc test: "${selector}"`);
|
|
54
61
|
}
|
|
55
62
|
toExecute.push(newTest);
|
|
56
63
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
1
2
|
import { readFile } from 'node:fs/promises';
|
|
2
|
-
// @ts-ignore — package ships a .js re-export without typings for this sub-path
|
|
3
|
-
import * as playwrightUtils from 'playwright-core/lib/utils';
|
|
4
3
|
import { createDebug } from './utils/logger.ts';
|
|
5
4
|
|
|
6
5
|
const debugLog = createDebug('explorbot:playwright-recorder');
|
|
@@ -12,10 +11,25 @@ const RECORDABLE: Record<string, Set<string>> = {
|
|
|
12
11
|
|
|
13
12
|
const PLAYWRIGHT_INCOMPATIBLE = "Playwright output is not compatible with this Playwright version (playwright-core/lib/utils does not expose asLocator). Use output.framework: 'codeceptjs' instead, or pin Playwright to a version shipping lib/utils/isomorphic/locatorGenerators.js.";
|
|
14
13
|
|
|
14
|
+
let cachedAsLocator: ((lang: string, selector: string) => string) | null = null;
|
|
15
|
+
let asLocatorLoadAttempted = false;
|
|
16
|
+
const nodeRequire = typeof require === 'function' ? require : createRequire(import.meta.url);
|
|
17
|
+
|
|
15
18
|
function getAsLocator(): (lang: string, selector: string) => string {
|
|
16
|
-
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
+
if (cachedAsLocator) return cachedAsLocator;
|
|
20
|
+
if (asLocatorLoadAttempted) throw new Error(PLAYWRIGHT_INCOMPATIBLE);
|
|
21
|
+
|
|
22
|
+
asLocatorLoadAttempted = true;
|
|
23
|
+
try {
|
|
24
|
+
const mod = nodeRequire('playwright-core/lib/utils');
|
|
25
|
+
if (typeof (mod as any)?.asLocator === 'function') {
|
|
26
|
+
cachedAsLocator = (mod as any).asLocator;
|
|
27
|
+
return cachedAsLocator!;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
// Module not exported or not found
|
|
31
|
+
}
|
|
32
|
+
throw new Error(PLAYWRIGHT_INCOMPATIBLE);
|
|
19
33
|
}
|
|
20
34
|
|
|
21
35
|
export interface TraceCall {
|