initialize(); async function initialize() { const tab = await openInitTab(); await attachDebugger(tab); await autoAttachDebugger(tab); // try to enable emulation(change UA) to make sure debuger is attached chrome.tabs.onUpdated.addListener(() => { sendCommand(tab, 'Emulation.setUserAgentOverride', { userAgent: 'debugger is attached' }); }); } async function openInitTab() { return new Promise((resolve, reject) => { chrome.tabs.create({ url: chrome.runtime.getURL('initial.html') }, async (tab) => { handleRuntimeError(resolve, reject, tab); }); }); } function log(message, obj) { console.log(`[${new Date().toTimeString()}] ${message}`, obj || ''); } async function attachDebugger(tab) { return new Promise((resolve, reject) => { chrome.debugger.attach({ tabId: tab.id }, '1.0', () => { if (handleRuntimeError(resolve, reject, tab)) { log(`Debugger was attached to tab: ${tab.id}`); } }); }); } async function sendCommand(tab, command, options) { return new Promise((resolve, reject) => { chrome.debugger.sendCommand({ tabId: tab.id }, command, options, (result) => { if (handleRuntimeError(resolve, reject, result)) { log(`Command was sent on tab: ${tab.id}, ${command}`, options); } }); }); } function handleRuntimeError(resolve, reject, result) { let errMessage = chrome.runtime.lastError ? chrome.runtime.lastError.message : null; if (errMessage && reject) { reject(errMessage); console.error(errMessage); return false; } resolve(result); return true; } async function autoAttachDebugger(tab) { track([ 'Target.attachedToTarget', 'Target.detachedFromTarget', 'Target.receivedMessageFromTarget', 'Target.targetCreated', 'Target.targetDestroyed', 'Target.targetInfoChanged', 'Target.targetCrashed' ], (params) => { log('Target event', params); }); // DOESNT DO ANYTHING await sendCommand(tab, 'Target.setAutoAttach', { autoAttach: true, waitForDebuggerOnStart: true, flatten: true }); // WILL FAIL WITH {"code":-32000,"message":"Not allowed"} await sendCommand(tab, 'Target.setDiscoverTargets', { discover: true }); } function track(events, callback) { log('Tracking for events:', events); chrome.debugger.onEvent.addListener(function (debuggee, eventType, params) { if (events.includes(eventType)) { log('Received event', { eventType, params }); if (callback) { callback(params); } } }); }