explorbot 0.1.31 → 0.2.0
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/README.md +14 -14
- package/bin/explorbot-cli.ts +4 -3
- package/boat/doc-collector/src/ai/documentarian.ts +22 -27
- package/boat/doc-collector/src/ai/tools.ts +67 -10
- package/boat/doc-collector/src/docbot.ts +28 -7
- package/boat/doc-collector/src/docs-renderer.ts +19 -24
- package/boat/doc-collector/src/screenshots.ts +33 -1
- package/boat/doc-collector/src/state-diagram.ts +281 -0
- package/dist/bin/explorbot-cli.js +3 -3
- package/dist/boat/doc-collector/src/ai/documentarian.js +16 -6
- package/dist/boat/doc-collector/src/ai/tools.js +47 -10
- package/dist/boat/doc-collector/src/docbot.js +25 -6
- package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
- package/dist/boat/doc-collector/src/screenshots.js +29 -0
- package/dist/boat/doc-collector/src/state-diagram.js +200 -0
- package/dist/package.json +8 -6
- package/dist/src/action-result.d.ts +131 -0
- package/dist/src/action-result.js +82 -159
- package/dist/src/action.d.ts +43 -0
- package/dist/src/action.js +18 -106
- package/dist/src/activity.d.ts +26 -0
- package/dist/src/ai/agent.d.ts +3 -0
- package/dist/src/ai/captain/file-tools.d.ts +28 -0
- package/dist/src/ai/captain/idle-mode.d.ts +11 -0
- package/dist/src/ai/captain/mixin.d.ts +10 -0
- package/dist/src/ai/captain/test-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.js +0 -7
- package/dist/src/ai/captain.d.ts +141 -0
- package/dist/src/ai/captain.js +4 -19
- package/dist/src/ai/conversation.d.ts +28 -0
- package/dist/src/ai/conversation.js +9 -28
- package/dist/src/ai/driller.d.ts +157 -0
- package/dist/src/ai/driller.js +3 -12
- package/dist/src/ai/experience-compactor.d.ts +53 -0
- package/dist/src/ai/experience-compactor.js +16 -33
- package/dist/src/ai/fisherman-tools.d.ts +90 -0
- package/dist/src/ai/fisherman-tools.js +1 -1
- package/dist/src/ai/fisherman.d.ts +29 -0
- package/dist/src/ai/fisherman.js +0 -3
- package/dist/src/ai/historian/codeceptjs.d.ts +17 -0
- package/dist/src/ai/historian/codeceptjs.js +3 -2
- package/dist/src/ai/historian/experience.d.ts +40 -0
- package/dist/src/ai/historian/mixin.d.ts +2 -0
- package/dist/src/ai/historian/playwright.d.ts +22 -0
- package/dist/src/ai/historian/playwright.js +3 -2
- package/dist/src/ai/historian/screencast.d.ts +32 -0
- package/dist/src/ai/historian/utils.d.ts +3 -0
- package/dist/src/ai/historian/utils.js +0 -1
- package/dist/src/ai/historian.d.ts +109 -0
- package/dist/src/ai/historian.js +1 -5
- package/dist/src/ai/navigator.d.ts +54 -0
- package/dist/src/ai/navigator.js +11 -46
- package/dist/src/ai/pilot.d.ts +81 -0
- package/dist/src/ai/pilot.js +6 -17
- package/dist/src/ai/planner/session-dedup.d.ts +12 -0
- package/dist/src/ai/planner/styles.d.ts +6 -0
- package/dist/src/ai/planner/subpages.d.ts +35 -0
- package/dist/src/ai/planner.d.ts +79 -0
- package/dist/src/ai/planner.js +49 -37
- package/dist/src/ai/provider.d.ts +53 -0
- package/dist/src/ai/provider.js +78 -130
- package/dist/src/ai/quartermaster.d.ts +56 -0
- package/dist/src/ai/quartermaster.js +4 -10
- package/dist/src/ai/rerunner.d.ts +48 -0
- package/dist/src/ai/rerunner.js +14 -22
- package/dist/src/ai/researcher/cache.d.ts +6 -0
- package/dist/src/ai/researcher/cache.js +11 -18
- package/dist/src/ai/researcher/coordinates.d.ts +56 -0
- package/dist/src/ai/researcher/deep-analysis.d.ts +74 -0
- package/dist/src/ai/researcher/deep-analysis.js +3 -6
- package/dist/src/ai/researcher/fingerprint-worker.d.ts +1 -0
- package/dist/src/ai/researcher/focus.d.ts +8 -0
- package/dist/src/ai/researcher/locators.d.ts +36 -0
- package/dist/src/ai/researcher/mixin.d.ts +2 -0
- package/dist/src/ai/researcher/parser.d.ts +35 -0
- package/dist/src/ai/researcher/parser.js +1 -1
- package/dist/src/ai/researcher/research-result.d.ts +15 -0
- package/dist/src/ai/researcher/research-result.js +0 -19
- package/dist/src/ai/researcher/sections.d.ts +19 -0
- package/dist/src/ai/researcher/sections.js +5 -1
- package/dist/src/ai/researcher.js +12 -53
- package/dist/src/ai/rules.d.ts +16 -0
- package/dist/src/ai/rules.js +22 -15
- package/dist/src/ai/session-analyst.d.ts +11 -0
- package/dist/src/ai/session-analyst.js +8 -5
- package/dist/src/ai/task-agent.d.ts +28 -0
- package/dist/src/ai/task-agent.js +2 -27
- package/dist/src/ai/tester.d.ts +101 -0
- package/dist/src/ai/tester.js +10 -61
- package/dist/src/ai/tools.d.ts +52 -0
- package/dist/src/ai/tools.js +119 -101
- package/dist/src/api/api-client.d.ts +17 -0
- package/dist/src/api/request-result.d.ts +44 -0
- package/dist/src/api/request-store.d.ts +29 -0
- package/dist/src/api/spec-reader.d.ts +5 -0
- package/dist/src/api/xhr-capture.d.ts +10 -0
- package/dist/src/browser-server.d.ts +10 -0
- package/dist/src/command-handler.d.ts +68 -0
- package/dist/src/commands/add-rule-command.d.ts +11 -0
- package/dist/src/commands/base-command.d.ts +26 -0
- package/dist/src/commands/clean-command.d.ts +12 -0
- package/dist/src/commands/compact-command.d.ts +20 -0
- package/dist/src/commands/compact-command.js +6 -6
- package/dist/src/commands/context-aria-command.d.ts +6 -0
- package/dist/src/commands/context-command.d.ts +11 -0
- package/dist/src/commands/context-command.js +1 -1
- package/dist/src/commands/context-data-command.d.ts +6 -0
- package/dist/src/commands/context-experience-command.d.ts +6 -0
- package/dist/src/commands/context-html-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.js +1 -1
- package/dist/src/commands/debug-command.d.ts +6 -0
- package/dist/src/commands/drill-command.d.ts +10 -0
- package/dist/src/commands/exit-command.d.ts +7 -0
- package/dist/src/commands/experience-command.d.ts +15 -0
- package/dist/src/commands/experience-command.js +1 -1
- package/dist/src/commands/explore-command.d.ts +51 -0
- package/dist/src/commands/freesail-command.d.ts +12 -0
- package/dist/src/commands/help-command.d.ts +6 -0
- package/dist/src/commands/index.d.ts +4 -0
- package/dist/src/commands/init-command.d.ts +7 -0
- package/dist/src/commands/knows-command.d.ts +10 -0
- package/dist/src/commands/knows-command.js +1 -1
- package/dist/src/commands/learn-command.d.ts +7 -0
- package/dist/src/commands/learn-command.js +3 -1
- package/dist/src/commands/navigate-command.d.ts +7 -0
- package/dist/src/commands/path-command.d.ts +10 -0
- package/dist/src/commands/plan-clear-command.d.ts +7 -0
- package/dist/src/commands/plan-command.d.ts +14 -0
- package/dist/src/commands/plan-edit-command.d.ts +7 -0
- package/dist/src/commands/plan-load-command.d.ts +7 -0
- package/dist/src/commands/plan-reload-command.d.ts +7 -0
- package/dist/src/commands/plan-save-command.d.ts +7 -0
- package/dist/src/commands/plans-command.d.ts +21 -0
- package/dist/src/commands/rerun-command.d.ts +7 -0
- package/dist/src/commands/research-command.d.ts +11 -0
- package/dist/src/commands/runs-command.d.ts +7 -0
- package/dist/src/commands/start-command.d.ts +7 -0
- package/dist/src/commands/status-command.d.ts +6 -0
- package/dist/src/commands/test-command.d.ts +11 -0
- package/dist/src/components/ActivityPane.d.ts +6 -0
- package/dist/src/components/AddKnowledge.d.ts +10 -0
- package/dist/src/components/AddKnowledge.js +3 -7
- package/dist/src/components/AddRule.d.ts +9 -0
- package/dist/src/components/App.d.ts +9 -0
- package/dist/src/components/App.js +2 -2
- package/dist/src/components/Autocomplete.d.ts +3 -0
- package/dist/src/components/InputPane.d.ts +13 -0
- package/dist/src/components/InputReadline.d.ts +17 -0
- package/dist/src/components/LogPane.d.ts +6 -0
- package/dist/src/components/PlanEditor.d.ts +9 -0
- package/dist/src/components/PlanPane.d.ts +13 -0
- package/dist/src/components/SessionTimer.d.ts +6 -0
- package/dist/src/components/StateTransitionPane.d.ts +8 -0
- package/dist/src/components/StatusPane.d.ts +4 -0
- package/dist/src/components/TaskPane.d.ts +9 -0
- package/dist/src/components/Welcome.d.ts +3 -0
- package/dist/src/components/WelcomeChecklist.d.ts +9 -0
- package/dist/src/components/WelcomeCommands.d.ts +6 -0
- package/dist/src/components/autocomplete-store.d.ts +10 -0
- package/dist/src/components/parse-keypress.d.ts +12 -0
- package/dist/src/config.d.ts +253 -0
- package/dist/src/config.js +12 -0
- package/dist/src/execution-controller.d.ts +25 -0
- package/dist/src/experience-tracker.d.ts +112 -0
- package/dist/src/experience-tracker.js +83 -155
- package/dist/src/explorbot.d.ts +106 -0
- package/dist/src/explorbot.js +17 -51
- package/dist/src/explorer.d.ts +129 -0
- package/dist/src/explorer.js +31 -77
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +2 -55
- package/dist/src/knowledge-tracker.d.ts +33 -0
- package/dist/src/knowledge-tracker.js +47 -47
- package/dist/src/observability.d.ts +13 -0
- package/dist/src/observability.js +2 -1
- package/dist/src/playwright-recorder.d.ts +31 -0
- package/dist/src/reporter.d.ts +34 -0
- package/dist/src/state-manager.d.ts +160 -0
- package/dist/src/state-manager.js +10 -136
- package/dist/src/stats.d.ts +24 -0
- package/dist/src/suite.d.ts +24 -0
- package/dist/src/test-plan.d.ts +166 -0
- package/dist/src/utils/aria.d.ts +25 -0
- package/dist/src/utils/aria.js +4 -1
- package/dist/src/utils/browser-errors.d.ts +8 -0
- package/dist/src/utils/cache.d.ts +15 -0
- package/dist/src/utils/cache.js +34 -0
- package/dist/src/utils/cli-name.d.ts +1 -0
- package/dist/src/utils/code-extractor.d.ts +1 -0
- package/dist/src/utils/context-formatter.d.ts +31 -0
- package/dist/src/utils/context-formatter.js +15 -27
- package/dist/src/utils/error-page.d.ts +12 -0
- package/dist/src/utils/expandable.d.ts +4 -0
- package/dist/src/utils/hooks-runner.d.ts +15 -0
- package/dist/src/utils/html-diff.d.ts +19 -0
- package/dist/src/utils/html.d.ts +129 -0
- package/dist/src/utils/html.js +71 -0
- package/dist/src/utils/log-filters.d.ts +6 -0
- package/dist/src/utils/logger.d.ts +35 -0
- package/dist/src/utils/loop.d.ts +35 -0
- package/dist/src/utils/markdown-files.d.ts +10 -0
- package/dist/src/utils/markdown-files.js +21 -0
- package/dist/src/utils/markdown-parser.d.ts +17 -0
- package/dist/src/utils/markdown-query.d.ts +46 -0
- package/dist/src/utils/markdown-query.js +14 -1
- package/dist/src/utils/markdown-terminal.d.ts +1 -0
- package/dist/src/utils/next-steps.d.ts +11 -0
- package/dist/src/utils/page-readiness.d.ts +7 -0
- package/dist/src/utils/page-readiness.js +1 -1
- package/dist/src/utils/research-parser.d.ts +1 -0
- package/dist/src/utils/retry.d.ts +8 -0
- package/dist/src/utils/rules-loader.d.ts +12 -0
- package/dist/src/utils/secrets.d.ts +4 -0
- package/dist/src/utils/secrets.js +28 -0
- package/dist/src/utils/step-analyzer.d.ts +11 -0
- package/dist/src/utils/strings.d.ts +5 -0
- package/dist/src/utils/strings.js +10 -0
- package/dist/src/utils/test-files.d.ts +3 -0
- package/dist/src/utils/test-plan-markdown.d.ts +9 -0
- package/dist/src/utils/throttle.d.ts +2 -0
- package/dist/src/utils/unique-names.d.ts +2 -0
- package/dist/src/utils/url-matcher.d.ts +6 -0
- package/dist/src/utils/web-element.d.ts +45 -0
- package/dist/src/utils/web-element.js +3 -0
- package/dist/src/utils/web-sandbox.d.ts +4 -0
- package/dist/src/utils/web-sandbox.js +37 -0
- package/dist/src/utils/xpath.d.ts +17 -0
- package/package.json +8 -6
- package/src/action-result.ts +80 -168
- package/src/action.ts +16 -123
- package/src/ai/captain/web-mode.ts +0 -7
- package/src/ai/captain.ts +5 -17
- package/src/ai/conversation.ts +9 -32
- package/src/ai/driller.ts +3 -16
- package/src/ai/experience-compactor.ts +16 -35
- package/src/ai/fisherman-tools.ts +1 -1
- package/src/ai/fisherman.ts +0 -4
- package/src/ai/historian/codeceptjs.ts +4 -2
- package/src/ai/historian/playwright.ts +4 -2
- package/src/ai/historian/utils.ts +0 -1
- package/src/ai/historian.ts +4 -7
- package/src/ai/navigator.ts +13 -49
- package/src/ai/pilot.ts +6 -16
- package/src/ai/planner.ts +56 -44
- package/src/ai/provider.ts +86 -139
- package/src/ai/quartermaster.ts +34 -41
- package/src/ai/rerunner.ts +17 -21
- package/src/ai/researcher/cache.ts +10 -16
- package/src/ai/researcher/deep-analysis.ts +3 -6
- package/src/ai/researcher/parser.ts +1 -1
- package/src/ai/researcher/research-result.ts +0 -18
- package/src/ai/researcher/sections.ts +5 -1
- package/src/ai/researcher.ts +11 -59
- package/src/ai/rules.ts +24 -13
- package/src/ai/session-analyst.ts +8 -5
- package/src/ai/task-agent.ts +3 -30
- package/src/ai/tester.ts +12 -73
- package/src/ai/tools.ts +119 -106
- package/src/commands/compact-command.ts +7 -8
- package/src/commands/context-command.ts +1 -1
- package/src/commands/context-knowledge-command.ts +1 -1
- package/src/commands/experience-command.ts +1 -1
- package/src/commands/knows-command.ts +1 -1
- package/src/commands/learn-command.ts +3 -1
- package/src/components/AddKnowledge.tsx +5 -7
- package/src/components/App.tsx +2 -2
- package/src/config.ts +12 -0
- package/src/experience-tracker.ts +90 -152
- package/src/explorbot.ts +17 -51
- package/src/explorer.ts +34 -81
- package/src/index.ts +9 -0
- package/src/knowledge-tracker.ts +49 -50
- package/src/observability.ts +2 -1
- package/src/state-manager.ts +15 -164
- package/src/utils/aria.ts +11 -2
- package/src/utils/cache.ts +40 -0
- package/src/utils/context-formatter.ts +12 -15
- package/src/utils/html.ts +79 -0
- package/src/utils/markdown-files.ts +30 -0
- package/src/utils/markdown-query.ts +15 -1
- package/src/utils/page-readiness.ts +1 -1
- package/src/utils/secrets.ts +28 -0
- package/src/utils/strings.ts +12 -0
- package/src/utils/web-element.ts +4 -0
- package/src/utils/web-sandbox.ts +43 -0
- package/src/index.tsx +0 -62
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { trace } from '@opentelemetry/api';
|
|
2
|
+
import { redactSecrets } from './utils/secrets.js';
|
|
2
3
|
let current = null;
|
|
3
4
|
export const Observability = {
|
|
4
5
|
async run(name, metadata, fn) {
|
|
@@ -70,7 +71,7 @@ function buildRootSpanAttributes(name, metadata) {
|
|
|
70
71
|
attributes['langfuse.trace.tags'] = metadata.tags;
|
|
71
72
|
}
|
|
72
73
|
if (metadata.input !== undefined) {
|
|
73
|
-
attributes['langfuse.trace.input'] = JSON.stringify(metadata.input);
|
|
74
|
+
attributes['langfuse.trace.input'] = redactSecrets(JSON.stringify(metadata.input));
|
|
74
75
|
}
|
|
75
76
|
return attributes;
|
|
76
77
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface TraceCall {
|
|
2
|
+
class: string;
|
|
3
|
+
method: string;
|
|
4
|
+
params: Record<string, any>;
|
|
5
|
+
}
|
|
6
|
+
export interface VerificationStep {
|
|
7
|
+
name: string;
|
|
8
|
+
args: any[];
|
|
9
|
+
}
|
|
10
|
+
export declare class PlaywrightRecorder {
|
|
11
|
+
context: any;
|
|
12
|
+
tracing: any;
|
|
13
|
+
active: boolean;
|
|
14
|
+
nextGroupId: number;
|
|
15
|
+
verifications: VerificationStep[];
|
|
16
|
+
recordVerification(steps: VerificationStep[]): void;
|
|
17
|
+
drainVerifications(): VerificationStep[];
|
|
18
|
+
start(browserContext: any): Promise<void>;
|
|
19
|
+
beginAction(title: string): Promise<string | null>;
|
|
20
|
+
endAction(): Promise<void>;
|
|
21
|
+
exportChunk(): Promise<Map<string, TraceCall[]>>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
isActive(): boolean;
|
|
24
|
+
}
|
|
25
|
+
declare function parseTrace(ndjson: string): Map<string, TraceCall[]>;
|
|
26
|
+
export declare function renderCall(call: TraceCall): string;
|
|
27
|
+
export declare function renderAssertion(assertion: {
|
|
28
|
+
name: string;
|
|
29
|
+
args: any[];
|
|
30
|
+
}): string;
|
|
31
|
+
export { parseTrace };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Client } from '@testomatio/reporter';
|
|
2
|
+
import type { Step } from '@testomatio/reporter/types/types.js';
|
|
3
|
+
import type { ReporterConfig } from './config.js';
|
|
4
|
+
import type { StateManager } from './state-manager.js';
|
|
5
|
+
import { Test } from './test-plan.js';
|
|
6
|
+
export type ReporterMeta = Record<string, string | undefined>;
|
|
7
|
+
export interface ReporterStep {
|
|
8
|
+
title: string;
|
|
9
|
+
status: 'passed' | 'failed';
|
|
10
|
+
code: string[];
|
|
11
|
+
discovery?: string;
|
|
12
|
+
}
|
|
13
|
+
export declare class Reporter {
|
|
14
|
+
client: Client;
|
|
15
|
+
isRunStarted: boolean;
|
|
16
|
+
reporterEnabled: boolean;
|
|
17
|
+
stateManager?: StateManager;
|
|
18
|
+
constructor(config?: ReporterConfig, stateManager?: StateManager);
|
|
19
|
+
buildTitle(): string;
|
|
20
|
+
static resolveEnabled(config?: ReporterConfig): boolean;
|
|
21
|
+
configureHtmlPipe(): void;
|
|
22
|
+
configureMarkdownPipe(): void;
|
|
23
|
+
configureRunGroup(runGroup: string | null | undefined): void;
|
|
24
|
+
startRun(): Promise<void>;
|
|
25
|
+
reportTestStart(test: Test): Promise<void>;
|
|
26
|
+
combineStepsAndNotes(test: Test, lastScreenshotFile?: string): Step[];
|
|
27
|
+
buildVerificationStep(test: Test, lastScreenshotFile?: string): Step | undefined;
|
|
28
|
+
reportTest(test: Test, meta?: ReporterMeta): Promise<void>;
|
|
29
|
+
finishRun(): Promise<void>;
|
|
30
|
+
isEnabled(): boolean;
|
|
31
|
+
setRunDescription(text: string): Promise<void>;
|
|
32
|
+
extractLastNoteMessage(test: Test): string;
|
|
33
|
+
reportSteps(test: Test, steps: ReporterStep[]): Promise<void>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { ActionResult } from './action-result.js';
|
|
2
|
+
import type { ExperienceTracker } from './experience-tracker.js';
|
|
3
|
+
import type { KnowledgeTracker, Knowledge } from './knowledge-tracker.js';
|
|
4
|
+
export interface Link {
|
|
5
|
+
title: string;
|
|
6
|
+
url: string;
|
|
7
|
+
visible?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface WebPageState {
|
|
10
|
+
/** Unique incremental state identifier */
|
|
11
|
+
id?: number;
|
|
12
|
+
/** URL path without domain, including hash: /path/to/page#section */
|
|
13
|
+
url: string;
|
|
14
|
+
/** Page title */
|
|
15
|
+
title?: string;
|
|
16
|
+
/** HTTP status of the main document navigation */
|
|
17
|
+
httpStatus?: number;
|
|
18
|
+
/** Full URL for reference */
|
|
19
|
+
fullUrl?: string;
|
|
20
|
+
/** Timestamp when state was captured */
|
|
21
|
+
timestamp?: Date;
|
|
22
|
+
/** Hash of the state for unique identification */
|
|
23
|
+
hash?: string;
|
|
24
|
+
/** HTML file path */
|
|
25
|
+
htmlFile?: string;
|
|
26
|
+
/** Screenshot file path */
|
|
27
|
+
screenshotFile?: string;
|
|
28
|
+
/** Log file path */
|
|
29
|
+
logFile?: string;
|
|
30
|
+
/** HTML content */
|
|
31
|
+
html?: string;
|
|
32
|
+
notes?: string[];
|
|
33
|
+
/** Page headings */
|
|
34
|
+
h1?: string;
|
|
35
|
+
h2?: string;
|
|
36
|
+
h3?: string;
|
|
37
|
+
h4?: string;
|
|
38
|
+
ariaSnapshot?: string | null;
|
|
39
|
+
ariaSnapshotFile?: string;
|
|
40
|
+
links?: Link[];
|
|
41
|
+
verifications?: Record<string, boolean>;
|
|
42
|
+
}
|
|
43
|
+
export interface StateTransition {
|
|
44
|
+
/** Previous state (null if this is the first state) */
|
|
45
|
+
fromState: WebPageState | null;
|
|
46
|
+
/** Current state */
|
|
47
|
+
toState: WebPageState;
|
|
48
|
+
/** Code block that caused the transition */
|
|
49
|
+
codeBlock: string;
|
|
50
|
+
/** Timestamp of the transition */
|
|
51
|
+
timestamp: Date;
|
|
52
|
+
/** Any error that occurred during transition */
|
|
53
|
+
error?: string;
|
|
54
|
+
/** What triggered the state change */
|
|
55
|
+
trigger: 'manual' | 'navigation' | 'automatic';
|
|
56
|
+
}
|
|
57
|
+
export type StateChangeListener = (event: StateTransition) => void;
|
|
58
|
+
export type { Knowledge };
|
|
59
|
+
export declare class StateManager {
|
|
60
|
+
currentState: WebPageState | null;
|
|
61
|
+
stateHistory: StateTransition[];
|
|
62
|
+
allVisitedUrls: Set<string>;
|
|
63
|
+
stateChangeListeners: StateChangeListener[];
|
|
64
|
+
experienceTracker: ExperienceTracker;
|
|
65
|
+
knowledgeTracker: KnowledgeTracker;
|
|
66
|
+
nextStateId: number;
|
|
67
|
+
constructor(experienceTracker: ExperienceTracker, knowledgeTracker: KnowledgeTracker);
|
|
68
|
+
getExperienceTracker(): ExperienceTracker;
|
|
69
|
+
getKnowledgeTracker(): KnowledgeTracker;
|
|
70
|
+
/**
|
|
71
|
+
* Subscribe to state change events
|
|
72
|
+
*/
|
|
73
|
+
onStateChange(listener: StateChangeListener): () => void;
|
|
74
|
+
/**
|
|
75
|
+
* Emit state change event to all listeners
|
|
76
|
+
*/
|
|
77
|
+
emitStateChange(event: StateTransition): void;
|
|
78
|
+
/**
|
|
79
|
+
* Update current state from ActionResult and record transition if state changed
|
|
80
|
+
*/
|
|
81
|
+
updateState(actionResult: ActionResult, codeBlock?: string, trigger?: 'manual' | 'navigation' | 'automatic'): WebPageState;
|
|
82
|
+
/**
|
|
83
|
+
* Update state from basic data (for navigation events)
|
|
84
|
+
*/
|
|
85
|
+
updateStateFromBasic(url: string, title?: string, trigger?: 'manual' | 'navigation' | 'automatic'): WebPageState;
|
|
86
|
+
hasDialogAppeared(previousState: WebPageState | null, newState: WebPageState): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Generate a basic hash for state comparison
|
|
89
|
+
*/
|
|
90
|
+
generateBasicHash(url: string, title?: string): string;
|
|
91
|
+
/**
|
|
92
|
+
* Get current state
|
|
93
|
+
*/
|
|
94
|
+
getCurrentState(): WebPageState | null;
|
|
95
|
+
/**
|
|
96
|
+
* Check if state has changed since a given state
|
|
97
|
+
*/
|
|
98
|
+
hasStateChanged(previousState: WebPageState | null): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Compare two states by their hash
|
|
101
|
+
*/
|
|
102
|
+
statesEqual(state1: WebPageState | null, state2: WebPageState | null): boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Get state history
|
|
105
|
+
*/
|
|
106
|
+
getStateHistory(): StateTransition[];
|
|
107
|
+
isInDeadLoop(): boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Get the last N transitions
|
|
110
|
+
*/
|
|
111
|
+
getRecentTransitions(count?: number): StateTransition[];
|
|
112
|
+
/**
|
|
113
|
+
* Get relevant knowledge files for current state
|
|
114
|
+
*/
|
|
115
|
+
getRelevantKnowledge(): Knowledge[];
|
|
116
|
+
/**
|
|
117
|
+
* Get relevant experience files for current state
|
|
118
|
+
*/
|
|
119
|
+
getRelevantExperience(): string[];
|
|
120
|
+
/**
|
|
121
|
+
* Get all context for current state (knowledge + experience)
|
|
122
|
+
*/
|
|
123
|
+
/**
|
|
124
|
+
* Check if we've been in this state before
|
|
125
|
+
*/
|
|
126
|
+
hasVisitedState(path: string): boolean;
|
|
127
|
+
getAllVisitedUrls(): Set<string>;
|
|
128
|
+
/**
|
|
129
|
+
* Get how many times we've visited a specific path
|
|
130
|
+
*/
|
|
131
|
+
getVisitCount(path: string): number;
|
|
132
|
+
/**
|
|
133
|
+
* Find the most recent transition to a specific path
|
|
134
|
+
*/
|
|
135
|
+
getLastVisitToPath(path: string): StateTransition | null;
|
|
136
|
+
/**
|
|
137
|
+
* Get previous state from history for comparison.
|
|
138
|
+
* If the last transition changed URL, returns the fromState (for URL change detection).
|
|
139
|
+
* Otherwise returns the most recent toState with content (for diffing).
|
|
140
|
+
*/
|
|
141
|
+
/**
|
|
142
|
+
* Clear state history (useful for testing or reset)
|
|
143
|
+
* Note: This preserves the current state, only clears navigation history
|
|
144
|
+
*/
|
|
145
|
+
clearHistory(): void;
|
|
146
|
+
/**
|
|
147
|
+
* Get the number of active state change listeners
|
|
148
|
+
*/
|
|
149
|
+
getListenerCount(): number;
|
|
150
|
+
/**
|
|
151
|
+
* Clear all state change listeners
|
|
152
|
+
*/
|
|
153
|
+
clearListeners(): void;
|
|
154
|
+
/**
|
|
155
|
+
* Complete cleanup of the StateManager instance
|
|
156
|
+
* Clears all state, history, listeners, and caches
|
|
157
|
+
*/
|
|
158
|
+
cleanup(): void;
|
|
159
|
+
}
|
|
160
|
+
export declare function normalizeUrl(url: string): string;
|
|
@@ -1,41 +1,27 @@
|
|
|
1
|
-
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
|
-
import { dirname, join } from 'node:path';
|
|
3
|
-
import matter from 'gray-matter';
|
|
4
1
|
import { ActionResult } from './action-result.js';
|
|
5
|
-
import { ConfigParser, outputPath } from './config.js';
|
|
6
|
-
import { ExperienceTracker } from './experience-tracker.js';
|
|
7
2
|
import { detectFocusArea } from './utils/aria.js';
|
|
8
|
-
import { htmlTextSnapshot } from './utils/html.js';
|
|
9
3
|
import { createDebug } from './utils/logger.js';
|
|
4
|
+
import { slugify } from './utils/strings.js';
|
|
10
5
|
import { extractStatePath } from './utils/url-matcher.js';
|
|
11
6
|
const debugLog = createDebug('explorbot:state');
|
|
12
7
|
export class StateManager {
|
|
13
8
|
currentState = null;
|
|
14
9
|
stateHistory = [];
|
|
15
10
|
allVisitedUrls = new Set();
|
|
16
|
-
knowledgeCache = [];
|
|
17
|
-
lastKnowledgeScan = null;
|
|
18
11
|
stateChangeListeners = [];
|
|
19
12
|
experienceTracker;
|
|
20
|
-
|
|
13
|
+
knowledgeTracker;
|
|
21
14
|
nextStateId = 1;
|
|
22
|
-
constructor() {
|
|
23
|
-
this.experienceTracker =
|
|
24
|
-
|
|
25
|
-
const config = configParser.getConfig();
|
|
26
|
-
const configPath = configParser.getConfigPath();
|
|
27
|
-
// Resolve knowledge directory relative to the config file location (project root)
|
|
28
|
-
if (configPath) {
|
|
29
|
-
const projectRoot = dirname(configPath);
|
|
30
|
-
this.knowledgeDir = join(projectRoot, config.dirs?.knowledge || 'knowledge');
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
this.knowledgeDir = config.dirs?.knowledge || 'knowledge';
|
|
34
|
-
}
|
|
15
|
+
constructor(experienceTracker, knowledgeTracker) {
|
|
16
|
+
this.experienceTracker = experienceTracker;
|
|
17
|
+
this.knowledgeTracker = knowledgeTracker;
|
|
35
18
|
}
|
|
36
19
|
getExperienceTracker() {
|
|
37
20
|
return this.experienceTracker;
|
|
38
21
|
}
|
|
22
|
+
getKnowledgeTracker() {
|
|
23
|
+
return this.knowledgeTracker;
|
|
24
|
+
}
|
|
39
25
|
/**
|
|
40
26
|
* Subscribe to state change events
|
|
41
27
|
*/
|
|
@@ -53,12 +39,6 @@ export class StateManager {
|
|
|
53
39
|
* Emit state change event to all listeners
|
|
54
40
|
*/
|
|
55
41
|
emitStateChange(event) {
|
|
56
|
-
// Log HTML content when state changes
|
|
57
|
-
if (event.toState.html && event.toState.html !== event.fromState?.html) {
|
|
58
|
-
let htmlContent = event?.toState?.html ?? '';
|
|
59
|
-
htmlContent = htmlTextSnapshot(htmlContent);
|
|
60
|
-
// tag('html').log(`Page HTML for ${event.toState.url}:\n${htmlContent}`);
|
|
61
|
-
}
|
|
62
42
|
this.stateChangeListeners.forEach((listener) => {
|
|
63
43
|
try {
|
|
64
44
|
listener(event);
|
|
@@ -68,11 +48,6 @@ export class StateManager {
|
|
|
68
48
|
}
|
|
69
49
|
});
|
|
70
50
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Extract state path from full URL
|
|
73
|
-
* Removes domain, port, protocol
|
|
74
|
-
* Keeps path, query, and hash: /path/to/page?tab=users#section
|
|
75
|
-
*/
|
|
76
51
|
/**
|
|
77
52
|
* Update current state from ActionResult and record transition if state changed
|
|
78
53
|
*/
|
|
@@ -148,13 +123,7 @@ export class StateManager {
|
|
|
148
123
|
if (title) {
|
|
149
124
|
parts.push(`title_${title}`);
|
|
150
125
|
}
|
|
151
|
-
return parts
|
|
152
|
-
.join('_')
|
|
153
|
-
.replace(/[^a-zA-Z0-9_]/g, '_')
|
|
154
|
-
.replace(/_+/g, '_')
|
|
155
|
-
.replace(/^_|_$/g, '')
|
|
156
|
-
.toLowerCase()
|
|
157
|
-
.substring(0, 200);
|
|
126
|
+
return slugify(parts.join('_')).substring(0, 200);
|
|
158
127
|
}
|
|
159
128
|
/**
|
|
160
129
|
* Get current state
|
|
@@ -233,57 +202,14 @@ export class StateManager {
|
|
|
233
202
|
getRecentTransitions(count = 5) {
|
|
234
203
|
return this.stateHistory.slice(-count);
|
|
235
204
|
}
|
|
236
|
-
/**
|
|
237
|
-
* Scan knowledge directory for .md files and cache them
|
|
238
|
-
*/
|
|
239
|
-
scanKnowledgeFiles() {
|
|
240
|
-
const now = new Date();
|
|
241
|
-
// Only rescan every 30 seconds to avoid excessive file I/O
|
|
242
|
-
if (this.lastKnowledgeScan && now.getTime() - this.lastKnowledgeScan.getTime() < 30000) {
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
this.knowledgeCache = [];
|
|
246
|
-
if (!existsSync(this.knowledgeDir)) {
|
|
247
|
-
debugLog(`Knowledge directory not found: ${this.knowledgeDir}`);
|
|
248
|
-
return;
|
|
249
|
-
}
|
|
250
|
-
try {
|
|
251
|
-
const files = readdirSync(this.knowledgeDir, { recursive: true })
|
|
252
|
-
.filter((file) => typeof file === 'string' && file.endsWith('.md'))
|
|
253
|
-
.map((file) => join(this.knowledgeDir, file));
|
|
254
|
-
for (const filePath of files) {
|
|
255
|
-
try {
|
|
256
|
-
const fileContent = readFileSync(filePath, 'utf8');
|
|
257
|
-
const parsed = matter(fileContent);
|
|
258
|
-
const urlPattern = parsed.data.url || parsed.data.path || '*';
|
|
259
|
-
this.knowledgeCache.push({
|
|
260
|
-
filePath,
|
|
261
|
-
url: urlPattern,
|
|
262
|
-
...parsed.data,
|
|
263
|
-
content: parsed.content,
|
|
264
|
-
});
|
|
265
|
-
debugLog(`Loaded knowledge file: ${filePath} (pattern: ${urlPattern})`);
|
|
266
|
-
}
|
|
267
|
-
catch (error) {
|
|
268
|
-
debugLog(`Failed to load knowledge file ${filePath}:`, error);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
this.lastKnowledgeScan = now;
|
|
272
|
-
debugLog(`Scanned ${this.knowledgeCache.length} knowledge files`);
|
|
273
|
-
}
|
|
274
|
-
catch (error) {
|
|
275
|
-
debugLog('Failed to scan knowledge directory:', error);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
205
|
/**
|
|
279
206
|
* Get relevant knowledge files for current state
|
|
280
207
|
*/
|
|
281
208
|
getRelevantKnowledge() {
|
|
282
209
|
if (!this.currentState)
|
|
283
210
|
return [];
|
|
284
|
-
this.scanKnowledgeFiles();
|
|
285
211
|
const actionResult = ActionResult.fromState(this.currentState);
|
|
286
|
-
return this.
|
|
212
|
+
return this.knowledgeTracker.getRelevantKnowledge(actionResult);
|
|
287
213
|
}
|
|
288
214
|
/**
|
|
289
215
|
* Get relevant experience files for current state
|
|
@@ -298,17 +224,6 @@ export class StateManager {
|
|
|
298
224
|
/**
|
|
299
225
|
* Get all context for current state (knowledge + experience)
|
|
300
226
|
*/
|
|
301
|
-
getCurrentContext() {
|
|
302
|
-
if (!this.currentState) {
|
|
303
|
-
throw new Error('No current state available');
|
|
304
|
-
}
|
|
305
|
-
return {
|
|
306
|
-
state: this.currentState,
|
|
307
|
-
knowledge: this.getRelevantKnowledge(),
|
|
308
|
-
experience: this.getRelevantExperience(),
|
|
309
|
-
recentTransitions: this.getRecentTransitions(),
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
227
|
/**
|
|
313
228
|
* Check if we've been in this state before
|
|
314
229
|
*/
|
|
@@ -340,41 +255,6 @@ export class StateManager {
|
|
|
340
255
|
* If the last transition changed URL, returns the fromState (for URL change detection).
|
|
341
256
|
* Otherwise returns the most recent toState with content (for diffing).
|
|
342
257
|
*/
|
|
343
|
-
getPreviousState() {
|
|
344
|
-
if (this.stateHistory.length === 0)
|
|
345
|
-
return null;
|
|
346
|
-
const lastTransition = this.stateHistory[this.stateHistory.length - 1];
|
|
347
|
-
if (lastTransition.fromState?.url !== lastTransition.toState?.url) {
|
|
348
|
-
return lastTransition.fromState;
|
|
349
|
-
}
|
|
350
|
-
for (let i = this.stateHistory.length - 1; i >= 0; i--) {
|
|
351
|
-
const toState = this.stateHistory[i].toState;
|
|
352
|
-
if (!toState)
|
|
353
|
-
continue;
|
|
354
|
-
if (toState.id === this.currentState?.id)
|
|
355
|
-
continue;
|
|
356
|
-
if (toState.html || toState.ariaSnapshot) {
|
|
357
|
-
return toState;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return null;
|
|
361
|
-
}
|
|
362
|
-
/**
|
|
363
|
-
* Load HTML content from file
|
|
364
|
-
*/
|
|
365
|
-
loadHtmlFromFile(htmlFile) {
|
|
366
|
-
try {
|
|
367
|
-
const filePath = outputPath('states', htmlFile);
|
|
368
|
-
if (existsSync(filePath)) {
|
|
369
|
-
return readFileSync(filePath, 'utf8');
|
|
370
|
-
}
|
|
371
|
-
return null;
|
|
372
|
-
}
|
|
373
|
-
catch (error) {
|
|
374
|
-
debugLog('Failed to load HTML from file:', error);
|
|
375
|
-
return null;
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
258
|
/**
|
|
379
259
|
* Clear state history (useful for testing or reset)
|
|
380
260
|
* Note: This preserves the current state, only clears navigation history
|
|
@@ -405,13 +285,7 @@ export class StateManager {
|
|
|
405
285
|
this.stateHistory = [];
|
|
406
286
|
this.allVisitedUrls.clear();
|
|
407
287
|
this.stateChangeListeners = [];
|
|
408
|
-
this.knowledgeCache = [];
|
|
409
|
-
this.lastKnowledgeScan = null;
|
|
410
288
|
this.nextStateId = 1;
|
|
411
|
-
// Clean up experience tracker if it has cleanup method
|
|
412
|
-
if (this.experienceTracker && typeof this.experienceTracker.cleanup === 'function') {
|
|
413
|
-
this.experienceTracker.cleanup();
|
|
414
|
-
}
|
|
415
289
|
debugLog('StateManager cleanup completed');
|
|
416
290
|
}
|
|
417
291
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
interface TokenUsage {
|
|
2
|
+
input: number;
|
|
3
|
+
output: number;
|
|
4
|
+
total: number;
|
|
5
|
+
cached?: number;
|
|
6
|
+
}
|
|
7
|
+
export type ExplorbotMode = 'explore' | 'test' | 'freesail' | 'tui';
|
|
8
|
+
export declare class Stats {
|
|
9
|
+
static startTime: number;
|
|
10
|
+
static sessionName: string;
|
|
11
|
+
static researches: number;
|
|
12
|
+
static tests: number;
|
|
13
|
+
static plans: number;
|
|
14
|
+
static mode?: ExplorbotMode;
|
|
15
|
+
static focus?: string;
|
|
16
|
+
static models: Record<string, TokenUsage>;
|
|
17
|
+
static recordTokens(_agent: string, model: string, usage: TokenUsage): void;
|
|
18
|
+
static getElapsedTime(): string;
|
|
19
|
+
static humanizeTokens(num: number): string;
|
|
20
|
+
static modelsTable(roleModels: Record<string, string>): string;
|
|
21
|
+
static hasActivity(): boolean;
|
|
22
|
+
static sessionLabel(): string;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare class Suite {
|
|
2
|
+
readonly url: string;
|
|
3
|
+
_automatedTests: AutomatedTest[] | null;
|
|
4
|
+
_plannedScenarios: string[] | null;
|
|
5
|
+
constructor(url: string);
|
|
6
|
+
getAutomatedTests(): AutomatedTest[];
|
|
7
|
+
getPlannedScenarios(): string[];
|
|
8
|
+
getActiveScenarioTitles(): Set<string>;
|
|
9
|
+
get automatedTestCount(): number;
|
|
10
|
+
getAutomatedTestNames(): string[];
|
|
11
|
+
getAutomatedTestFiles(): string[];
|
|
12
|
+
loadAutomatedTests(): AutomatedTest[];
|
|
13
|
+
parseTestFile(filePath: string): {
|
|
14
|
+
url: string;
|
|
15
|
+
tests: AutomatedTest[];
|
|
16
|
+
} | null;
|
|
17
|
+
loadPlannedScenarios(): string[];
|
|
18
|
+
}
|
|
19
|
+
interface AutomatedTest {
|
|
20
|
+
title: string;
|
|
21
|
+
pending: boolean;
|
|
22
|
+
file: string;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { WebPageState } from './state-manager.js';
|
|
2
|
+
export declare const TestResult: {
|
|
3
|
+
readonly PASSED: "passed";
|
|
4
|
+
readonly FAILED: "failed";
|
|
5
|
+
readonly SKIPPED: "skipped";
|
|
6
|
+
};
|
|
7
|
+
export type TestResultType = (typeof TestResult)[keyof typeof TestResult] | null;
|
|
8
|
+
export declare const TestStatus: {
|
|
9
|
+
readonly PENDING: "pending";
|
|
10
|
+
readonly IN_PROGRESS: "in_progress";
|
|
11
|
+
readonly DONE: "done";
|
|
12
|
+
};
|
|
13
|
+
export type TestStatusType = (typeof TestStatus)[keyof typeof TestStatus];
|
|
14
|
+
export interface Note {
|
|
15
|
+
message: string;
|
|
16
|
+
status?: TestResultType;
|
|
17
|
+
startTime: number;
|
|
18
|
+
endTime: number;
|
|
19
|
+
screenshot?: string;
|
|
20
|
+
log?: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class ActiveNote {
|
|
23
|
+
task: Task;
|
|
24
|
+
startTime: number;
|
|
25
|
+
message: string;
|
|
26
|
+
status?: TestResultType;
|
|
27
|
+
screenshot?: string;
|
|
28
|
+
log?: string;
|
|
29
|
+
constructor(task: Task, message: string, status?: TestResultType);
|
|
30
|
+
commit(finalStatus?: TestResultType): void;
|
|
31
|
+
getMessage(): string;
|
|
32
|
+
getStartTime(): number;
|
|
33
|
+
}
|
|
34
|
+
export interface StepData {
|
|
35
|
+
text: string;
|
|
36
|
+
duration?: number;
|
|
37
|
+
status?: string;
|
|
38
|
+
error?: string;
|
|
39
|
+
log?: string;
|
|
40
|
+
artifacts?: string[];
|
|
41
|
+
noteStartTime?: number;
|
|
42
|
+
}
|
|
43
|
+
export declare class Task {
|
|
44
|
+
id: string;
|
|
45
|
+
description: string;
|
|
46
|
+
notes: Record<string, Note>;
|
|
47
|
+
steps: Record<string, StepData>;
|
|
48
|
+
states: WebPageState[];
|
|
49
|
+
startUrl: string;
|
|
50
|
+
verification?: Verification;
|
|
51
|
+
timestampCounter: number;
|
|
52
|
+
activeNote?: ActiveNote;
|
|
53
|
+
constructor(description: string, startUrl?: string);
|
|
54
|
+
startNote(message: string, status?: TestResultType): ActiveNote;
|
|
55
|
+
finishNote(activeNote: ActiveNote, endTime: number, finalStatus?: TestResultType): void;
|
|
56
|
+
getPrintableNotes(): string[];
|
|
57
|
+
notesToString(): string;
|
|
58
|
+
addNote(message: string, status?: TestResultType, screenshot?: string, log?: string): void;
|
|
59
|
+
addUrlNote(state: UrlNoteState, prevState?: {
|
|
60
|
+
title?: string;
|
|
61
|
+
h1?: string;
|
|
62
|
+
h2?: string;
|
|
63
|
+
}): void;
|
|
64
|
+
addState(state: WebPageState): void;
|
|
65
|
+
addStep(text: string, duration?: number, status?: string, error?: string, log?: string, artifacts?: string[]): void;
|
|
66
|
+
setActiveNoteScreenshot(screenshotFile?: string): void;
|
|
67
|
+
setVerification(message: string, status: TestResultType, state?: UrlNoteState): void;
|
|
68
|
+
addVerificationDetail(detail: string): void;
|
|
69
|
+
getLog(): Array<{
|
|
70
|
+
type: 'step' | 'note' | 'artifact';
|
|
71
|
+
content: string;
|
|
72
|
+
timestamp: number;
|
|
73
|
+
}>;
|
|
74
|
+
getLogString(): string;
|
|
75
|
+
getRunResult(): 'success' | 'partial' | 'failed';
|
|
76
|
+
}
|
|
77
|
+
export declare class Test extends Task {
|
|
78
|
+
scenario: string;
|
|
79
|
+
sessionName?: string;
|
|
80
|
+
status: TestStatusType;
|
|
81
|
+
result: TestResultType;
|
|
82
|
+
priority: 'critical' | 'important' | 'high' | 'normal' | 'low';
|
|
83
|
+
expected: string[];
|
|
84
|
+
plannedSteps: string[];
|
|
85
|
+
plan?: Plan;
|
|
86
|
+
summary: string;
|
|
87
|
+
artifacts: Record<string, string>;
|
|
88
|
+
generatedCode?: string;
|
|
89
|
+
style?: string;
|
|
90
|
+
planIteration: number;
|
|
91
|
+
enabled: boolean;
|
|
92
|
+
startTime?: number;
|
|
93
|
+
endTime?: number;
|
|
94
|
+
resetCount: number;
|
|
95
|
+
constructor(scenario: string, priority: 'critical' | 'important' | 'high' | 'normal' | 'low', expectedOutcome: string | string[], startUrl: string, plannedSteps?: string[]);
|
|
96
|
+
getVisitedUrls({ localOnly }?: {
|
|
97
|
+
localOnly?: boolean;
|
|
98
|
+
}): string[];
|
|
99
|
+
addArtifact(artifact?: string): void;
|
|
100
|
+
get hasFinished(): boolean;
|
|
101
|
+
get isSuccessful(): boolean;
|
|
102
|
+
get hasFailed(): boolean;
|
|
103
|
+
get isSkipped(): boolean;
|
|
104
|
+
getCheckedNotes(): Note[];
|
|
105
|
+
getCheckedExpectations(): string[];
|
|
106
|
+
hasAchievedAny(): boolean;
|
|
107
|
+
getRunResult(): 'success' | 'partial' | 'failed';
|
|
108
|
+
hasAchievedAll(): boolean;
|
|
109
|
+
isComplete(): boolean;
|
|
110
|
+
start(): void;
|
|
111
|
+
finish(result?: TestResultType): void;
|
|
112
|
+
getDurationMs(): number | null;
|
|
113
|
+
getRemainingExpectations(): string[];
|
|
114
|
+
getLog(): Array<{
|
|
115
|
+
type: 'step' | 'note' | 'artifact';
|
|
116
|
+
content: string;
|
|
117
|
+
timestamp: number;
|
|
118
|
+
}>;
|
|
119
|
+
}
|
|
120
|
+
type PlanChangeListener = (tests: Test[]) => void;
|
|
121
|
+
export declare class Plan {
|
|
122
|
+
title: string;
|
|
123
|
+
tests: Test[];
|
|
124
|
+
url?: string;
|
|
125
|
+
iteration: number;
|
|
126
|
+
parentPlan?: Plan;
|
|
127
|
+
changeListeners: PlanChangeListener[];
|
|
128
|
+
constructor(title: string);
|
|
129
|
+
nextIteration(): void;
|
|
130
|
+
addTest(test: Test): void;
|
|
131
|
+
removeTest(test: Test): void;
|
|
132
|
+
onTestsChange(listener: PlanChangeListener): () => void;
|
|
133
|
+
notifyChange(): void;
|
|
134
|
+
getAllTests(): Test[];
|
|
135
|
+
listTests(): Test[];
|
|
136
|
+
getPendingTests(): Test[];
|
|
137
|
+
get isComplete(): boolean;
|
|
138
|
+
get allSuccessful(): boolean;
|
|
139
|
+
get allFailed(): boolean;
|
|
140
|
+
updateStatus(): void;
|
|
141
|
+
static fromMarkdown(filePath: string): Plan;
|
|
142
|
+
saveToMarkdown(filePath: string): void;
|
|
143
|
+
static saveMultipleToMarkdown(plans: Plan[], filePath: string): void;
|
|
144
|
+
getVisitedPages(): WebPageState[];
|
|
145
|
+
merge(otherPlan: Plan): Plan;
|
|
146
|
+
toAiContext(options?: {
|
|
147
|
+
skipSteps?: boolean;
|
|
148
|
+
}): string;
|
|
149
|
+
}
|
|
150
|
+
interface Verification {
|
|
151
|
+
message: string;
|
|
152
|
+
status: TestResultType;
|
|
153
|
+
screenshot?: string;
|
|
154
|
+
url?: string;
|
|
155
|
+
pageLabel?: string;
|
|
156
|
+
details: string[];
|
|
157
|
+
}
|
|
158
|
+
interface UrlNoteState {
|
|
159
|
+
url?: string;
|
|
160
|
+
fullUrl?: string;
|
|
161
|
+
title?: string;
|
|
162
|
+
h1?: string;
|
|
163
|
+
h2?: string;
|
|
164
|
+
screenshotFile?: string;
|
|
165
|
+
}
|
|
166
|
+
export {};
|