Test your mobile web application using the Ripple Emulator

Are you a mobile web developer or tester looking for new and better ways to test and debug your mobile web? Have you been struggling with testing on multiple devices and across multiple platforms?

If you have developed mobile web application using jQuery Mobile, and wanted to test on your local machine. The Ripple Emulator is best solution to test mobile web application in Google Chrome browser with multiple mobile devices.

Introducing the Ripple Emulator (Beta version)

tinyHippos Inc. has just released the Beta version of The Ripple Emulator and is offering it for FREE during the Beta period.

Ripple is a cross platform emulator, currently supporting the JIL 1.2 API and Opera Widget platforms as well as Mobile Websites. Ripple has been built by developers for developers, therefore; providing a highly customizable environment. You can customize everything from Ripple’s layout to the values that it returns to your widgets. For example:

  • Specify the values that Ripple will return to your widget for things like geo location, mobile device events being fired, etc.
  • Ability to change mobile platforms and devices
  • Toggle between landscape and portrait modes
  • Collapsible / expandable control panels
  • The ability to move the control panels around
  • and many more…

Ripple allows you to look “under the hood” of your mobile widget. It offers you the ability to use existing browser tools, such as the WebKit Web Inspector, to perform JavaScript debugging, HTML DOM inspection, automated testing, as well as multiple device and screen resolution emulation in real-time without having to redeploy the mobile widget or restart the emulator.

Here’s a screen shot showing you what the Ripple Emulator looks like:

How can you get Ripple

Download:

  • Ripple runs as a Google Chrome extension and is a simple, one click, install. You can find the download/installation page here.

Requirements:

  • You need to have the Google Chrome browser installed on your computer. You can download it here if you don’t already have it: http://www.google.com/chrome
  • If you’re working with mobile widgets on your computer, you’ll need to run a local HTTP server.

Getting Started:

To walk through the features available in Ripple, a Demo Widget has been created. All you have to do to get started is:

Want to find out more?

If you’d like to find out more about Ripple, here are some handy resources.

Introduction to jQuery Mobile

What is jQuery Mobile?

  • Mobile framework using jQuery (obviously).
  • Aggressively cross-browser, cross-platform.
  • Create web apps that feel as close to native as possible.
  • Markup driven, minimal code required to get up and running.
  • Focused on progressive enhancement, graceful degradation.

Targeted Platforms

  • iOS, Android, Windows Mobile
  • Blackberry, Symbian, webOS
  • Firefox Mobile (Fennec), Opera Mobile / Mini
  • Meego, bada, Maemo…
  • Phonegap!

Basic Page Elements

  • Custom elements declared using DIVs with ‘data-role’ attributes
  • At least one ‘data-role=”page”‘ element.
  • Inside the page, at least one ‘data-role=”content”‘ element.
  • Classes are added automatically.
  • Form elements and lists are automatically enhanced.

Basic Page Markup

<!doctype html> 
<html> 
  <head> 
  <title>Page Title</title> 
  <link rel="stylesheet" href="jquery.mobile.css" />
  <script src="jquery.js"></script>
  <script src="jquery.mobile.js"></script>
</head> 
<body> 

<div data-role="page">

  <div data-role="header">
    <h1>Page Title</h1>
  </div>

  <div data-role="content">  
    <p>Page content goes here.</p>    
  </div>

  <div data-role="footer">
    <h4>Page Footer</h4>
  </div>
</div>
</body>
</html>

Virtual Pages

<div data-role="page" id="page1">
  <div data-role="header">
    <h1>Page 1</h1>
  </div>
  <div data-role="content">
    <a href="#page2" data-role="button">Go to Page 2</a>
  </div>
</div>

<div data-role="page" id="page2">
  <div data-role="header">
    <h1>Page 2</h1>
  </div>
  <div data-role="content">
    <a href="#page1" data-role="button">Go to Page 1</a>  
  </div>
</div>

Separate Pages with AJAX Loading

<div data-role="page">
  <div data-role="header">
    <h1>Page 1</h1>
  </div>
  <div data-role="content">
    <a href="page2.html" data-role="button">Go to Page 2</a>
  </div>
</div>

Fixed Footer Navigation

<div data-role="footer" data-id="myfooter" data-position="fixed">
  <div data-role="navbar">
    <ul>
      <li><a href="footer.html" class="ui-btn-active">One</a></li>
      <li><a href="footer2.html">Two</a></li>
      <li><a href="footer3.html">Three</a></li>
    </ul>
  </div>
</div>

// Second page
<div data-role="footer" data-id="myfooter" data-position="fixed">
  <div data-role="navbar">
    <ul>
      <li><a href="footer.html">One</a></li>
      <li><a href="footer2.html" class="ui-btn-active">Two</a></li>
      <li><a href="footer3.html">Three</a></li>
    </ul>
  </div>
</div>

// Third page
<div data-role="footer" data-id="myfooter" data-position="fixed">
  <div data-role="navbar">
    <ul>
      <li><a href="footer.html">One</a></li>
      <li><a href="footer2.html">Two</a></li>
      <li><a href="footer3.html" class="ui-btn-active">Three</a></li>
    </ul>
  </div>
</div>

AJAX Loading In Depth

  • Every page must fit the jQuery Mobile standard.
  • Pages are injected into the DOM with a transition if AJAX is supported, otherwise a regular page load occurs.
  • If the page fails to load, the user receives a friendly, themed error message.
  • When linking to a non-mobile page on the same domain, use rel=”external”.
  • Links to different domains are detected automatically, triggering a regular load.

Form Elements

  • Regular form elements are automatically enhanced for mobile usability.
  • All controls gracefully degrade to their native equivalents.
  • Default settings can be changed to meet your needs.

Form Element Markup

<div data-role="fieldcontain"> 
  <label for="textbox">Textbox:</label> 
  <input type="text" name="textbox" id="textbox" value=""  /> 
</div>

<div data-role="fieldcontain"> 
  <label for="textarea">Textarea:</label> 
  <textarea name="textarea" id="textarea" value=""></textarea>
</div>

<div data-role="fieldcontain"> 
  <label for="search">Search:</label> 
  <input type="search" name="search" id="search" value=""  /> 
</div>

<div data-role="fieldcontain"> 
  <label for="slider">Slider:</label> 
  <select name="slider" id="slider" data-role="slider"> 
    <option value="0">Off</option>
    <option value="1">On</option>
  </select>
</div>

<div data-role="fieldcontain"> 
  <label for="range">Range:</label>
  <input type="range" name="range" value="0" min="0" max="10" /> 
</div>

<div data-role="fieldcontain"> 
  <fieldset data-role="controlgroup"> 
    <legend>Checklist:</legend>
    <input type="checkbox" name="checkbox1" id="checkbox1" /> 
    <label for="checkbox1">HTML</label> 

    <input type="checkbox" name="checkbox2" id="checkbox2" /> 
    <label for="checkbox2">CSS</label> 

    <input type="checkbox" name="checkbox3" id="checkbox3" /> 
    <label for="checkbox3">JavaScript</label>
  </fieldset>
</div>

<div data-role="fieldcontain"> 
  <fieldset data-role="controlgroup" data-type="horizontal"> 
    <legend>Horizontal Checklist:</legend>
    <input type="checkbox" name="checkbox4" id="checkbox4" /> 
    <label for="checkbox4">Tea</label>

    <input type="checkbox" name="checkbox5" id="checkbox5" /> 
    <label for="checkbox5">Coffee</label>
  </fieldset> 
</div>

<div data-role="fieldcontain"> 
  <fieldset data-role="controlgroup">
    <legend>Radio Buttons:</legend>
      <input type="radio" name="radio1" id="radio1a" value="a" /> 
      <label for="radio1a">HTML5</label>

      <input type="radio" name="radio1" id="radio1b" value="b" /> 
      <label for="radio1b">Flash</label>

      <input type="radio" name="radio1" id="radio1c" value="c" /> 
      <label for="radio1c">Silverlight</label>
  </fieldset>
</div>

<div data-role="fieldcontain"> 
  <fieldset data-role="controlgroup" data-type="horizontal">
    <legend>Horizontal Radio Buttons:</legend>
      <input type="radio" name="radio2" id="radio2a" value="a" /> 
      <label for="radio2a">Tea</label>

      <input type="radio" name="radio2" id="radio2b" value="b" /> 
      <label for="radio2b">Coffee</label>
  </fieldset>
</div>

<div data-role="fieldcontain">
  <label for="select1" class="select">Standard Select:</label>
  <select name="select1" id="select1">
    <option value="1">HTML5</option>
    <option value="2">Flash</option>
    <option value="3">Silverlight</option>
  </select>
</div>

<div data-role="fieldcontain">
  <label for="select2" class="select">Custom Select:</label>
  <select name="select2" id="select2" data-native-menu="false">
    <option value="1">HTML5</option>
    <option value="2">Flash</option>
    <option value="3">Silverlight</option>
  </select>
</div>

<button name="button" name="button">Button</button>
<button type="submit" name="submit">Submit</button>

List View Markup

<h4>Basic List View</h4>

<ul data-role="listview" data-inset="true">
  <li>HTML</li>
  <li>JavaScript</li>
  <li>CSS</li>
</ul>

<h4>Linked List View</h4>

<ul data-role="listview" data-inset="true">
  <li><a href="target.html">HTML</a></li>
  <li><a href="target.html">JavaScript</a></li>
  <li><a href="target.html">CSS</a></li>
</ul>

<h4>Ordered List View</h4>

<ol data-role="listview" data-inset="true">
  <li><a href="target.html">HTML</a></li>
  <li><a href="target.html">JavaScript</a></li>
  <li><a href="target.html">CSS</a></li>
</ol>

<h4>Nested List View</h4>

<ul data-role="listview" data-inset="true">
  <li>
    iOS
    <ul data-role="listview" data-inset="true">
      <li><a href="target.html">v2.2.1</a></li>
      <li><a href="target.html">v3.1.3, v3.2</a></li>
      <li><a href="target.html">v4.0</a></li>
    </ul>
  </li>
  <li>
    Android
    <ul data-role="listview" data-inset="true">
      <li><a href="target.html">v1.5, v1.6</a></li>
      <li><a href="target.html">v2.1</a></li>
      <li><a href="target.html">v2.2</a></li>
    </ul>
  </li>
  <li>
    Windows Mobile
    <ul data-role="listview" data-inset="true">
      <li><a href="target.html">v6.1</a></li>
      <li><a href="target.html">v6.5.1</a></li>
      <li><a href="target.html">v7.0</a></li>
    </ul>
  </li>
</ul>

<h4>Searchable List View</h4>

<ul data-role="listview" data-inset="true" data-filter="true">
  <li><a href="target.html">HTML</a></li>
  <li><a href="target.html">JavaScript</a></li>
  <li><a href="target.html">CSS</a></li>
</ul>

<h4>Split Button List View</h4>

<ul data-role="listview" data-inset="true">
  <li>
    <a href="target.html">HTML</a>
    <a href="options.html" data-icon="gear">Options</a>
  </li>
  <li>
    <a href="target.html">JavaScript</a>
    <a href="options.html" data-icon="gear">Options</a>
  </li>
  <li>
    <a href="target.html">CSS</a>
    <a href="options.html" data-icon="gear">Options</a>
  </li>
</ul>

<h4>Thumbnail List View</h4>

<ul data-role="listview">
  <li>
    <a href="target.html">
      <img src="thumbnail1.jpg" />
      <h3>Miles Davis</h3>
      <p>Kind of Blue<p>
    </a>
  </li>
  <li>
    <a href="target.html">
      <img src="thumbnail2.jpg" />
      <h3>Cannonball Adderley</h3>
      <p>Somethin' Else</p>
    </a>
  </li>
  <li>
    <a href="target.html">
      <img src="thumbnail3.jpg" />
      <h3>Charles Mingus</h3>
      <p>The Black Saint and the Sinner Lady</p>
    </a>
  </li>
</ul>

So where’s the JavaScript?

  • Oh yeah, I almost forgot.

New Events!

  • User events: tap, taphold, swipe, swipeleft, swiperight, orientationchange, scrollstart, scrollstop.
  • Page events: pagebeforeshow, pagebeforehide, pageshow, pagehide.
  • $(document).ready()?: pagebeforecreate, pagecreate.

New Functions!

  • $.mobile.changePage(options)
  • $.fn.listview(), $.fn.selectmenu() etc…
  • $.fn.listview(‘refresh’), $.fn.selectmenu(‘refresh’) etc…
  • $.fn.jqmData(), $.fn.jqmRemoveData(), and $.fn.jqmHasData()
  • $.mobile.pageLoading(bool)
    Show or, if bool is false, hide loading indicator.
  • $.mobile.silentScroll(y)
  • $.mobile.media() – Run cross-browser media queries!

Responsive Layout HTML Classes

  • .portrait and .landscape classes.
  • .min-width-x and .max-width-x classes
    (x == 320, 480, 768 and 1024)
  • Create custom width breakpoints with $.mobile.addResolutionBreakpoints()

Now What?

  • I haven’t covered everything, so…
  • Go read the full API docs at jquerymobile.com.
  • Grab a copy and try it for yourself.
  • Follow @jquerymobile to keep up with developments.