debugging mobile web apps
for:
GOTO Nights Chicago - January 22 2013
by:
Patrick Mueller
@pmuellr
http://muellerware.org/
etc
canonical links to presentation
other mobile debugging presentations by me
slide template
last modified
2
what
This presentation will cover:
what is a mobile web app
what tools are available for debugging them
a demo of the weinre debugger
how the weinre debugger works
3
what is a 'mobile web app '?
web pages running in a mobile browser
aka "web pages" or "web site"
aka "browser app"
native app that uses a 'web control'
4
debug tools by platforms
5
RIM
first mobile platform vendor to ship
real remote Web Inspector implementation from WebKit
works just like Chrome Dev Tools
should just work on modern RIM devices since PlayBook
links
6
iOS
Real remote Web Inspector like Safari 6 Web Inspector
"like Safari 6 Web Inspector" not neccessarily a good thing, wrt UI
only on iOS 6
must use Safari 6 as the client
must have the latest Xcode
links
7
Android
Real remote Web Inspector like Chrome Dev Tools
enabled for Chrome/Android only
not enabled for WebView
so won't work with Cordova :-(
links
8
Windows
???
Ongoing work to
get weinre running on Windows Phone .
9
Boot to Gecko / Firefox OS
Runs applications implemented entirely in HTML, CSS and
JavaScript.
[link]
Also see the slide on r2d2b2g in this presentation.
links
10
debugging tools for platform simulators
11
ripple
Chrome extension allowing you to quickly see how your
application looks and functions on multiple mobile devices
and platforms.
supports using WebWorks and Cordova APIs
supports JavaScript debugging
links
12
r2d2b2g
Firefox extension to run the Boot to Gecko desktop and
apps within Firefox.
links
13
platform agnostic debugging tools
14
jsbin
From the web site:
JS Bin is a webapp specifically designed to help
JavaScript and CSS folk test snippets of code, within some
context, and debug the code collaboratively.
links
15
aardwolf
From the web site:
Aardwolf is a remote JavaScript debugger for iPhone / Android
/ WindowsPhone 7 / BlackBerry OS 6+. It is written in JavaScript.
only cross-platform tool to debug JavaScript
instruments your code before running it
links
16
jsfiddle
Popular HTML, CSS, JavaScript snippet testing environment
includes "Run" option to debug with weinre via
the busy, busy public weinre server at
debug.phonegap.com
links
17
Adobe Edge Inspect
Preview and inspect web designs on mobile devices.
besides lots of other goodies, embeds weinre functionality
hosted service, part of Adobe Creative Cloud
free for one concurrent connection, $$$ for more than one
links
18
rsprofiler
proof-of-concept project for extracting and displaying
dtrace-ishly precise JavaScript performance profiling
can be used wherever you can use Safari 6 desktop or
iOS 6 remote debug
currently displays profile data as an interactive flame
graph
links
19
rsprofiler demo source
function run () {
rsprofiler . start ( "jquery profile" )
runTests ()
rsprofiler . stop ( function ( err ) { ... })
}
function runTests () {
for ( var i = 0 ; i < 40 ; i ++) { runTestsDiv1 (); runTestsSpan1 () }
}
function runTestsDiv1 () {
for ( var i = 0 ; i < 1000 ; i ++) { $ ( "#div-1" ). text () }
}
function runTestsSpan1 () {
for ( var i = 0 ; i < 1000 ; i ++) { $ ( "#span-1" ). text ( $ ( "#span-1" ). text ()) }
}
20
rsprofiler demo flame graph
Thread_1() rsprofiler_start() runTests() runTestsDiv1() jQuery() init() charAt() exec() getElementById() text() access() (anonymous function)() getText() getText() runTestsSpan1() jQuery() init() charAt() exec() getElementById() text() access() (anonymous function)() getText() getText() empty() getElementsByTagName() cleanData() removeChild() createTextNode() append() domManip() concat() isFunction() type() toString() buildFragment() createDocumentFragment() clean() push() nodeName() toLowerCase() appendChild() nodeName() toLowerCase() (anonymous function)() appendChild() isFunction() type() toString() rsprofiler_stop() (idle)()
Hover over a box! Click a box!
21
weinre
UI and a lot of function from Web Inspector
mainly for WebKit-based browsers, other platforms
being tinkered with
NO JAVASCRIPT SOURCE DEBUGGING
run the weinre server on your desktop box
install via sudo npm -g install weinre
links
22
weinre tips and tricks
use --verbose and --debug when things are b0rken
did you use the --boundHost option?
are your device and desktop on the same network?
does the demo shipped with weinre work?
For issues with Cordova, PhoneGap, Worklight:
switch order of the <script src=> entries for weinre.js and cordova.js
did you add your weinre server to the white-list?
23
demo time!
weinre movies here:
old rsprofiler movie here:
24
contribute to weinre!
25
how weinre works
26
weinre is a web server
targets connect by:
adding a <script> element pointing
to the server
using a bookmarklet to add the script
clients connect by:
browsing to the server like any other site
server supports CORS so that target can XHR to a cross-origin host (the weinre server)
client and target use long-polling to enable messaging to/from the server
27
weinre connections
M targets connected to N clients
28
example messages sent
from client to target: (command)
CSS.getStylesForNode()
callback will send result from target to client
from target to client: (event)
DOMNotify.childNodeInserted()
Messages defined as functions described in WebIDL.
~20 interfaces from Web Inspector
6 more interfaces for weinre
29
example message interface
module weinre {
interface WeinreTargetCommands {
void registerTarget(int url, out string targetId);
void sendClientCallback(string callbackId, Object args);
void logDebug( in string message );
void logInfo( in string message );
void logWarning( in string message );
void logError( in string message );
};
}
30
lots of messages sent quickly, sometimes
31
things replaced
window.clearInterval()
window.clearTimeout()
window.setInterval()
window.setTimeout()
window.addEventListener()
Node.addEventListener()
XMLHttpRequest.open()
XMLHttpRequest.send()
XMLHttpRequest.addEventListener()
window.openDatabase()
window.console()
LocalStorage.setItem()
LocalStorage.removeItem()
LocalStorage.clear()
SessionStorage.setItem()
SessionStorage.removeItem()
SessionStorage.clear()
32
questions?
33