Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .cursor/CLAUDE.md
5 changes: 4 additions & 1 deletion .cursor/rules/codestyle.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ Avoid creating extra functions that were not explicitly set
Avoid deep nesting of conditionals, use if () { .. return } inestead of if/else
Prefer to use array map/reduce/etc methods over complex ifs

STOP USING FUCKING EMOJIS EVERYWHERE
STOP USING EMOJIS EVERYWHERE

Use Bun for instlling packages
Bun for running tests
37 changes: 1 addition & 36 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [18, 20]
node-version: [18, 20, 22, 24]

steps:
- name: Checkout code
Expand Down Expand Up @@ -50,38 +50,3 @@ jobs:

- name: Run unit tests
run: bun test tests/unit/

- name: Run CodeceptJS tests
run: bun run test:headless

- name: Build project
run: bun run build

test-headless:
runs-on: ubuntu-latest
needs: test

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Install Playwright browsers
run: bunx playwright install --with-deps

- name: Run CodeceptJS tests in headless mode
run: bun run test:headless
env:
CI: true
1 change: 1 addition & 0 deletions AGENTS.md
51 changes: 51 additions & 0 deletions Bunoshfile.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
// Bunosh CLI required to execute tasks from this file
// Get it here => https://buno.sh
import fs from 'node:fs';
import dotenv from 'dotenv';
dotenv.config();
const highlight = require('cli-highlight').highlight;
import { htmlCombinedSnapshot, htmlTextSnapshot, minifyHtml } from './src/utils/html.js';

const { exec, shell, fetch, writeToFile, task, ai } = global.bunosh;

Expand All @@ -19,3 +24,49 @@ export async function worktreeCreate(name = '') {

say(`Created worktree for feature ${worktreeName} in ${newDir}`);
}

/**
* Print HTML combined file for the given file name
* @param {file} fileName
*/
export async function htmlCombined(fileName) {
const html = fs.readFileSync(fileName, 'utf8');
const combinedHtml = await minifyHtml(htmlCombinedSnapshot(html));
console.log('----------');
console.log(highlight(combinedHtml, { language: 'markdown' }));
}

export async function htmlAiText(fileName) {
const html = fs.readFileSync(fileName, 'utf8');
if (!html) {
throw new Error('HTML file not found');
}
say(`Transforming HTML to markdown... ${html.length} characters`);
const combinedHtml = await minifyHtml(htmlCombinedSnapshot(html));
if (!combinedHtml) {
throw new Error('HTML has no semantic elements');
}
console.log(combinedHtml);
const result = await ai(`Transform into markdown. Identify headers, footers, asides, special application parts and main contant.
Content should be in markdown format. If it is content: tables must be tables, lists must be lists.
Navigation elements should be represented as standalone blocks after the content.
Do not summarize content, just transform it into markdown.
It is important to list all the content text
If it is link it must be linked
You can summarize footers/navigation/aside elements.
But main conteint should be kept as text and formatted as markdown based on its current markup.

Break down into sections:

## Content Area

## Navigation Area

## Footer & External Links Area

Here is HTML:

${combinedHtml}
`);
console.log(highlight(result.output, { language: 'markdown' }));
}
91 changes: 62 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Explorbot autonomously explores web applications by:
- **Learning** from previous interactions through experience tracking
- **Leveraging** domain knowledge from documentation files

## Core Philosophy

This project has a hybrid agent-workflow implementation.
While all core decisions (analyze page, run test, plan tests) are strictly implemented in code (workflow), when comes to tactical decisions (page navigation, test completentess) it is done in agentic mode. That makes Explorbot to be **deterministic in strategic goals**, while being flexible and smart in taking in-place decisions. This also reduces context length (each agent has few operations, so context overhead is not hit) and execution speed.

Wherever possible Explorbot asks for codeblocks instead of executing tools directly. This way LLM provides few alternative suggestions to achieve the desired result in one request. Explorbot iterates over them with no additional AI calls. That saves tokens and speeds up navigation web page.


## Core Capabilities

### Intelligent Web Navigation
Expand All @@ -31,12 +39,6 @@ Based on page research, Explorbot generates relevant test scenarios prioritized
- User experience features (medium priority)
- Edge cases and validations (low priority)

### Self-Healing Test Execution
When tests fail, Explorbot doesn't just report errors - it attempts multiple resolution strategies:
- Alternative element locators
- Different interaction approaches
- Contextual problem-solving based on page state

### Experience-Based Learning
Explorbot maintains experience files that capture:
- Successful interaction patterns
Expand All @@ -46,29 +48,58 @@ Explorbot maintains experience files that capture:

## AI Agent Architecture

### Navigator Agent
The Navigator handles all web interactions and error resolution:
- Executes CodeceptJS commands for browser automation
- Analyzes page state after each action
- Resolves failures using AI-powered problem solving
- Tries multiple locator strategies when elements aren't found
- Learns from successful and failed interaction patterns

### Researcher Agent
The Researcher performs comprehensive page analysis:
- Identifies all interactive elements and their functions
- Maps navigation structures and hidden menus
- Expands collapsible content to discover full functionality
- Documents form fields, buttons, and content areas
- Provides structured analysis for test planning

### Planner Agent
The Planner creates test scenarios based on research:
- Generates business-focused test scenarios
- Assigns priority levels based on risk and importance
- Focuses on UI-testable functionality
- Creates expected outcomes for verification
- Balances positive and negative test cases
Explorbot uses a multi-agent system where each AI agent has a specific role in the exploratory testing process. The agents work together to provide comprehensive, intelligent web application testing.

### 🧭 Navigator Agent
The Navigator is the expert test automation engineer who handles all web interactions and error resolution:

- Executes browser automation commands (clicks, form fills, navigation)
- Analyzes page state after each action to verify success
- Resolves failed interactions using AI-powered problem solving
- Tries multiple element locator strategies when elements aren't found
- Learns from successful and failed interaction patterns through experience tracking
- Provides alternative approaches when primary interactions fail

### 🔍 Researcher Agent
The Researcher is the exploratory testing specialist who performs comprehensive page analysis:

- Identifies all interactive elements and their specific functions
- Maps navigation structures, menus, and hidden content areas
- Expands collapsible content (accordions, tabs, dropdowns) to discover full functionality
- Documents form fields, buttons, links, and content areas with detailed analysis
- Provides structured research summaries for test planning
- Caches research results to avoid redundant analysis
- Tracks page changes through HTML diffing

### 📋 Planner Agent

- Generates business-focused test scenarios based on research findings
- Assigns priority levels (HIGH/MEDIUM/LOW) based on risk and business importance
- Creates specific, verifiable expected outcomes for each scenario
- Balances positive scenarios (happy paths) with negative scenarios (edge cases)
- Ensures tests are atomic, independent, and relevant to the page content
- Focuses on main content areas rather than navigation elements
- Maintains test plan history to avoid duplicating previous scenarios

### 🧪 Tester Agent

- Executes planned test scenarios using CodeceptJS tools
- Interacts with web pages to achieve main scenario goals
- Verifies expected results as secondary objectives
- Handles test execution failures with adaptive problem solving
- Tracks state changes and page transitions during testing
- Documents test outcomes and any deviations from expected behavior
- Uses research data to understand page context during execution

### 🧑‍✈️ Captain Agent
The Captain is the orchestrator who coordinates all other agents and manages the overall testing session:

> WORK IN PROGRESS

- Listens to user input in TUI mode and reacts to user commands
- Can launch other agents
- Can change the current agent conversation
- Can update planning, test steps, etc

## Interactive Terminal Interface

Expand Down Expand Up @@ -128,6 +159,8 @@ Explorbot provides a real-time TUI (Terminal User Interface) with three main are
- `/research [url]` - Analyze current page or navigate to URL first
- `/plan [feature]` - Plan tests for a specific feature or general page testing
- `/navigate <target>` - AI-assisted navigation to pages or states
- `/test` - Test planned scenarios
- `/explore` - Research + plan + test

**CodeceptJS Commands:**
- `I.amOnPage(url)` - Navigate to a specific page
Expand Down
62 changes: 0 additions & 62 deletions TESTING_SUMMARY.md

This file was deleted.

25 changes: 7 additions & 18 deletions bin/maclay.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#!/usr/bin/env bun
import { Command } from 'commander';
import { exploreCommand } from '../src/commands/explore.js';
import { addKnowledgeCommand } from '../src/commands/add-knowledge.js';
import { cleanCommand } from '../src/commands/clean.js';
import { exploreCommand } from '../src/commands/explore.js';
import { initCommand } from '../src/commands/init.js';
import { addKnowledgeCommand } from '../src/commands/add-knowledge.js';

const program = new Command();

Expand All @@ -17,37 +17,26 @@ program
.option('--debug', 'Enable debug logging (same as --verbose)')
.option('-c, --config <path>', 'Path to configuration file')
.option('-p, --path <path>', 'Working directory path')
.option('-s, --show', 'Show browser window')
.option('--headless', 'Run browser in headless mode (opposite of --show)')
.helpOption('-h, --help', 'Show this help message')
.action(exploreCommand);

program
.command('clean')
.description('Clean generated files and folders')
.option(
'-t, --type <type>',
'Type of cleaning: artifacts, experience, or all',
'artifacts'
)
.option('-t, --type <type>', 'Type of cleaning: artifacts, experience, or all', 'artifacts')
.option('-p, --path <path>', 'Custom path to clean')
.action(cleanCommand);

program
.command('init')
.description('Initialize a new project with configuration')
.option(
'-c, --config-path <path>',
'Path for the config file',
'./explorbot.config.js'
)
.option('-c, --config-path <path>', 'Path for the config file', './explorbot.config.js')
.option('-f, --force', 'Overwrite existing config file', false)
.option('-p, --path <path>', 'Working directory for initialization')
.action(initCommand);

program
.command('add-knowledge')
.alias('knows')
.description('Add knowledge for specific URLs')
.option('-p, --path <path>', 'Knowledge directory path')
.action(addKnowledgeCommand);
program.command('add-knowledge').alias('knows').description('Add knowledge for specific URLs').option('-p, --path <path>', 'Knowledge directory path').action(addKnowledgeCommand);

program.parse();
Loading