Index: trunk/extensions/MobileFrontend/tests/js/fixtures.js |
— | — | @@ -0,0 +1,56 @@ |
| 2 | +window.MobileFrontendTests = { |
| 3 | + cleanFixtures: function() { |
| 4 | + $("#zero-rated-banner").remove(); // remove remnants from another test somewhere in test suite |
| 5 | + $("#qunit-fixture-x").remove(); |
| 6 | + }, |
| 7 | + createFixtures: function() { |
| 8 | + this.cleanFixtures(); |
| 9 | + $('<div id="qunit-fixture-x">').html(['<div id="test-env">', |
| 10 | + ' <img id="logo" src="" alt="logo">', |
| 11 | + ' <div id="nav" style="display:none">', |
| 12 | + ' navigation menu', |
| 13 | + ' <select id="languageselection">', |
| 14 | + ' <option value="en">english</option>', |
| 15 | + ' <option value="de">deutsch</option>', |
| 16 | + ' </select>', |
| 17 | + ' </div>', |
| 18 | + ' <div id="zero-rated-banner">', |
| 19 | + ' banner', |
| 20 | + ' <button id="dismiss-notification">dismiss banner</button>', |
| 21 | + ' </div>', |
| 22 | + ' <input type="text" id="search">', |
| 23 | + ' <button id="clearsearch">clear</button>', |
| 24 | + ' <div id="results">search results here</div>', |
| 25 | + ' <div id="content">', |
| 26 | + ' <h2 class="section_heading" id="section_1">', |
| 27 | + ' <button class="section_heading show" section_id="1">Show</button>', |
| 28 | + ' <button class="section_heading hide" section_id="1" style="display:none">Hide</button>', |
| 29 | + ' <span id="First_Section">First Section</span>', |
| 30 | + ' </h2>', |
| 31 | + ' <div class="content_block" id="content_1" style="display:none">', |
| 32 | + ' <p>', |
| 33 | + ' Text', |
| 34 | + ' <span id="First_Section_2">2.1</span>', |
| 35 | + ' </p>', |
| 36 | + ' </div>', |
| 37 | + ' <div id="anchor_1" class="section_anchors" style="display:none">', |
| 38 | + ' <a href="#section_1" class="back_to_top">↑Jump back a section</a>', |
| 39 | + ' </div>', |
| 40 | + ' <h2 class="section_heading" id="section_2">', |
| 41 | + ' <button class="section_heading show" section_id="2">Show</button>', |
| 42 | + ' <button class="section_heading hide" section_id="2" style="display:none">Hide</button>', |
| 43 | + ' <span id="Second_Section">Second Section</span>', |
| 44 | + ' </h2>', |
| 45 | + ' <div class="content_block" id="content_2" style="display:none"><p>Text with a <a href="#First_Section">section 1</a> link! and to <a href="#First_Section_2">section 1.2</a></p></div>', |
| 46 | + ' </div>', |
| 47 | + '</div>'].join("")).appendTo(document.body); |
| 48 | + }, |
| 49 | + triggerEvent: function(el, eventName) { |
| 50 | + // NOTE: this will not work on legacy browsers |
| 51 | + var ev = document.createEvent("HTMLEvents"); |
| 52 | + ev.initEvent(eventName, true, true); |
| 53 | + el.dispatchEvent(ev); |
| 54 | + } |
| 55 | +} |
| 56 | +var scriptPath = "/"; |
| 57 | +window.MobileFrontendTests.createFixtures(); // setup so scripts can initialise |
Index: trunk/extensions/MobileFrontend/tests/js/test_application.js |
— | — | @@ -0,0 +1,183 @@ |
| 2 | +var MFE = MobileFrontend; |
| 3 | +var MFET = window.MobileFrontendTests; |
| 4 | + |
| 5 | +module("MobileFrontend application.js: cookies"); |
| 6 | + |
| 7 | +test("read and write cookies", function() { |
| 8 | + var cookie_name = "test_cookies_module"; |
| 9 | + MFE.writeCookie(cookie_name, "yes", 400); |
| 10 | + var cookieVal = MFE.readCookie(cookie_name); |
| 11 | + strictEqual(cookieVal, "yes", |
| 12 | + "Are you running off localhost?"); |
| 13 | +}); |
| 14 | + |
| 15 | +test("read and write cookies with spaces", function() { |
| 16 | + var cookie_name = "test_cookies_module"; |
| 17 | + MFE.writeCookie(cookie_name, " yes this has spaces ", 400); |
| 18 | + MFE.writeCookie(cookie_name + "2", " yes this has spaces ", 400); |
| 19 | + var cookieVal = MFE.readCookie(cookie_name); |
| 20 | + strictEqual(cookieVal, "yes this has spaces", |
| 21 | + "spaces are kept and trailing whitespace is removed"); |
| 22 | +}); |
| 23 | + |
| 24 | +test("remove cookie via write", function() { |
| 25 | + var cookie_name = "test_cookies_module"; |
| 26 | + MFE.writeCookie(cookie_name, "", -1); |
| 27 | + var cookieVal = MFE.readCookie(cookie_name); |
| 28 | + strictEqual(cookieVal, null, "Cookie deleted"); |
| 29 | +}); |
| 30 | + |
| 31 | +var BANNER_COOKIE_NAME = "zeroRatedBannerVisibility"; |
| 32 | +module("MobileFrontend application.js: notifications", { |
| 33 | + setup: function() { |
| 34 | + MFET.cleanFixtures(); |
| 35 | + MFE.removeCookie(BANNER_COOKIE_NAME); |
| 36 | + MFET.createFixtures(); |
| 37 | + MFE.init(); |
| 38 | + }, |
| 39 | + teardown: function() { |
| 40 | + MFET.cleanFixtures(); |
| 41 | + MFE.removeCookie(BANNER_COOKIE_NAME); |
| 42 | + } |
| 43 | +}); |
| 44 | + |
| 45 | +test("dismiss notification", function() { |
| 46 | + var cookieStart = MFE.readCookie(BANNER_COOKIE_NAME); |
| 47 | + strictEqual(cookieStart, null, "no cookie set at start"); |
| 48 | + strictEqual($("#zero-rated-banner").is(":visible"), true, "banner should be on show"); |
| 49 | + |
| 50 | + // trigger dismiss event |
| 51 | + $("#dismiss-notification").trigger("click"); |
| 52 | + |
| 53 | + var cookieEnd = MFE.readCookie(BANNER_COOKIE_NAME); |
| 54 | + strictEqual(cookieStart, null, "no cookie set at start"); |
| 55 | + strictEqual($("#zero-rated-banner").is(":visible"), false, "banner should now be hidden"); |
| 56 | + strictEqual(cookieEnd, "off", "banner now set for dismissal"); |
| 57 | +}); |
| 58 | + |
| 59 | +module("MobileFrontend application.js: clear search", { |
| 60 | + setup: function() { |
| 61 | + MFET.createFixtures(); |
| 62 | + MFE.init(); |
| 63 | + $("#clearsearch").hide(); |
| 64 | + }, |
| 65 | + teardown: function() { |
| 66 | + MFET.cleanFixtures(); |
| 67 | + } |
| 68 | +}); |
| 69 | + |
| 70 | +test("setup", function() { |
| 71 | + strictEqual($("#clearsearch").attr("title"), "Clear", "check clearsearch tooltip"); |
| 72 | +}); |
| 73 | + |
| 74 | +test("reveal clearsearch on text", function() { |
| 75 | + $("#search").val("hello"); |
| 76 | + var initialVisibility = $("#clearsearch").is(":visible"); |
| 77 | + MFET.triggerEvent($("#search")[0], "keyup") |
| 78 | + strictEqual(initialVisibility, false, "at start clear button should be hidden.") |
| 79 | + strictEqual($("#clearsearch").is(":visible"), true, "clear search is now visible"); |
| 80 | +}); |
| 81 | + |
| 82 | +test("hide clearsearch when no text", function() { |
| 83 | + $("#clearsearch").show(); |
| 84 | + $("#search").val(""); |
| 85 | + var initialVisibility = $("#clearsearch").is(":visible"); |
| 86 | + MFET.triggerEvent($("#search")[0], "keyup"); |
| 87 | + strictEqual(initialVisibility, true, "at start we made it visible") |
| 88 | + strictEqual($("#clearsearch").is("visible"), false, "now invisible due to lack of text in input"); |
| 89 | + strictEqual($("#results").is("visible"), false, "results also hidden"); |
| 90 | +}); |
| 91 | + |
| 92 | +test("click clearSearchBox", function() { |
| 93 | + $("#search").val("hello world"); |
| 94 | + $("#results,#clearsearch").show(); |
| 95 | + |
| 96 | + MFET.triggerEvent($("#clearsearch")[0], "mousedown") |
| 97 | + |
| 98 | + strictEqual($("#search").val(), "", "value reset"); |
| 99 | + strictEqual($("#results").is(":visible"), false, "results hidden"); |
| 100 | + strictEqual($("#clearsearch").is(":visible"), false, "clear search hidden"); |
| 101 | +}); |
| 102 | + |
| 103 | +module("MobileFrontend application.js: logo click", { |
| 104 | + setup: function() { |
| 105 | + MFET.createFixtures(); |
| 106 | + MFE.init(); |
| 107 | + }, |
| 108 | + teardown: function() { |
| 109 | + MFET.cleanFixtures(); |
| 110 | + } |
| 111 | +}); |
| 112 | + |
| 113 | +test("logoClick", function() { |
| 114 | + var visible1 = $("#nav").is(":visible"); |
| 115 | + |
| 116 | + var logo = $("#logo")[0]; |
| 117 | + MFET.triggerEvent(logo, "click"); |
| 118 | + var visible2 = $("#nav").is(":visible"); |
| 119 | + MFET.triggerEvent(logo, "click"); |
| 120 | + var visible3 = $("#nav").is(":visible"); |
| 121 | + |
| 122 | + strictEqual(visible1, false, "starts invisible"); |
| 123 | + strictEqual(visible2, true, "toggle"); |
| 124 | + strictEqual(visible3, false, "toggle"); |
| 125 | +}); |
| 126 | + |
| 127 | +module("MobileFrontend application.js: wm_toggle_section", { |
| 128 | + setup: function() { |
| 129 | + MFET.createFixtures(); |
| 130 | + MFE.init(); |
| 131 | + $("#content_1,#anchor_1,#section_1 .hide").hide(); |
| 132 | + $("#section_1 .show").show(); |
| 133 | + }, |
| 134 | + teardown: function() { |
| 135 | + MFET.cleanFixtures(); |
| 136 | + window.location.hash = "#"; |
| 137 | + } |
| 138 | +}); |
| 139 | + |
| 140 | +test("wm_toggle_section", function() { |
| 141 | + MFE.wm_toggle_section("1"); |
| 142 | + strictEqual($("#content_1").is(":visible"), true, "check content is visible on a toggle"); |
| 143 | + strictEqual($("#anchor_1").is(":visible"), true, "check anchor is visible on toggle"); |
| 144 | + strictEqual($("#section_1 .hide").is(":visible"), true, "check hide button now visible"); |
| 145 | + strictEqual($("#section_1 .show").is(":visible"), false, "check show button now hidden"); |
| 146 | + |
| 147 | + // perform second toggle |
| 148 | + MFE.wm_toggle_section("1"); |
| 149 | + strictEqual($("#content_1").is(":visible"), false, "check content is hidden on a toggle"); |
| 150 | + strictEqual($("#anchor_1").is(":visible"), false, "check anchor is hidden on toggle"); |
| 151 | + strictEqual($("#section_1 .hide").is(":visible"), false, "check hide button now hidden"); |
| 152 | + strictEqual($("#section_1 .show").is(":visible"), true, "check show button now visible"); |
| 153 | +}); |
| 154 | + |
| 155 | +test("wm_reveal_for_hash", function() { |
| 156 | + MFE.wm_reveal_for_hash("#First_Section"); |
| 157 | + strictEqual($("#content_1").is(":visible"), true, "check content is visible on a toggle"); |
| 158 | + strictEqual($("#anchor_1").is(":visible"), true, "check anchor is visible on toggle"); |
| 159 | + strictEqual($("#section_1 .hide").is(":visible"), true, "check hide button now visible"); |
| 160 | + strictEqual($("#section_1 .show").is(":visible"), false, "check show button now hidden"); |
| 161 | +}); |
| 162 | + |
| 163 | +test("wm_reveal_for_hash", function() { |
| 164 | + MFE.wm_reveal_for_hash("#First_Section_2"); |
| 165 | + strictEqual($("#content_1").is(":visible"), true, "check content is visible on a toggle"); |
| 166 | + strictEqual($("#anchor_1").is(":visible"), true, "check anchor is visible on toggle"); |
| 167 | + strictEqual($("#section_1 .hide").is(":visible"), true, "check hide button now visible"); |
| 168 | + strictEqual($("#section_1 .show").is(":visible"), false, "check show button now hidden"); |
| 169 | +}); |
| 170 | + |
| 171 | +test("clicking hash links", function() { |
| 172 | + MFET.triggerEvent($("[href=#First_Section_2]")[0], "click"); |
| 173 | + strictEqual($("#content_1").is(":visible"), true, "check content is visible on a toggle"); |
| 174 | + strictEqual($("#anchor_1").is(":visible"), true, "check anchor is visible on toggle"); |
| 175 | + strictEqual($("#section_1 .hide").is(":visible"), true, "check hide button now visible"); |
| 176 | + strictEqual($("#section_1 .show").is(":visible"), false, "check show button now hidden"); |
| 177 | +}); |
| 178 | + |
| 179 | +test("clicking a heading toggles it", function() { |
| 180 | + var visibilityStart = $("#content_1").is(":visible"); |
| 181 | + MFET.triggerEvent($("#section_1")[0], "click"); |
| 182 | + strictEqual(visibilityStart, false, "check content is hidden at start"); |
| 183 | + strictEqual($("#content_1").is(":visible"), true, "check content is hidden on a toggle"); |
| 184 | +}); |
Index: trunk/extensions/MobileFrontend/MobileFrontend.body.php |
— | — | @@ -1293,6 +1293,17 @@ |
1294 | 1294 | wfProfileOut( __METHOD__ ); |
1295 | 1295 | } |
1296 | 1296 | |
| 1297 | + public function addTestModules( array &$testModules, ResourceLoader &$resourceLoader ) { |
| 1298 | + $testModules['qunit']['ext.mobilefrontend.tests'] = array( |
| 1299 | + 'scripts' => array( 'tests/js/fixtures.js', 'javascripts/application.js', |
| 1300 | + 'tests/js/test_application.js' ), |
| 1301 | + 'dependencies' => array( ), |
| 1302 | + 'localBasePath' => dirname( __FILE__ ), |
| 1303 | + 'remoteExtPath' => 'MobileFrontend', |
| 1304 | + ); |
| 1305 | + return true; |
| 1306 | + } |
| 1307 | + |
1297 | 1308 | public function getVersion() { |
1298 | 1309 | return __CLASS__ . ': $Id$'; |
1299 | 1310 | } |
Index: trunk/extensions/MobileFrontend/MobileFrontend.php |
— | — | @@ -100,6 +100,7 @@ |
101 | 101 | $wgHooks['BeforePageRedirect'][] = array( &$wgExtMobileFrontend, 'beforePageRedirect' ); |
102 | 102 | $wgHooks['SkinTemplateOutputPageBeforeExec'][] = array( &$wgExtMobileFrontend, 'addMobileFooter' ); |
103 | 103 | $wgHooks['TestCanonicalRedirect'][] = array( &$wgExtMobileFrontend, 'testCanonicalRedirect' ); |
| 104 | + $wgHooks['ResourceLoaderTestModules'][] = array( &$wgExtMobileFrontend, 'addTestModules' ); |
104 | 105 | } |
105 | 106 | |
106 | 107 | /** |