Skip to content

Commit a71e00d

Browse files
committed
Add server discovery to Chrome extension with configurable host/port settings
1 parent 46e6cf3 commit a71e00d

File tree

4 files changed

+340
-107
lines changed

4 files changed

+340
-107
lines changed

chrome-extension/background.js

Lines changed: 76 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,98 @@
11
// Listen for messages from the devtools panel
22
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
33
if (message.type === "CAPTURE_SCREENSHOT" && message.tabId) {
4-
// Get the inspected window's tab
5-
chrome.tabs.get(message.tabId, (tab) => {
6-
if (chrome.runtime.lastError) {
7-
console.error("Error getting tab:", chrome.runtime.lastError);
8-
sendResponse({
9-
success: false,
10-
error: chrome.runtime.lastError.message,
11-
});
12-
return;
13-
}
14-
15-
// Get all windows to find the one containing our tab
16-
chrome.windows.getAll({ populate: true }, (windows) => {
17-
const targetWindow = windows.find(w =>
18-
w.tabs.some(t => t.id === message.tabId)
19-
);
4+
// First get the server settings
5+
chrome.storage.local.get(["browserConnectorSettings"], (result) => {
6+
const settings = result.browserConnectorSettings || {
7+
serverHost: "localhost",
8+
serverPort: 3025,
9+
};
2010

21-
if (!targetWindow) {
22-
console.error("Could not find window containing the inspected tab");
11+
// Get the inspected window's tab
12+
chrome.tabs.get(message.tabId, (tab) => {
13+
if (chrome.runtime.lastError) {
14+
console.error("Error getting tab:", chrome.runtime.lastError);
2315
sendResponse({
2416
success: false,
25-
error: "Could not find window containing the inspected tab"
17+
error: chrome.runtime.lastError.message,
2618
});
2719
return;
2820
}
2921

30-
// Capture screenshot of the window containing our tab
31-
chrome.tabs.captureVisibleTab(targetWindow.id, { format: "png" }, (dataUrl) => {
32-
// Ignore DevTools panel capture error if it occurs
33-
if (chrome.runtime.lastError &&
34-
!chrome.runtime.lastError.message.includes("devtools://")) {
35-
console.error("Error capturing screenshot:", chrome.runtime.lastError);
22+
// Get all windows to find the one containing our tab
23+
chrome.windows.getAll({ populate: true }, (windows) => {
24+
const targetWindow = windows.find((w) =>
25+
w.tabs.some((t) => t.id === message.tabId)
26+
);
27+
28+
if (!targetWindow) {
29+
console.error("Could not find window containing the inspected tab");
3630
sendResponse({
3731
success: false,
38-
error: chrome.runtime.lastError.message,
32+
error: "Could not find window containing the inspected tab",
3933
});
4034
return;
4135
}
4236

43-
// Send screenshot data to browser connector
44-
fetch("http://127.0.0.1:3025/screenshot", {
45-
method: "POST",
46-
headers: {
47-
"Content-Type": "application/json",
48-
},
49-
body: JSON.stringify({
50-
data: dataUrl,
51-
path: message.screenshotPath,
52-
}),
53-
})
54-
.then((response) => response.json())
55-
.then((result) => {
56-
if (result.error) {
57-
console.error("Error from server:", result.error);
58-
sendResponse({ success: false, error: result.error });
59-
} else {
60-
console.log("Screenshot saved successfully:", result.path);
61-
// Send success response even if DevTools capture failed
37+
// Capture screenshot of the window containing our tab
38+
chrome.tabs.captureVisibleTab(
39+
targetWindow.id,
40+
{ format: "png" },
41+
(dataUrl) => {
42+
// Ignore DevTools panel capture error if it occurs
43+
if (
44+
chrome.runtime.lastError &&
45+
!chrome.runtime.lastError.message.includes("devtools://")
46+
) {
47+
console.error(
48+
"Error capturing screenshot:",
49+
chrome.runtime.lastError
50+
);
6251
sendResponse({
63-
success: true,
64-
path: result.path,
65-
title: tab.title || "Current Tab"
52+
success: false,
53+
error: chrome.runtime.lastError.message,
6654
});
55+
return;
6756
}
68-
})
69-
.catch((error) => {
70-
console.error("Error sending screenshot data:", error);
71-
sendResponse({
72-
success: false,
73-
error: error.message || "Failed to save screenshot",
74-
});
75-
});
57+
58+
// Send screenshot data to browser connector using configured settings
59+
const serverUrl = `http://${settings.serverHost}:${settings.serverPort}/screenshot`;
60+
console.log(`Sending screenshot to ${serverUrl}`);
61+
62+
fetch(serverUrl, {
63+
method: "POST",
64+
headers: {
65+
"Content-Type": "application/json",
66+
},
67+
body: JSON.stringify({
68+
data: dataUrl,
69+
path: message.screenshotPath,
70+
}),
71+
})
72+
.then((response) => response.json())
73+
.then((result) => {
74+
if (result.error) {
75+
console.error("Error from server:", result.error);
76+
sendResponse({ success: false, error: result.error });
77+
} else {
78+
console.log("Screenshot saved successfully:", result.path);
79+
// Send success response even if DevTools capture failed
80+
sendResponse({
81+
success: true,
82+
path: result.path,
83+
title: tab.title || "Current Tab",
84+
});
85+
}
86+
})
87+
.catch((error) => {
88+
console.error("Error sending screenshot data:", error);
89+
sendResponse({
90+
success: false,
91+
error: error.message || "Failed to save screenshot",
92+
});
93+
});
94+
}
95+
);
7696
});
7797
});
7898
});

chrome-extension/devtools.js

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ let settings = {
99
showRequestHeaders: false,
1010
showResponseHeaders: false,
1111
screenshotPath: "", // Add new setting for screenshot path
12+
serverHost: "localhost", // Default server host
13+
serverPort: 3025, // Default server port
1214
};
1315

1416
// Keep track of debugger state
@@ -29,6 +31,16 @@ chrome.storage.local.get(["browserConnectorSettings"], (result) => {
2931
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
3032
if (message.type === "SETTINGS_UPDATED") {
3133
settings = message.settings;
34+
35+
// If server settings changed and we have a WebSocket, reconnect
36+
if (
37+
ws &&
38+
(message.settings.serverHost !== settings.serverHost ||
39+
message.settings.serverPort !== settings.serverPort)
40+
) {
41+
console.log("Server settings changed, reconnecting WebSocket...");
42+
setupWebSocket();
43+
}
3244
}
3345
});
3446

@@ -242,34 +254,51 @@ function sendToBrowserConnector(logData) {
242254
);
243255
}
244256

245-
fetch("http://127.0.0.1:3025/extension-log", {
257+
const serverUrl = `http://${settings.serverHost}:${settings.serverPort}/extension-log`;
258+
console.log(`Sending log to ${serverUrl}`);
259+
260+
fetch(serverUrl, {
246261
method: "POST",
247262
headers: { "Content-Type": "application/json" },
248263
body: JSON.stringify(payload),
249264
})
250265
.then((response) => {
251266
if (!response.ok) {
252-
throw new Error(`HTTP error! status: ${response.status}`);
267+
throw new Error(`HTTP error ${response.status}`);
253268
}
254-
console.log("Successfully sent log to browser-connector");
255269
return response.json();
256270
})
257271
.then((data) => {
258-
console.log("Browser connector response:", data);
272+
console.log("Log sent successfully:", data);
259273
})
260274
.catch((error) => {
261-
console.error("Failed to send log to browser-connector:", error);
275+
console.error("Error sending log:", error);
262276
});
263277
}
264278

265-
// Add function to wipe logs
279+
// Function to clear logs on the server
266280
function wipeLogs() {
267-
fetch("http://127.0.0.1:3025/wipelogs", {
281+
console.log("Wiping all logs...");
282+
283+
const serverUrl = `http://${settings.serverHost}:${settings.serverPort}/wipelogs`;
284+
console.log(`Sending wipe request to ${serverUrl}`);
285+
286+
fetch(serverUrl, {
268287
method: "POST",
269288
headers: { "Content-Type": "application/json" },
270-
}).catch((error) => {
271-
console.error("Failed to wipe logs:", error);
272-
});
289+
})
290+
.then((response) => {
291+
if (!response.ok) {
292+
throw new Error(`HTTP error ${response.status}`);
293+
}
294+
return response.json();
295+
})
296+
.then((data) => {
297+
console.log("Logs wiped successfully:", data);
298+
})
299+
.catch((error) => {
300+
console.error("Error wiping logs:", error);
301+
});
273302
}
274303

275304
// Listen for page refreshes
@@ -529,7 +558,30 @@ function setupWebSocket() {
529558
ws.close();
530559
}
531560

532-
ws = new WebSocket("ws://localhost:3025/extension-ws");
561+
const wsUrl = `ws://${settings.serverHost}:${settings.serverPort}/extension-ws`;
562+
console.log(`Connecting to WebSocket at ${wsUrl}`);
563+
564+
ws = new WebSocket(wsUrl);
565+
566+
ws.onopen = () => {
567+
console.log(`Chrome Extension: WebSocket connected to ${wsUrl}`);
568+
};
569+
570+
ws.onerror = (error) => {
571+
console.error(`Chrome Extension: WebSocket error for ${wsUrl}:`, error);
572+
};
573+
574+
ws.onclose = (event) => {
575+
console.log(`Chrome Extension: WebSocket closed for ${wsUrl}:`, event);
576+
577+
// Try to reconnect after delay
578+
setTimeout(() => {
579+
console.log(
580+
`Chrome Extension: Attempting to reconnect WebSocket to ${wsUrl}`
581+
);
582+
setupWebSocket();
583+
}, WS_RECONNECT_DELAY);
584+
};
533585

534586
ws.onmessage = async (event) => {
535587
try {
@@ -580,25 +632,6 @@ function setupWebSocket() {
580632
);
581633
}
582634
};
583-
584-
ws.onopen = () => {
585-
console.log("Chrome Extension: WebSocket connected");
586-
if (wsReconnectTimeout) {
587-
clearTimeout(wsReconnectTimeout);
588-
wsReconnectTimeout = null;
589-
}
590-
};
591-
592-
ws.onclose = () => {
593-
console.log(
594-
"Chrome Extension: WebSocket disconnected, attempting to reconnect..."
595-
);
596-
wsReconnectTimeout = setTimeout(setupWebSocket, WS_RECONNECT_DELAY);
597-
};
598-
599-
ws.onerror = (error) => {
600-
console.error("Chrome Extension: WebSocket error:", error);
601-
};
602635
}
603636

604637
// Initialize WebSocket connection when DevTools opens

chrome-extension/panel.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,30 @@ <h3>Screenshot Settings</h3>
133133
</div>
134134
</div>
135135

136+
<div class="settings-section">
137+
<h3>Server Connection Settings</h3>
138+
<div class="form-group">
139+
<label for="server-host">Server Host</label>
140+
<input type="text" id="server-host" placeholder="localhost or IP address">
141+
</div>
142+
<div class="form-group">
143+
<label for="server-port">Server Port</label>
144+
<input type="number" id="server-port" min="1" max="65535" value="3025">
145+
</div>
146+
<div class="quick-actions">
147+
<button id="discover-server" class="action-button">
148+
Auto-Discover Server
149+
</button>
150+
<button id="test-connection" class="action-button">
151+
Test Connection
152+
</button>
153+
</div>
154+
<div id="connection-status" style="margin-top: 8px; display: none;">
155+
<span id="status-icon" class="status-indicator"></span>
156+
<span id="status-text"></span>
157+
</div>
158+
</div>
159+
136160
<div class="settings-section">
137161
<div class="settings-header" id="advanced-settings-header">
138162
<h3>Advanced Settings</h3>

0 commit comments

Comments
 (0)