Merge lp:~benji/juju-gui/bug-1104105-browser-compatability-warning-3 into lp:juju-gui/experimental
- bug-1104105-browser-compatability-warning-3
- Merge into trunk
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 377 | ||||
Proposed branch: | lp:~benji/juju-gui/bug-1104105-browser-compatability-warning-3 | ||||
Merge into: | lp:juju-gui/experimental | ||||
Diff against target: |
499 lines (+215/-53) 12 files modified
.bzrignore (+2/-0) Makefile (+33/-15) app/app.js (+1/-1) app/index.html (+85/-8) app/templates/login.handlebars (+3/-3) app/views/login.js (+4/-4) lib/merge-files.js (+4/-1) lib/views/stylesheet.less (+19/-18) test/index.html (+1/-0) test/test_login.js (+3/-3) test/test_startup.js.bottom (+50/-0) test/test_startup.js.top (+10/-0) |
||||
To merge this branch: | bzr merge lp:~benji/juju-gui/bug-1104105-browser-compatability-warning-3 | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Juju GUI Hackers | Pending | ||
Review via email: mp+147448@code.launchpad.net |
Commit message
Description of the change
Add a warning about unsupported browsers.
The tests for the code are a bit unusual in that the code under test is
embedded in an HTML file, so it must be extracted and the test file built my
the Makefile so it can be tested. I don't think this approach is too heinous.
- 383. By Benji York
-
merge trunk and resolve conflict
Brad Crittenden (bac) wrote : | # |
Gary Poster (gary) wrote : | # |
Hi Benji. Interesting test approach that is cool. Will think about it
more.
I raised the concern on IRC last week that make prod appears to be
broken. Here are some other review comments. I'll re-review when you
have these addressed and make prod fixed.
Thank you
Gary
https:/
File Makefile (right):
https:/
Makefile:523: server spritegen test test-debug test-prod undocumented \
test-prep too, yeah?
https:/
File app/index.html (right):
https:/
app/index.html:41: Your browser not fully supported.</span>
add an "is" in there please.
On IE 10 this is two lines, even without the is, which is a shame. It
would be nice if the panel were wider. I might mess with that.
https:/
app/index.html:50: <a href="http://
be fully
I think we ought to say Firefox here too. Maybe we wait for CI for
that. If so, please make a bug about this ("Firefox is not regularly
tested" with description mentioning that CI is fix for this bug, and
that this message should be updated when it is).
https:/
app/index.html:113: startTheApp = function() {
Unless someone corrects me, I'll assert that is a matter of good
practice to always use var declarations, even at the top level where
they technically are equivalent to what you have written here. Unless
someone argues against them, please add var statements here and below.
(see pastebin from next comment)
https:/
app/index.html:150: </script>
This ordering does not accomplish the workflow we want, described in the
graphic assets. The browser warning should be shown before we load the
JS. I think this is one approach to get what we want:
http://
ones.
https:/
File lib/views/
https:/
lib/views/
I'd like to see what this looks like expanded a bit. The goal would be
to have the text fit in a single line at the top, while still looking
good for login.
- 384. By Benji York
-
fix prod and tweak widths to reduce line breaks
- 385. By Benji York
-
review fixes
- 386. By Benji York
-
fix lint
- 387. By Benji York
-
fix lint
Gary Poster (gary) wrote : | # |
Land with changes, unless you argue against the changes.
Cool, thank you, and thanks for the source fix. Works well for me.
What was the make prod problem?
The box is still not wide enough for me on FF, but is fine on IE. could
you push ".centered-column div" and ".centered-column .panel
input[type=
.panel input" out to 270px, unless you disagree? I think the design
folks might want to tweak, but not breaking the header text across lines
is more important than the arguably less attractive proportions of the
wider box, IMO.
https:/
File app/index.html (right):
https:/
app/index.html:108: <script id="app-startup">
You could protect all of these functions in a function(
namespace hack to keep them out of the global namespace. startTheApp is
the only one that would need to be global.
https:/
app/index.html:109: isBrowserSupported = function(agent) {
Suggest "var isBrowserSupported = function(agent) {"
This is nicer for variable definition, and would work as desired within
the namespace hack I mention.
OTOH, if you don't use var, "function isBrowserSuppor
identical in semantics, at least as clear, and more concise.
https:/
app/index.html:114: getDocument = function() {
Same var discussion
https:/
app/index.html:118: displayBrowserW
Same var discussion
https:/
app/index.html:123: continueWithCur
Same var discussion
https:/
app/index.html:130: startTheApp = function() {
Same var discussion, except that it needs to be global as you've
implemented it here.
https:/
app/index.html:136: window.
Heh. Yeah, I considered this approach too. My global flag was grody in
my book, but so was this. I leaned toward the global flag, then, but
<shrug>.
https:/
app/index.html:139: go = function() {
Same var discussion
https:/
File lib/merge-files.js (right):
https:/
lib/merge-
sourceMapName;
Good catch. Seems silly that we have to do this.
Preview Diff
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2013-02-01 20:27:02 +0000 |
3 | +++ .bzrignore 2013-02-11 17:53:23 +0000 |
4 | @@ -20,3 +20,5 @@ |
5 | build-debug |
6 | bin/py |
7 | python-shelltoolbox |
8 | +test/test_startup.js |
9 | +test/extracted_startup_code |
10 | |
11 | === modified file 'Makefile' |
12 | --- Makefile 2013-02-08 17:46:45 +0000 |
13 | +++ Makefile 2013-02-11 17:53:23 +0000 |
14 | @@ -33,12 +33,13 @@ |
15 | -e '^server.js$$') |
16 | THIRD_PARTY_JS=app/assets/javascripts/reconnecting-websocket.js |
17 | NODE_TARGETS=node_modules/chai node_modules/cryptojs node_modules/d3 \ |
18 | - node_modules/expect.js node_modules/express node_modules/graceful-fs \ |
19 | - node_modules/grunt node_modules/jshint node_modules/less \ |
20 | - node_modules/minimatch node_modules/mocha node_modules/node-markdown \ |
21 | - node_modules/node-minify node_modules/node-spritesheet \ |
22 | - node_modules/rimraf node_modules/should node_modules/yui \ |
23 | - node_modules/yuidocjs node_modules/recess |
24 | + node_modules/expect.js node_modules/express \ |
25 | + node_modules/graceful-fs node_modules/grunt node_modules/jshint \ |
26 | + node_modules/less node_modules/minimatch node_modules/mocha \ |
27 | + node_modules/node-markdown node_modules/node-minify \ |
28 | + node_modules/node-spritesheet node_modules/recess \ |
29 | + node_modules/rimraf node_modules/should node_modules/uglify-js \ |
30 | + node_modules/yui node_modules/yuidocjs |
31 | EXPECTED_NODE_TARGETS=$(shell echo "$(NODE_TARGETS)" | tr ' ' '\n' | sort \ |
32 | | tr '\n' ' ') |
33 | |
34 | @@ -251,7 +252,7 @@ |
35 | # below without the grep to get recess' report. |
36 | node_modules/recess/bin/recess lib/views/stylesheet.less --config recess.json | grep -q Perfect |
37 | |
38 | -lint: gjslint jshint recess yuidoc-lint |
39 | +lint: test-prep gjslint jshint recess yuidoc-lint |
40 | |
41 | virtualenv/bin/python: |
42 | virtualenv virtualenv |
43 | @@ -271,7 +272,7 @@ |
44 | ln -sf "$(PWD)/node_modules/yui/assets/skins/sam/rail-x.png" \ |
45 | build-shared/juju-ui/assets/combined-css/rail-x.png |
46 | bin/merge-files |
47 | - mv *-source-map build-shared/juju-ui/assets/ |
48 | + mv *.js.map build-shared/juju-ui/assets/ |
49 | |
50 | build-files: $(BUILD_FILES) |
51 | |
52 | @@ -349,7 +350,7 @@ |
53 | $(LINK_PROD_FILES): |
54 | $(call link-files,prod) |
55 | ln -sf "$(PWD)/build-shared/juju-ui/assets/all-yui.js" build-prod/juju-ui/assets/ |
56 | - ln -sf "$(PWD)"/build-shared/juju-ui/assets/*-source-map build-prod/juju-ui/assets/ |
57 | + ln -sf "$(PWD)"/build-shared/juju-ui/assets/*.js.map build-prod/juju-ui/assets/ |
58 | # Link in the application source code so source maps work. |
59 | mkdir -p $(PWD)/build-prod/juju-ui/assets/source |
60 | ln -s $(PWD)/app $(PWD)/build-prod/juju-ui/assets/source |
61 | @@ -357,13 +358,30 @@ |
62 | |
63 | prep: beautify lint |
64 | |
65 | -test-debug: build-debug |
66 | +test/extracted_startup_code: app/index.html |
67 | + # Pull the JS out of the index so we can run tests against it. |
68 | + cat app/index.html | \ |
69 | + sed -n '/<script id="app-startup">/,/<\/script>/p'| \ |
70 | + head -n-1 | tail -n+2 > test/extracted_startup_code |
71 | + |
72 | +test/test_startup.js: test/test_startup.js.top test/test_startup.js.bottom \ |
73 | + test/extracted_startup_code |
74 | + # Stitch together the test file for app start-up. |
75 | + echo "// THIS IS A GENERATED FILE. DO NOT EDIT." > $@ |
76 | + echo "// See the Makefile for details." >> $@ |
77 | + cat test/test_startup.js.top >> $@ |
78 | + cat test/extracted_startup_code >> $@ |
79 | + cat test/test_startup.js.bottom >> $@ |
80 | + |
81 | +test-prep: test/test_startup.js |
82 | + |
83 | +test-debug: build-debug test-prep |
84 | ./test-server.sh debug |
85 | |
86 | -test-prod: build-prod |
87 | +test-prod: build-prod test-prep |
88 | ./test-server.sh prod |
89 | |
90 | -test-server: build-debug |
91 | +test-server: build-debug test-prep |
92 | ./test-server.sh debug true |
93 | |
94 | test-misc: |
95 | @@ -500,9 +518,9 @@ |
96 | |
97 | # targets are alphabetically sorted, they like it that way :-) |
98 | .PHONY: appcache-force appcache-touch beautify build build-files \ |
99 | - build-devel clean clean-all clean-deps clean-docs code-doc \ |
100 | - debug devel docs dist gjslint help jshint lint main-doc prep prod \ |
101 | - recess server spritegen test test-debug test-prod undocumented \ |
102 | + build-devel clean clean-all clean-deps clean-docs code-doc debug \ |
103 | + devel docs dist gjslint help jshint lint main-doc prep prod recess \ |
104 | + server spritegen test test-debug test-prep test-prod undocumented \ |
105 | view-code-doc view-docs view-main-doc yuidoc-lint |
106 | |
107 | .DEFAULT_GOAL := all |
108 | |
109 | === modified file 'app/app.js' |
110 | --- app/app.js 2013-02-08 17:36:58 +0000 |
111 | +++ app/app.js 2013-02-11 17:53:23 +0000 |
112 | @@ -638,7 +638,7 @@ |
113 | * @private |
114 | */ |
115 | onLogin: function() { |
116 | - Y.one('body > #login-mask').hide(); |
117 | + Y.one('body > #full-screen-mask').hide(); |
118 | this.dispatch(); |
119 | }, |
120 | |
121 | |
122 | === added file 'app/assets/images/alert_icon2.png' |
123 | Binary files app/assets/images/alert_icon2.png 1970-01-01 00:00:00 +0000 and app/assets/images/alert_icon2.png 2013-02-11 17:53:23 +0000 differ |
124 | === modified file 'app/index.html' |
125 | --- app/index.html 2013-02-07 21:04:01 +0000 |
126 | +++ app/index.html 2013-02-11 17:53:23 +0000 |
127 | @@ -30,7 +30,32 @@ |
128 | </head> |
129 | |
130 | <body> |
131 | - <div id="login-mask" class="crosshatch-background"></div> |
132 | + <div id="full-screen-mask" class="crosshatch-background"> |
133 | + <div id="browser-warning" class="centered-column" |
134 | + style="display:none;"> |
135 | + <i class="sprite juju_logo" title="Juju GUI"></i> |
136 | + <div class="panel"> |
137 | + <div class="header"> |
138 | + <div class="error"> |
139 | + <span><i class="sprite alert_icon2"></i> |
140 | + Your browser is not fully supported.</span> |
141 | + </div> |
142 | + </div> |
143 | + <p> |
144 | + If you continue to use Juju with your current browser your |
145 | + experience may not be as good as we would like it to be. |
146 | + </p> |
147 | + <p> |
148 | + Please use the latest version of |
149 | + <a href="http://www.google.com/chrome">Chrome</a> to be fully |
150 | + supported. |
151 | + </p> |
152 | + <form onsubmit="return continueWithCurrentBrowser();"> |
153 | + <input type="submit" value="Continue"/> |
154 | + </form> |
155 | + </div> |
156 | + </div> |
157 | + </div> |
158 | <div id="notifier-box"></div> |
159 | <div id="viewport-wrapper"> |
160 | <div id="vp-left-border"></div> |
161 | @@ -80,17 +105,69 @@ |
162 | </div> |
163 | <div id="vp-right-border"></div> |
164 | </div> |
165 | - <!-- javascript away --> |
166 | + <script id="app-startup"> |
167 | + isBrowserSupported = function(agent) { |
168 | + // At the moment, only Chrome is supported. |
169 | + return (/Chrome/.test(agent)); |
170 | + }; |
171 | + |
172 | + getDocument = function() { |
173 | + return document; |
174 | + }; |
175 | + |
176 | + displayBrowserWarning = function() { |
177 | + getDocument() |
178 | + .getElementById('browser-warning').style.display = 'block'; |
179 | + }; |
180 | + |
181 | + continueWithCurrentBrowser = function() { |
182 | + getDocument() |
183 | + .getElementById('browser-warning').style.display = 'none'; |
184 | + startTheApp(); |
185 | + return false; |
186 | + }; |
187 | + |
188 | + startTheApp = function() { |
189 | + // This function will be redefined when all the app's JavaScript is |
190 | + // loaded. We want to keep trying until that happens. |
191 | + |
192 | + // Tell jslint that we really do want to evaluate a string: |
193 | + /*jslint evil: true */ |
194 | + window.setTimeout('startTheApp', 100); |
195 | + }; |
196 | + |
197 | + go = function() { |
198 | + if (isBrowserSupported(navigator.userAgent)) { |
199 | + startTheApp(); |
200 | + } else { |
201 | + displayBrowserWarning(); |
202 | + } |
203 | + }; |
204 | + </script> |
205 | + <!-- |
206 | + Load the (potentially slow to download) core of the app. We do this here |
207 | + because we want the browser warning to execute before spending the time |
208 | + to download an app the user might not be able to use anyway. |
209 | + --> |
210 | <script src="/juju-ui/assets/all-yui.js"></script> |
211 | <script src="/juju-ui/assets/modules.js"></script> |
212 | <script src="/juju-ui/assets/config.js"></script> |
213 | <script> |
214 | - YUI(GlobalConfig).use(["juju-gui"], function(Y) { |
215 | - app = new Y.juju.App(juju_config); |
216 | - // We need to activate the hotkeys when running the application |
217 | - // in production. Unit tests should call it manually. |
218 | - app.activateHotkeys(); |
219 | - }); |
220 | + // Now that all of the above JS is loaded we can define the real start |
221 | + // function which will be picked up by the setTimeout and the app will |
222 | + // start. |
223 | + startTheApp = function() { |
224 | + YUI(GlobalConfig).use(['juju-gui'], function(Y) { |
225 | + app = new Y.juju.App(juju_config); |
226 | + // We need to activate the hotkeys when running the application |
227 | + // in production. Unit tests should call it manually. |
228 | + app.activateHotkeys(); |
229 | + }); |
230 | + }; |
231 | + // This call is here instead of in the "app-startup" script tag above |
232 | + // because we extract that JS in order to test it. This bit here is just |
233 | + // to bootstrap the app when actually loaded into a browser. |
234 | + go(); |
235 | </script> |
236 | </body> |
237 | </html> |
238 | |
239 | === modified file 'app/templates/login.handlebars' |
240 | --- app/templates/login.handlebars 2013-01-10 10:25:55 +0000 |
241 | +++ app/templates/login.handlebars 2013-02-11 17:53:23 +0000 |
242 | @@ -1,7 +1,7 @@ |
243 | -<div id="login-column"> |
244 | +<div class="centered-column"> |
245 | <i class="sprite juju_logo" title="Juju GUI"></i> |
246 | - <div id="login-form"> |
247 | - <div id="login-header"> |
248 | + <div id="login-form" class="panel"> |
249 | + <div class="header"> |
250 | {{environment_name}} <span class="provider-type">{{provider_type}}</span> |
251 | </div> |
252 | <form> |
253 | |
254 | === modified file 'app/views/login.js' |
255 | --- app/views/login.js 2013-02-08 17:36:58 +0000 |
256 | +++ app/views/login.js 2013-02-11 17:53:23 +0000 |
257 | @@ -56,12 +56,12 @@ |
258 | // In order to have the mask cover everything, it needs to be an |
259 | // immediate child of the body. In order for it to render immediately |
260 | // when the app loads, it needs to be in index.html. |
261 | - var loginMask = Y.one('body > #login-mask'); |
262 | - if (!loginMask) { |
263 | - // No login mask in the DOM, as is the case in tests. |
264 | + var mask = Y.one('body > #full-screen-mask'); |
265 | + if (!mask) { |
266 | + // No mask in the DOM, as is the case in tests. |
267 | return this; |
268 | } |
269 | - loginMask.show(); |
270 | + mask.show(); |
271 | var env = this.get('env'); |
272 | var environment_name_node = Y.one('#environment-name'); |
273 | var provider_type_node = Y.one('#provider-type'); |
274 | |
275 | === modified file 'lib/merge-files.js' |
276 | --- lib/merge-files.js 2013-02-06 17:37:02 +0000 |
277 | +++ lib/merge-files.js 2013-02-11 17:53:23 +0000 |
278 | @@ -32,7 +32,7 @@ |
279 | |
280 | // Combine one or more JavaScript files. |
281 | function combineJs(files, outputFile) { |
282 | - var sourceMapName = syspath.basename(outputFile, '.js') + '-source-map'; |
283 | + var sourceMapName = syspath.basename(outputFile) + '.map'; |
284 | // We feed the minifier relative path names so the source map will map to |
285 | // relative URLs that can be easily served. |
286 | var relative_files = []; |
287 | @@ -45,6 +45,9 @@ |
288 | outSourceMap: sourceMapName, |
289 | sourceRoot: 'source' |
290 | }); |
291 | + // The uglifyjs script does this instead of the library, so we have to do |
292 | + // it ourselves since we are using uglify as a library and not a script. |
293 | + result.code += '\n//@ sourceMappingURL=' + sourceMapName; |
294 | fs.writeFileSync(outputFile, result.code, 'utf8', throw_error); |
295 | fs.writeFileSync(sourceMapName, result.map, 'utf8', throw_error); |
296 | } |
297 | |
298 | === modified file 'lib/views/stylesheet.less' |
299 | --- lib/views/stylesheet.less 2013-02-07 19:04:00 +0000 |
300 | +++ lib/views/stylesheet.less 2013-02-11 17:53:23 +0000 |
301 | @@ -1414,7 +1414,7 @@ |
302 | } |
303 | } |
304 | |
305 | -#login-mask { |
306 | +#full-screen-mask { |
307 | display: block; |
308 | position: absolute; |
309 | top: 0; |
310 | @@ -1423,18 +1423,18 @@ |
311 | height: 100%; |
312 | z-index: 10000; |
313 | } |
314 | -#login-column { |
315 | +.centered-column { |
316 | display: block; |
317 | z-index: 10001; |
318 | position: absolute; |
319 | top: 80px; |
320 | left: 50%; |
321 | text-align: center; |
322 | - width: 300px; |
323 | - margin-left: -150px; |
324 | + width: 400px; |
325 | + margin-left: -200px; |
326 | |
327 | div { |
328 | - width: 220px; |
329 | + width: 260px; |
330 | text-align: left; |
331 | margin: 0 auto; |
332 | margin-bottom: 1ex; |
333 | @@ -1445,17 +1445,20 @@ |
334 | text-decoration: none |
335 | } |
336 | } |
337 | - @login-panel-color: #f5f5f5; |
338 | - @login-panel-gradient: (@login-panel-color - #111); |
339 | - @login-panel-shadow: (@login-panel-color - #444); |
340 | + |
341 | + @panel-color: #f5f5f5; |
342 | + @panel-gradient: (@panel-color - #111); |
343 | + @panel-shadow: (@panel-color - #444); |
344 | @curve-radius: ~"24px 28px"; |
345 | - div#login-form { |
346 | + |
347 | + .panel { |
348 | input { |
349 | + width: 250px; |
350 | margin-top: 8px; |
351 | margin-bottom: 8px; |
352 | } |
353 | input[type=submit] { |
354 | - width: 220px; |
355 | + width: 260px; |
356 | height: 26px; |
357 | text-transform: uppercase; |
358 | text-shadow: none; |
359 | @@ -1474,12 +1477,10 @@ |
360 | padding: 5px 25px 5px; |
361 | margin-top: 3ex; |
362 | margin-bottom: 4ex; |
363 | - .create-button(@login-panel-color, |
364 | - @login-panel-gradient, |
365 | - @login-panel-shadow, |
366 | - -6px); |
367 | - .create-border-radius(~"24px / 28px"); |
368 | - div#login-header { |
369 | + .create-button(@panel-color, @panel-gradient, @panel-shadow, -6px); |
370 | + .create-border-radius(@curve-radius); |
371 | + |
372 | + .header { |
373 | padding: 15px 25px 10px 25px; |
374 | margin-left: -25px; |
375 | margin-top: -5px; |
376 | @@ -1489,8 +1490,8 @@ |
377 | -moz-border-radius-topright: @curve-radius; |
378 | border-top-left-radius: @curve-radius; |
379 | border-top-right-radius: @curve-radius; |
380 | - @gradient-start: @login-panel-gradient; |
381 | - @gradient-end: @login-panel-shadow; |
382 | + @gradient-start: @panel-gradient; |
383 | + @gradient-end: @panel-shadow; |
384 | background-image: -ms-linear-gradient( |
385 | top, @gradient-start, @gradient-end); |
386 | background-image: -webkit-gradient( |
387 | |
388 | === modified file 'test/index.html' |
389 | --- test/index.html 2013-02-07 16:40:46 +0000 |
390 | +++ test/index.html 2013-02-11 17:53:23 +0000 |
391 | @@ -28,6 +28,7 @@ |
392 | |
393 | |
394 | <!-- Tests (Alphabetical)--> |
395 | + <script src="test_startup.js"></script> |
396 | <script src="test_app.js"></script> |
397 | <script src="test_app_hotkeys.js"></script> |
398 | <script src="test_application_notifications.js"></script> |
399 | |
400 | === modified file 'test/test_login.js' |
401 | --- test/test_login.js 2013-01-18 13:40:28 +0000 |
402 | +++ test/test_login.js 2013-02-11 17:53:23 +0000 |
403 | @@ -85,7 +85,7 @@ |
404 | |
405 | describe('login view', function() { |
406 | var requires = ['node', 'juju-gui', 'juju-views', 'juju-tests-utils']; |
407 | - var Y, conn, env, utils, juju, views, loginView, container, loginMask; |
408 | + var Y, conn, env, utils, juju, views, loginView, container, mask; |
409 | var test = it; // We aren't really doing BDD so let's be more direct. |
410 | |
411 | before(function(done) { |
412 | @@ -104,7 +104,7 @@ |
413 | conn.open(); |
414 | container = Y.one('body').appendChild('<div/>'); |
415 | // Needed by the render method. |
416 | - loginMask = Y.one('body').appendChild('<div/>').set('id', 'login-mask'); |
417 | + mask = Y.one('body').appendChild('<div/>').set('id', 'full-screen-mask'); |
418 | loginView = new views.login( |
419 | {container: container, env: env, help_text: 'Help text'}); |
420 | }); |
421 | @@ -112,7 +112,7 @@ |
422 | afterEach(function() { |
423 | env.destroy(); |
424 | container.remove(true); |
425 | - loginMask.remove(true); |
426 | + mask.remove(true); |
427 | }); |
428 | |
429 | test('the view login method logs in through the environment', function() { |
430 | |
431 | === added file 'test/test_startup.js.bottom' |
432 | --- test/test_startup.js.bottom 1970-01-01 00:00:00 +0000 |
433 | +++ test/test_startup.js.bottom 2013-02-11 17:53:23 +0000 |
434 | @@ -0,0 +1,50 @@ |
435 | + startTheApp = function() { |
436 | + appStarted = true; |
437 | + }; |
438 | + getDocument = function() { |
439 | + return { |
440 | + getElementById: function(id) { |
441 | + assert.equal(id, 'browser-warning'); |
442 | + return {style: warningStyle}; |
443 | + } |
444 | + }; |
445 | + }; |
446 | + }); |
447 | + |
448 | + it('knows that Chrome is supported', function() { |
449 | + assert.isTrue(isBrowserSupported('Chrome')); |
450 | + }); |
451 | + |
452 | + it('knows that Firefox is not supported', function() { |
453 | + assert.isFalse(isBrowserSupported('Firefox')); |
454 | + }); |
455 | + |
456 | + it('knows that IE is not supported', function() { |
457 | + assert.isFalse(isBrowserSupported('MSIE')); |
458 | + }); |
459 | + |
460 | + it('can display the browser warning', function() { |
461 | + displayBrowserWarning(); |
462 | + assert.equal(warningStyle.display, 'block'); |
463 | + }); |
464 | + |
465 | + it('will hide the browser warning when the user continues', function() { |
466 | + continueWithCurrentBrowser(); |
467 | + assert.equal(warningStyle.display, 'none'); |
468 | + }); |
469 | + |
470 | + it('will stop event propigation when the user continues', function() { |
471 | + var result = continueWithCurrentBrowser(); |
472 | + // Since the function is an event handler of a submit button and we do |
473 | + // not want the form submittion to actually happen, the handler must |
474 | + // return false. |
475 | + assert.isFalse(result); |
476 | + }); |
477 | + |
478 | + it('will start the app when the user continues', function() { |
479 | + continueWithCurrentBrowser(); |
480 | + assert.isTrue(appStarted); |
481 | + }); |
482 | + |
483 | + }); |
484 | +}) (); |
485 | |
486 | === added file 'test/test_startup.js.top' |
487 | --- test/test_startup.js.top 1970-01-01 00:00:00 +0000 |
488 | +++ test/test_startup.js.top 2013-02-11 17:53:23 +0000 |
489 | @@ -0,0 +1,10 @@ |
490 | +'use strict'; |
491 | + |
492 | +(function() { |
493 | + describe('Application start-up', function() { |
494 | + var startTheApp, isBrowserSupported, displayBrowserWarning, |
495 | + continueWithCurrentBrowser, go, app, juju_config, getDocument, |
496 | + appStarted, warningStyle; |
497 | + before(function() { |
498 | + warningStyle = {display: null}; |
499 | + appStarted = false; |
The branch looks good, thanks Benji. One change to make before landing.
https:/ /codereview. appspot. com/7299071/ diff/3001/ app/index. html
File app/index.html (right):
https:/ /codereview. appspot. com/7299071/ diff/3001/ app/index. html#newcode41
app/index.html:41: Your browser not fully supported.</span>
Please change to: Your browser is not fully supported.
https:/ /codereview. appspot. com/7299071/