Weinre: Remote Firebug

Weinre provides a Firebug-like (WebKit's Web Inspector) remote interface in pure JavaScript! And it was so easy to setup.

I'm developing web apps that will run on set-top boxes (STB), and everywhere else, of course. The browsers have no JavaScript consoles, no Firebug, sometimes there isn't even a keyboard attached. And lots of (in)compatibility problems$#@!

Setup

  1. npm install weinre
  2. And just run it!
    $ ./node_modules/weinre/weinre --boundHost=-all-
    2013-08-22T17:45:47.645Z weinre: starting server at http://localhost:8080
    ...
  3. Open the remote console in Chromium: http://localhost:8080/elitist/client/. I'm running Weinre and Chromium (for remote debugging) on the same workstation, thus localhost, but they can also be hosted separately.
  4. I preferred to only inject the (target's) client side JS on demand, to avoid the performance cost:
    // Inject script to load Weinre.
    $("head").append('<script id="weinre" type="text/javascript" src="http://workstation:8080/target/target-script-min.js"></script>');
    (Maybe should've used an AMD instead?) I run this in the STB when, eg, some key is pressed.
  5. When that script is injected, a "target" automatically appears in the remote console (Chromium on the workstation), and I can then mess with the STB browser's DOM, run JavaScript (jQuery! ;o) commands, etc.

"It works!"

  1. Cute that Weinre works even in an iframe, because loaded by the nested page. Debugger doesn't show the parent frame's DOM, obviously.
  2. In the JS console I can see the value of navigator (a global variable), eg, in Android 4:
    appCodeName: "Mozilla"
    appName: "Netscape"
    appVersion: "5.0 (iPad; CPU OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A4..."
    connection: Connection
    cookieEnabled: true
    geolocation: Geolocation
    language: "en-DE"
    mimeTypes: DOMMimeTypeArray
    onLine: true
    platform: "Linux armv7l"
    plugins: DOMPluginArray
    product: "Gecko"
    productSub: "20030107"
    userAgent: "Mozilla/5.0 (iPad; CPU OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mo..."
    vendor: "Google Inc."
    vendorSub: ""
    __proto__: Navigator
    Useful for customizing a Modernizr build.
  3. jQuery!

But…

  1. Spams stderr, eg:
    2013-08-14T13:10:56.246Z weinre: client c-8: Callback::invoke exception invoking callback: bound([object Object]): TypeError: Cannot read property 'section' of null
    2013-08-14T13:11:50.816Z weinre: client c-8: weinre: invocation exception on Object.setChildNodes(): TypeError: Cannot read property 'children' of undefined
    2013-08-14T13:32:33.563Z weinre: client c-8: weinre: invocation exception on Object.characterDataModified(): TypeError: Cannot set property '_nodeValue' of undefined
    2013-08-15T07:14:48.649Z weinre: client c-8: Callback::invoke exception invoking callback: bound(6): TypeError: Cannot call method 'keySet' of undefined
  2. Double invocation of the script causes:
    2013-08-15T08:55:43.997Z weinre: target t-4: weinre: invocation exception on WeinreTargetEventsImpl.connectionCreated(): TypeError: Cannot read property '__weinre__id' of undefined
    I avoided reloading by giving the script an ID and if (! $("#weinre").length).
  3. Highlighted layouts often look wrong, but pro'ly Android's browser's fault.

Nevertheless, a killer app. ;o)

Related

  1. node-inspector
  2. Blink

--
The real world is a special case