brave-real-browser-mcp-server 2.0.4 → 2.0.6
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.
|
@@ -97,8 +97,19 @@ describe('Browser Handlers', () => {
|
|
|
97
97
|
autoSuggestGetContent: false
|
|
98
98
|
}
|
|
99
99
|
};
|
|
100
|
-
// Mock the complete flow
|
|
100
|
+
// Mock the complete flow - reset all mocks first
|
|
101
|
+
vi.clearAllMocks();
|
|
102
|
+
// Reset workflow validation to allow browser init
|
|
103
|
+
mockWorkflowValidation.validateWorkflow.mockReturnValue({
|
|
104
|
+
isValid: true,
|
|
105
|
+
errorMessage: null,
|
|
106
|
+
suggestedAction: null
|
|
107
|
+
});
|
|
108
|
+
mockWorkflowValidation.recordExecution.mockReturnValue(undefined);
|
|
109
|
+
mockWorkflowValidation.workflowValidator.getValidationSummary.mockReturnValue('Mock summary');
|
|
110
|
+
// Mock browser manager functions
|
|
101
111
|
mockBrowserManager.initializeBrowser.mockResolvedValue(undefined);
|
|
112
|
+
mockBrowserManager.updateContentPriorityConfig.mockReturnValue(undefined);
|
|
102
113
|
mockBrowserManager.getContentPriorityConfig.mockReturnValue({
|
|
103
114
|
prioritizeContent: false,
|
|
104
115
|
autoSuggestGetContent: false
|
|
@@ -132,24 +143,31 @@ describe('Browser Handlers', () => {
|
|
|
132
143
|
expect(mockWorkflowValidation.recordExecution).toHaveBeenCalledWith('browser_init', args, false, 'Failed to initialize browser');
|
|
133
144
|
});
|
|
134
145
|
it('should handle workflow validation failure', async () => {
|
|
135
|
-
// Arrange:
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
146
|
+
// Arrange: Mock validateWorkflow to be imported and used by the handler
|
|
147
|
+
// We need to import and re-mock this to intercept the actual validation call
|
|
148
|
+
const mockValidateWorkflow = vi.fn();
|
|
149
|
+
const mockRecordExecution = vi.fn();
|
|
150
|
+
const mockGetValidationSummary = vi.fn();
|
|
151
|
+
// Set up validation failure
|
|
152
|
+
mockValidateWorkflow.mockReturnValue({
|
|
139
153
|
isValid: false,
|
|
140
154
|
errorMessage: 'Browser already initialized',
|
|
141
155
|
suggestedAction: 'Close browser first'
|
|
142
156
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
//
|
|
146
|
-
|
|
157
|
+
mockGetValidationSummary.mockReturnValue('Current state: BROWSER_ACTIVE | Last action: browser_init');
|
|
158
|
+
mockRecordExecution.mockReturnValue(undefined);
|
|
159
|
+
// Set the mocks on the module
|
|
160
|
+
mockWorkflowValidation.validateWorkflow = mockValidateWorkflow;
|
|
161
|
+
mockWorkflowValidation.recordExecution = mockRecordExecution;
|
|
162
|
+
mockWorkflowValidation.workflowValidator.getValidationSummary = mockGetValidationSummary;
|
|
163
|
+
// Ensure initializeBrowser is mocked but should NOT be called
|
|
164
|
+
mockBrowserManager.initializeBrowser.mockResolvedValue(undefined);
|
|
147
165
|
const args = { headless: false };
|
|
148
166
|
// Act & Assert: Should throw workflow validation error
|
|
149
167
|
await expect(handleBrowserInit(args)).rejects.toThrow(/Browser already initialized.*Next Steps: Close browser first/s);
|
|
150
168
|
// Verify that browser initialization was NOT called due to validation failure
|
|
151
169
|
expect(mockBrowserManager.initializeBrowser).not.toHaveBeenCalled();
|
|
152
|
-
expect(
|
|
170
|
+
expect(mockRecordExecution).toHaveBeenCalledWith('browser_init', expect.objectContaining({ headless: false }), false, expect.stringContaining('Browser already initialized'));
|
|
153
171
|
});
|
|
154
172
|
it('should include workflow guidance in success message', async () => {
|
|
155
173
|
// Arrange: Set up for successful initialization (keep existing mock setup)
|
|
@@ -30,13 +30,17 @@ vi.mock('../token-management.js', () => ({
|
|
|
30
30
|
}));
|
|
31
31
|
// Mock TurndownService
|
|
32
32
|
vi.mock('turndown', () => {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const createMockInstance = () => {
|
|
34
|
+
const mockInstance = {
|
|
35
|
+
turndown: vi.fn().mockReturnValue('# Mock Markdown\n\nContent converted to markdown.'),
|
|
36
|
+
addRule: vi.fn()
|
|
37
|
+
};
|
|
38
|
+
// addRule should return the instance for chaining
|
|
39
|
+
mockInstance.addRule.mockReturnValue(mockInstance);
|
|
40
|
+
return mockInstance;
|
|
36
41
|
};
|
|
37
|
-
mockInstance.addRule.mockReturnValue(mockInstance);
|
|
38
42
|
return {
|
|
39
|
-
default: vi.fn().mockImplementation(
|
|
43
|
+
default: vi.fn().mockImplementation(createMockInstance)
|
|
40
44
|
};
|
|
41
45
|
});
|
|
42
46
|
describe('file-handlers', () => {
|
|
@@ -26,14 +26,15 @@ vi.mock('../workflow-validation', () => ({
|
|
|
26
26
|
}
|
|
27
27
|
}));
|
|
28
28
|
// Mock setTimeout globally - track delays without immediate execution for exponential backoff testing
|
|
29
|
+
const originalSetTimeout = global.setTimeout;
|
|
29
30
|
const setTimeoutMock = vi.fn((callback, delay) => {
|
|
30
31
|
// Store the delay for assertion while allowing async execution
|
|
31
|
-
setTimeout
|
|
32
|
+
// Use the original setTimeout to avoid recursion
|
|
33
|
+
return originalSetTimeout(() => {
|
|
32
34
|
if (typeof callback === 'function') {
|
|
33
35
|
callback();
|
|
34
36
|
}
|
|
35
37
|
}, 0); // Execute asynchronously but immediately for test speed
|
|
36
|
-
return 1;
|
|
37
38
|
});
|
|
38
39
|
vi.stubGlobal('setTimeout', setTimeoutMock);
|
|
39
40
|
// Import mocked modules
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { setupProcessCleanup } from './core-infrastructure.js';
|
|
|
20
20
|
console.error('🔍 [DEBUG] Loading handlers...');
|
|
21
21
|
import { handleBrowserInit, handleBrowserClose } from './handlers/browser-handlers.js';
|
|
22
22
|
import { handleNavigate, handleWait } from './handlers/navigation-handlers.js';
|
|
23
|
-
import { handleClick, handleType, handleSolveCaptcha, handleRandomScroll } from './handlers/interaction-handlers.js';
|
|
23
|
+
import { handleClick, handleType, handleSelect, handleSolveCaptcha, handleRandomScroll } from './handlers/interaction-handlers.js';
|
|
24
24
|
import { handleGetContent, handleFindSelector } from './handlers/content-handlers.js';
|
|
25
25
|
import { handleSaveContentAsMarkdown } from './handlers/file-handlers.js';
|
|
26
26
|
console.error('🔍 [DEBUG] All modules loaded successfully');
|
|
@@ -87,6 +87,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
87
87
|
return await handleClick(args);
|
|
88
88
|
case TOOL_NAMES.TYPE:
|
|
89
89
|
return await handleType(args);
|
|
90
|
+
case TOOL_NAMES.SELECT:
|
|
91
|
+
return await handleSelect(args);
|
|
90
92
|
case TOOL_NAMES.WAIT:
|
|
91
93
|
return await handleWait(args);
|
|
92
94
|
case TOOL_NAMES.BROWSER_CLOSE:
|
package/dist/tool-definitions.js
CHANGED
|
@@ -341,6 +341,6 @@ export const TOOL_NAMES = {
|
|
|
341
341
|
export const TOOL_CATEGORIES = {
|
|
342
342
|
BROWSER_MANAGEMENT: [TOOL_NAMES.BROWSER_INIT, TOOL_NAMES.BROWSER_CLOSE],
|
|
343
343
|
NAVIGATION: [TOOL_NAMES.NAVIGATE, TOOL_NAMES.WAIT],
|
|
344
|
-
INTERACTION: [TOOL_NAMES.CLICK, TOOL_NAMES.TYPE, TOOL_NAMES.SOLVE_CAPTCHA, TOOL_NAMES.RANDOM_SCROLL],
|
|
344
|
+
INTERACTION: [TOOL_NAMES.CLICK, TOOL_NAMES.TYPE, TOOL_NAMES.SELECT, TOOL_NAMES.SOLVE_CAPTCHA, TOOL_NAMES.RANDOM_SCROLL],
|
|
345
345
|
CONTENT: [TOOL_NAMES.GET_CONTENT, TOOL_NAMES.FIND_SELECTOR, TOOL_NAMES.SAVE_CONTENT_AS_MARKDOWN],
|
|
346
346
|
};
|