Skip to content

Instantly share code, notes, and snippets.

@kanzure
Created December 22, 2012 09:53
Show Gist options
  • Save kanzure/4358293 to your computer and use it in GitHub Desktop.
Save kanzure/4358293 to your computer and use it in GitHub Desktop.
proof of concept for a command-line interface to the webkit inspector
#!/usr/bin/env node
#
# Proof of concept for accessing the WebKit Inspector from the shell. This
# traverses the DOM and dumps the raw HTML. A more sophisticated demo might
# allow you to inject javascript into the page. Also, this works with phantomjs
# out of the box.
#
# things to install:
# google-chrome --remote-debugging-port=9222 https://gmail.com/
# npm install traverse request ws
# sudo npm install -g coffee-script
# coffee -c webkit-inspector-shell.coffee && node webkit-inspector-shell.js
#
# things to do:
# 1) basic arguments and commands
# 2) DOM
# 3) CSS
# 4) JS debugging, watchpoints, breakpoints, stepping
# 5) network traffic
# 6) code clean up
# 7) testing
traverse = require("traverse")
request = require("request")
WebSocket = require("ws")
url = "http://localhost:9222/json"
requestTabs = (url, callback) ->
handleResponse = (error, response, body) ->
if (error)
console.log("error was: " + error)
else
tabs = JSON.parse(body)
callback(tabs)
request(url, handleResponse)
getWebSocketConnection = (url, callback) ->
tabHandler = (tabs) =>
webSocketDebuggerUrl = tabs[0]["webSocketDebuggerUrl"]
# wtf why doesn't the url include localhost?
if (/ws:\/\/\//.test(webSocketDebuggerUrl))
webSocketDebuggerUrl = webSocketDebuggerUrl.replace("ws:///", "ws://localhost:9222/")
console.log("webSocketDebuggerUrl: " + webSocketDebuggerUrl)
ws = new WebSocket(webSocketDebuggerUrl)
callback(webSocketDebuggerUrl, ws)
requestTabs(url, tabHandler)
class WebSocketMessageSystem
constructor: (url) ->
@url = url
@dom = {}
@messages = {}
@message_counter = 0
getWebSocketConnection(url, @webSocketSetup)
webSocketSetup: (webSocketDebuggerUrl, ws) =>
@ws = ws
self = @
onMessage = (data, flags) =>
data = JSON.parse(data)
# console.log("message received: " + JSON.stringify(data))
id = data["id"]
if (id of self.messages)
self.messages[id](data, flags)
else
console.log("unable to find a callback for id: " + id)
onOpen = =>
console.log("WebSocket <" + webSocketDebuggerUrl + "> opened, sending hello..")
# self.ws.send(JSON.stringify({"id": 1, "method": "DOM.getDocument"}))
# self.send("DOM.getDocument", {}, self.consumeDOM)
# get the DOM root node, then go get the HTML
self.send("DOM.getDocument", {}, self.getOuterHTML)
ws.on("open", onOpen)
ws.on("message", onMessage)
send: (method, params, callback) =>
if (!params)
params = {}
@message_counter += 1
id = @message_counter
@messages[id] = callback
payload =
"id": id
"method": method
"params": params
@ws.send(JSON.stringify(payload))
consumeDOM: (data, flags) =>
# console.log("consumeDOM was called with data: " + JSON.stringify(data))
# requests HTML for the DOM's root node
getOuterHTML: (data, flags) =>
nodeId = data["result"]["root"]["nodeId"]
@send("DOM.getOuterHTML", {"nodeId": nodeId}, @showHTML)
# dumps HTML for the DOM's root node
showHTML: (data, flags) =>
console.log("yep: " + data["result"]["outerHTML"])
process.exit()
system = new WebSocketMessageSystem(url)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment