~launchpad-pqm/launchpad/devel

12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
1
YUI({
2
    base: '../../../../canonical/launchpad/icing/yui/',
3
    filter: 'raw', combine: false, fetchCSS: false
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
4
    }).use('test', 'console', 'lazr.effects',
5
           'lp.bugs.bug_notification_level', 'node-event-simulate',
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
6
           function(Y) {
7
8
var suite = new Y.Test.Suite("lp.bugs.bug_notification_level Tests");
9
var module = Y.lp.bugs.bug_notification_level;
10
11
/**
12915.6.10 by Danilo Segan
Add tests for needs_toggling.
12
 * Test is_notification_level_shown() for a given set of
13
 * conditions.
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
14
 */
15
suite.add(new Y.Test.Case({
12915.6.23 by Danilo Segan
Narrative fixes.
16
    name: 'Is the selection of notification levels shown?',
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
17
18
    setUp: function () {
19
        this.MY_NAME = "ME";
20
        window.LP = { links: { me: "/~" + this.MY_NAME } };
21
    },
22
23
    tearDown: function() {
24
        delete window.LP;
25
    },
26
27
    test_subscribe_me: function() {
28
        // Person wants to subscribe so levels are shown:
12915.6.23 by Danilo Segan
Narrative fixes.
29
        // the selected radio button has a value of the username,
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
30
        // and there is no option to update a subscription.
31
        Y.Assert.isTrue(
32
            module._is_notification_level_shown(this.MY_NAME, false));
33
    },
34
35
    test_unsubscribe_someone_else: function() {
36
        // Not subscribed (thus no option to update a subscription)
37
        // and wants to unsubscribe a team: levels are not shown.
38
        Y.Assert.isFalse(
39
            module._is_notification_level_shown('TEAM', false));
40
    },
41
42
    test_edit_subscription_me: function() {
43
        // There is either an existing subscription, or bug mail
44
        // is muted, so one can 'update existing subscription'.
45
        // If unmute/unsubscribe options are chosen, no level
46
        // options are shown.
47
        Y.Assert.isFalse(
48
            module._is_notification_level_shown(this.MY_NAME, true));
49
    },
50
51
    test_edit_subscription_update: function() {
52
        // There is either an existing subscription, or bug mail
53
        // is muted, so one can 'update existing subscription'.
54
        // If 'update-subscription' option is chosen, level
55
        // options are shown.
56
        Y.Assert.isTrue(
57
            module._is_notification_level_shown('update-subscription', true));
58
    },
59
60
    test_edit_subscription_someone_else: function() {
61
        // There is either an existing subscription, or bug mail
62
        // is muted, so one can 'update existing subscription'.
63
        // If unsubscribe a team option is chosen, no level
64
        // options are shown.
65
        Y.Assert.isFalse(
66
            module._is_notification_level_shown('TEAM', true));
67
    }
68
69
}));
70
71
12915.6.10 by Danilo Segan
Add tests for needs_toggling.
72
/**
73
 * Test needs_toggling() which compares two sets of conditions and
74
 * returns if the need for notification level has changed.
75
 */
76
suite.add(new Y.Test.Case({
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
77
    name: 'State of the notification level visibility should change',
12915.6.10 by Danilo Segan
Add tests for needs_toggling.
78
79
    setUp: function () {
80
        this.MY_NAME = "ME";
81
        window.LP = { links: { me: "/~" + this.MY_NAME } };
82
    },
83
84
    tearDown: function() {
85
        delete window.LP;
86
    },
87
88
    test_no_change: function() {
89
        // Both current_value and new_value are identical.
90
        Y.Assert.isFalse(
91
            module._needs_toggling('value', 'value', false));
92
        Y.Assert.isFalse(
93
            module._needs_toggling('value', 'value', true));
94
    },
95
96
    test_unsubscribe_to_team: function() {
97
        // Changing the option from 'unsubscribe me' (no levels shown)
98
        // to 'unsubscribe team' (no levels shown) means no change.
99
        Y.Assert.isFalse(
100
            module._needs_toggling(this.MY_NAME, 'TEAM', true));
101
    },
102
103
    test_edit_subscription_to_team: function() {
104
        // Changing the option from 'update-subscription' (levels shown)
105
        // to 'unsubscribe team' (no levels shown) means a change.
106
        Y.Assert.isTrue(
107
            module._needs_toggling('update-subscription', 'TEAM', true));
108
    }
109
110
}));
111
112
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
113
/**
114
 * Test toggle_field_visibility() which shows/hides a node based on
115
 * the value of bug_notification_level_visible value.
116
 */
117
suite.add(new Y.Test.Case({
118
    name: 'Toggle visibility of the notification levels with animations',
119
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
120
    setUp: function() {
121
        // Monkey patch effects duration to make effects instant.
122
        // This keeps wait times to a minimum.
123
        this.original_defaults = Y.lazr.effects.slide_effect_defaults;
124
        Y.lazr.effects.slide_effect_defaults.duration = 0;
125
    },
126
12915.6.23 by Danilo Segan
Narrative fixes.
127
    tearDown: function() {
128
        // Restore the default value.
129
        module._bug_notification_level_visible = true;
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
130
        Y.lazr.effects.slide_effect_defaults = this.original_defaults;
12915.6.23 by Danilo Segan
Narrative fixes.
131
    },
132
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
133
    test_quick_close: function() {
134
        // When quick_close===true, no animation happens and the
135
        // node is hidden.
12915.6.13 by Danilo Segan
Add tests for initialize() method.
136
        var node = Y.Node.create('<div></div>');
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
137
        module._toggle_field_visibility(node, true);
138
        Y.Assert.isTrue(node.hasClass('lazr-closed'));
12915.6.22 by Danilo Segan
Do not use display:none which causes jumping text.
139
        Y.Assert.areEqual('0px', node.getStyle('height'));
140
        Y.Assert.areEqual('hidden', node.getStyle('overflow'));
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
141
        Y.Assert.isFalse(module._bug_notification_level_visible);
142
    },
143
144
    test_hide_node: function() {
145
        // Initially a node is shown, so 'toggling' makes it hidden.
12915.6.13 by Danilo Segan
Add tests for initialize() method.
146
        var node = Y.Node.create('<div></div>');
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
147
        module._toggle_field_visibility(node);
148
        this.wait(function() {
149
            // Wait for the animation to complete.
150
            Y.Assert.isTrue(node.hasClass('lazr-closed'));
151
            Y.Assert.isFalse(module._bug_notification_level_visible);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
152
        }, 20);
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
153
    },
154
155
    test_show_node: function() {
156
        // When the node is closed, toggling shows it.
157
        module._bug_notification_level_visible = false;
12915.6.13 by Danilo Segan
Add tests for initialize() method.
158
        var node = Y.Node.create('<div></div>');
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
159
        module._toggle_field_visibility(node);
160
        this.wait(function() {
161
            // Wait for the animation to complete.
162
            Y.Assert.isTrue(node.hasClass('lazr-opened'));
163
            Y.Assert.isTrue(module._bug_notification_level_visible);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
164
        }, 20);
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
165
    },
166
167
    test_show_and_hide: function() {
168
        // Showing and then quickly hiding the node stops the
169
        // slide out animation for nicer rendering.
170
        module._bug_notification_level_visible = false;
12915.6.13 by Danilo Segan
Add tests for initialize() method.
171
        var node = Y.Node.create('<div></div>');
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
172
        // This triggers the 'slide-out' animation.
173
        module._toggle_field_visibility(node);
174
        // Now we wait 100ms (<400ms for the animation) and
175
        // trigger the 'slide-in' animation.
176
        this.wait(function() {
177
            module._toggle_field_visibility(node);
178
            // The slide-out animation should be stopped now.
179
            Y.Assert.isFalse(module._slideout_animation.get('running'));
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
180
        }, 20);
12915.6.13 by Danilo Segan
Add tests for initialize() method.
181
    }
182
183
}));
184
185
186
/**
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
187
 * Helper for creating radio buttons for different actions
188
 * in an advanced subscription overlay.
189
 */
190
function createRadioButton(value, checked) {
191
    if (checked === undefined) {
192
        checked = false;
193
    }
194
    return Y.Node.create('<input type="radio"></input>')
195
        .set('name', 'field.subscription')
196
        .set('value', value)
197
        .set('checked', checked);
198
}
199
200
201
/**
12915.6.13 by Danilo Segan
Add tests for initialize() method.
202
 * Test initialize() which sets up the initial state as appropriate.
203
 */
204
suite.add(new Y.Test.Case({
205
    name: 'Test initial set-up of the level options display.',
206
207
    setUp: function () {
208
        this.MY_NAME = "ME";
209
        window.LP = { links: { me: "/~" + this.MY_NAME } };
210
    },
211
212
    tearDown: function() {
213
        delete window.LP;
214
    },
215
216
    test_bug_notification_level_default: function() {
217
        // `bug_notification_level_visible` is always restored to true.
218
        var level_node = Y.Node.create('<div></div>');
219
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
220
        node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
221
        var radio_buttons = node.all('input[name=field.subscription]');
222
223
        module._bug_notification_level_visible = false;
224
        var state = module._initialize(radio_buttons, level_node);
225
        Y.Assert.isTrue(module._bug_notification_level_visible);
226
    },
227
228
    test_value_undefined: function() {
13158.4.25 by Curtis Hovey
Removed duplicate test reported by lint.
229
        // When there is no selected radio button, the returned value
230
        // is undefined.
12915.6.13 by Danilo Segan
Add tests for initialize() method.
231
        var level_node = Y.Node.create('<div></div>');
232
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
233
        node.appendChild(createRadioButton(this.MY_NAME));
234
        node.appendChild(createRadioButton('TEAM'));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
235
        var radio_buttons = node.all('input[name=field.subscription]');
236
237
        var state = module._initialize(radio_buttons, level_node);
238
        Y.Assert.isUndefined(state.value);
239
    },
240
241
    test_value_selected: function() {
12915.6.23 by Danilo Segan
Narrative fixes.
242
        // When there is a selected radio button, returned value matches
243
        // the value from that radio button.
12915.6.13 by Danilo Segan
Add tests for initialize() method.
244
        var level_node = Y.Node.create('<div></div>');
245
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
246
        node.appendChild(createRadioButton('VALUE', true));
247
        node.appendChild(createRadioButton('TEAM'));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
248
        var radio_buttons = node.all('input[name=field.subscription]');
249
250
        var state = module._initialize(radio_buttons, level_node);
251
        Y.Assert.areEqual('VALUE', state.value);
252
    },
253
254
    test_has_update_subscription_button_false: function() {
12915.6.23 by Danilo Segan
Narrative fixes.
255
        // When there is no radio button with value 'update-subscription',
12915.6.13 by Danilo Segan
Add tests for initialize() method.
256
        // returned state indicates that.
257
        var level_node = Y.Node.create('<div></div>');
258
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
259
        node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
260
        var radio_buttons = node.all('input[name=field.subscription]');
261
        var state = module._initialize(radio_buttons, level_node);
262
        Y.Assert.isFalse(state.has_update_subscription_button);
263
    },
264
265
    test_has_update_subscription_button_true: function() {
12915.6.23 by Danilo Segan
Narrative fixes.
266
        // When there is a radio button with value 'update-subscription',
12915.6.13 by Danilo Segan
Add tests for initialize() method.
267
        // returned state indicates that.
268
        var level_node = Y.Node.create('<div></div>');
269
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
270
        node.appendChild(createRadioButton('update-subscription', true));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
271
        var radio_buttons = node.all('input[name=field.subscription]');
272
        var state = module._initialize(radio_buttons, level_node);
273
        Y.Assert.isTrue(state.has_update_subscription_button);
274
    },
275
276
    test_no_toggling_for_visible: function() {
277
        // No toggling happens when options should be shown
278
        // since that's the default.
279
        var level_node = Y.Node.create('<div></div>');
280
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
281
        node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
282
        var radio_buttons = node.all('input[name=field.subscription]');
283
        module._initialize(radio_buttons, level_node);
284
        Y.Assert.isFalse(level_node.hasClass('lazr-opened'));
285
        Y.Assert.isFalse(level_node.hasClass('lazr-closed'));
286
    },
287
288
    test_toggling_for_hiding: function() {
289
        // Quick toggling happens when options should be hidden.
290
        var level_node = Y.Node.create('<div></div>');
291
        var node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
292
        node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
293
        node.appendChild(
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
294
            createRadioButton('update-subscription', false));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
295
        var radio_buttons = node.all('input[name=field.subscription]');
296
        module._initialize(radio_buttons, level_node);
12915.6.22 by Danilo Segan
Do not use display:none which causes jumping text.
297
        Y.Assert.areEqual('0px', level_node.getStyle('height'));
12915.6.13 by Danilo Segan
Add tests for initialize() method.
298
        Y.Assert.isTrue(level_node.hasClass('lazr-closed'));
299
    }
12915.6.11 by Danilo Segan
Add tests for toggle_field_visibility.
300
301
}));
302
303
12915.6.14 by Danilo Segan
Add tests for setup().
304
/**
305
 * Test setup() of level options display toggling.
306
 */
307
suite.add(new Y.Test.Case({
308
    name: 'Test initial set-up of the level options display.',
309
310
    _should: {
311
        error: {
312
            test_multiple_nodes_with_level_options: new Error(
313
                'There are multiple bug-notification-level-field nodes.')
314
        }
315
    },
316
317
    setUp: function () {
318
        this.MY_NAME = "ME";
319
        window.LP = { links: { me: "/~" + this.MY_NAME } };
320
        this.root = Y.one('body').appendChild(
321
            Y.Node.create('<div></div>'));
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
322
        // Monkey patch effects duration to make effects instant.
323
        // This keeps wait times to a minimum.
324
        this.original_defaults = Y.lazr.effects.slide_effect_defaults;
325
        Y.lazr.effects.slide_effect_defaults.duration = 0;
12915.6.14 by Danilo Segan
Add tests for setup().
326
    },
327
328
    tearDown: function() {
329
        delete window.LP;
330
        this.root.empty();
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
331
        Y.lazr.effects.slide_effect_defaults = this.original_defaults;
12915.6.14 by Danilo Segan
Add tests for setup().
332
    },
333
334
    test_multiple_nodes_with_level_options: function() {
335
        // Multiple nodes with bug notification level options
336
        // make the set-up fail.
337
        this.root.appendChild(
338
            Y.Node.create('<div></div>')
339
                .addClass('bug-notification-level-field'));
340
        this.root.appendChild(
341
            Y.Node.create('<div></div>')
342
                .addClass('bug-notification-level-field'));
343
        module.setup();
344
    },
345
346
    test_no_level_options: function() {
347
        // When there are no level options, no animation is set-up.
348
        var options_node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
349
        options_node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.14 by Danilo Segan
Add tests for setup().
350
12915.6.21 by Danilo Segan
Move event to setup().
351
        var event_fired = false;
352
        Y.on('bugnotificationlevel:contentready', function () {
353
            event_fired = true;
354
        });
355
356
        this.root.appendChild(options_node);
357
        Y.Assert.isFalse(module.setup());
358
359
        // Event is fired regardless.
360
        this.wait(function() {
361
            Y.Assert.isTrue(event_fired);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
362
        }, 5);
12915.6.21 by Danilo Segan
Move event to setup().
363
    },
364
12915.6.14 by Danilo Segan
Add tests for setup().
365
    test_single_option_no_animation: function() {
366
        // When there is only a single option, no animation is set-up.
367
        var level_node = Y.Node.create('<div></div>')
368
            .addClass('bug-notification-level-field');
369
        var options_node = Y.Node.create('<div></div>');
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
370
        options_node.appendChild(createRadioButton(this.MY_NAME, true));
12915.6.14 by Danilo Segan
Add tests for setup().
371
372
        this.root.appendChild(options_node);
373
        this.root.appendChild(level_node);
12915.6.21 by Danilo Segan
Move event to setup().
374
375
        var event_fired = false;
376
        Y.on('bugnotificationlevel:contentready', function () {
377
            event_fired = true;
378
        });
379
12915.6.14 by Danilo Segan
Add tests for setup().
380
        Y.Assert.isFalse(module.setup());
12915.6.21 by Danilo Segan
Move event to setup().
381
382
        // Event is fired regardless.
383
        this.wait(function() {
384
            Y.Assert.isTrue(event_fired);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
385
        }, 5);
12915.6.14 by Danilo Segan
Add tests for setup().
386
    },
387
388
    test_animation_set_up: function() {
389
        // With multiple options (eg. "subscribe me", "unsubscribe team")
390
        // toggling of visibility (with animation) is set-up for all items.
391
        var level_node = Y.Node.create('<div></div>')
392
            .addClass('bug-notification-level-field');
393
12915.6.20 by Danilo Segan
Emit bugnotificationlevel:contentready event from initialize() and show the overlay on it. Remove duplicate copy of createRadioButton() method in tests and make it a function instead.
394
        var subscribe_me = createRadioButton(this.MY_NAME, true);
395
        var unsubscribe_team = createRadioButton('TEAM', false);
12915.6.14 by Danilo Segan
Add tests for setup().
396
397
        var options_node = Y.Node.create('<div></div>');
398
        options_node.appendChild(subscribe_me);
399
        options_node.appendChild(unsubscribe_team);
400
401
        this.root.appendChild(options_node);
402
        this.root.appendChild(level_node);
403
12915.6.21 by Danilo Segan
Move event to setup().
404
        var event_fired = false;
405
        Y.on('bugnotificationlevel:contentready', function () {
406
            event_fired = true;
407
        });
408
12915.6.14 by Danilo Segan
Add tests for setup().
409
        // Set-up is successful.
410
        Y.Assert.isTrue(module.setup());
411
12915.6.21 by Danilo Segan
Move event to setup().
412
        // And event is fired when the form set-up has been completed.
413
        this.wait(function() {
414
            Y.Assert.isTrue(event_fired);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
415
        }, 5);
12915.6.21 by Danilo Segan
Move event to setup().
416
12915.6.14 by Danilo Segan
Add tests for setup().
417
        // Clicking the second option hides the initially shown
418
        // notification level options.
419
        unsubscribe_team.simulate('click');
420
        this.wait(function() {
421
            Y.Assert.isTrue(level_node.hasClass('lazr-closed'));
422
            Y.Assert.isFalse(level_node.hasClass('lazr-opened'));
423
            Y.Assert.isFalse(module._bug_notification_level_visible);
424
            // Clicking it again does nothing.
425
            unsubscribe_team.simulate('click');
426
            Y.Assert.isFalse(module._bug_notification_level_visible);
427
428
            // Clicking the other option slides the options out again.
429
            subscribe_me.simulate('click');
430
            this.wait(function() {
431
                Y.Assert.isTrue(level_node.hasClass('lazr-opened'));
432
                Y.Assert.isFalse(level_node.hasClass('lazr-closed'));
433
                Y.Assert.isTrue(module._bug_notification_level_visible);
13241.1.6 by Deryck Hodge
Make test_bug_notification_level faster, with the same kind of effects anim monkey patching.
434
            }, 20);
435
        }, 20);
12915.6.14 by Danilo Segan
Add tests for setup().
436
    }
437
438
}));
439
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
440
var handle_complete = function(data) {
13158.4.10 by Curtis Hovey
Return a yui test results as json.
441
    window.status = '::::' + JSON.stringify(data);
12915.6.9 by Danilo Segan
Add tests for is_notification_level_shown.
442
    };
443
Y.Test.Runner.on('complete', handle_complete);
444
Y.Test.Runner.add(suite);
445
446
var console = new Y.Console({newestOnTop: false});
447
console.render('#log');
448
449
Y.on('domready', function() {
450
    Y.Test.Runner.run();
451
});
452
});