brave-real-browser-mcp-server 2.23.8 ā 2.23.9
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.
|
@@ -44,15 +44,31 @@ export async function handleClick(args) {
|
|
|
44
44
|
strategyMessage = `\nš Self-healing: Used ${strategy} fallback selector: ${usedSelector}`;
|
|
45
45
|
tracker.setProgress(50, `š Using fallback selector: ${usedSelector}`);
|
|
46
46
|
}
|
|
47
|
+
// Text-based strategies have special __TEXT__: prefix or are strategy-identified
|
|
48
|
+
// These have invalid CSS selectors, so we skip waitForSelector and use element directly
|
|
49
|
+
const isTextBasedStrategy = ['text-content', 'implicit-text-match', 'text', 'text-exact', 'text-partial', 'tag-text'].includes(strategy) ||
|
|
50
|
+
usedSelector.startsWith('__TEXT__:');
|
|
51
|
+
// Clean display selector for output (remove __TEXT__: prefix)
|
|
52
|
+
const displaySelector = usedSelector.startsWith('__TEXT__:')
|
|
53
|
+
? usedSelector.replace('__TEXT__:', 'text:')
|
|
54
|
+
: usedSelector;
|
|
47
55
|
try {
|
|
48
56
|
tracker.setProgress(60, 'ā³ Waiting for element to be ready...');
|
|
49
|
-
//
|
|
50
|
-
|
|
57
|
+
// Only wait for selector if it's a valid CSS selector (not text-based)
|
|
58
|
+
if (!isTextBasedStrategy) {
|
|
59
|
+
await pageInstance.waitForSelector(usedSelector, { timeout: 5000 });
|
|
60
|
+
}
|
|
51
61
|
// Check element visibility and interaction options
|
|
52
62
|
const boundingBox = await element.boundingBox();
|
|
53
63
|
if (!boundingBox) {
|
|
54
64
|
tracker.setProgress(70, 'š§ No bounding box, using JavaScript click...');
|
|
55
|
-
|
|
65
|
+
// For text-based strategies, use element.evaluate to click
|
|
66
|
+
if (isTextBasedStrategy) {
|
|
67
|
+
await element.evaluate((el) => el.click());
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
await pageInstance.$eval(usedSelector, (el) => el.click());
|
|
71
|
+
}
|
|
56
72
|
}
|
|
57
73
|
else {
|
|
58
74
|
tracker.setProgress(70, 'š±ļø Clicking element...');
|
|
@@ -60,12 +76,13 @@ export async function handleClick(args) {
|
|
|
60
76
|
tracker.setProgress(75, 'š Clicking and waiting for navigation...');
|
|
61
77
|
await Promise.all([
|
|
62
78
|
pageInstance.waitForNavigation({ waitUntil: 'networkidle2' }),
|
|
63
|
-
|
|
79
|
+
element.click(), // Use element.click() for all strategies
|
|
64
80
|
]);
|
|
65
81
|
tracker.setProgress(90, 'ā
Navigation completed');
|
|
66
82
|
}
|
|
67
83
|
else {
|
|
68
|
-
|
|
84
|
+
// Use element.click() directly - works for all strategies
|
|
85
|
+
await element.click();
|
|
69
86
|
}
|
|
70
87
|
}
|
|
71
88
|
tracker.complete('š Click completed successfully');
|
|
@@ -82,7 +99,13 @@ export async function handleClick(args) {
|
|
|
82
99
|
tracker.setProgress(85, 'ā ļø Click failed, trying JavaScript fallback...');
|
|
83
100
|
// Final fallback: JavaScript click
|
|
84
101
|
try {
|
|
85
|
-
|
|
102
|
+
// For text-based strategies, use element.evaluate instead of $eval
|
|
103
|
+
if (isTextBasedStrategy) {
|
|
104
|
+
await element.evaluate((el) => el.click());
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
await pageInstance.$eval(usedSelector, (el) => el.click());
|
|
108
|
+
}
|
|
86
109
|
tracker.complete('š Click completed via JavaScript fallback');
|
|
87
110
|
return {
|
|
88
111
|
content: [
|
|
@@ -145,7 +145,7 @@ export class SelfHealingLocators {
|
|
|
145
145
|
if (element) {
|
|
146
146
|
return {
|
|
147
147
|
element,
|
|
148
|
-
usedSelector:
|
|
148
|
+
usedSelector: `__TEXT__:${textSelector.tagName || '*'}:${textSelector.text}`,
|
|
149
149
|
strategy: 'text-content'
|
|
150
150
|
};
|
|
151
151
|
}
|
|
@@ -171,7 +171,7 @@ export class SelfHealingLocators {
|
|
|
171
171
|
if (textElement) {
|
|
172
172
|
return {
|
|
173
173
|
element: textElement,
|
|
174
|
-
usedSelector:
|
|
174
|
+
usedSelector: `__TEXT__:*:${primarySelector}`,
|
|
175
175
|
strategy: 'implicit-text-match'
|
|
176
176
|
};
|
|
177
177
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brave-real-browser-mcp-server",
|
|
3
|
-
"version": "2.23.
|
|
3
|
+
"version": "2.23.9",
|
|
4
4
|
"description": "š¦ MCP server for Brave Real Browser - NPM Workspaces Monorepo with anti-detection features, SSE streaming, and LSP compatibility",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": "latest",
|
|
52
52
|
"@types/turndown": "latest",
|
|
53
|
-
"brave-real-browser": "^2.4.
|
|
53
|
+
"brave-real-browser": "^2.4.9",
|
|
54
54
|
"turndown": "latest",
|
|
55
55
|
"vscode-languageserver": "^9.0.1",
|
|
56
56
|
"vscode-languageserver-textdocument": "^1.0.12"
|