2 // These tests expect the DOM to contain a presentation
3 // with the following slide structure:
6 // 2 - Three sub-slides
7 // 3 - Three fragment elements
8 // 3 - Two fragments with same data-fragment-index
12 Reveal
.addEventListener( 'ready', function() {
14 // ---------------------------------------------------------------
17 QUnit
.module( 'DOM' );
19 test( 'Initial slides classes', function() {
20 var horizontalSlides
= document
.querySelectorAll( '.reveal .slides>section' )
22 strictEqual( document
.querySelectorAll( '.reveal .slides section.past' ).length
, 0, 'no .past slides' );
23 strictEqual( document
.querySelectorAll( '.reveal .slides section.present' ).length
, 1, 'one .present slide' );
24 strictEqual( document
.querySelectorAll( '.reveal .slides>section.future' ).length
, horizontalSlides
.length
- 1, 'remaining horizontal slides are .future' );
26 strictEqual( document
.querySelectorAll( '.reveal .slides section.stack' ).length
, 2, 'two .stacks' );
28 ok( document
.querySelectorAll( '.reveal .slides section.stack' )[0].querySelectorAll( '.future' ).length
> 0, 'vertical slides are given .future' );
31 // ---------------------------------------------------------------
34 QUnit
.module( 'API' );
36 test( 'Reveal.isReady', function() {
37 strictEqual( Reveal
.isReady(), true, 'returns true' );
40 test( 'Reveal.isOverview', function() {
41 strictEqual( Reveal
.isOverview(), false, 'false by default' );
43 Reveal
.toggleOverview();
44 strictEqual( Reveal
.isOverview(), true, 'true after toggling on' );
46 Reveal
.toggleOverview();
47 strictEqual( Reveal
.isOverview(), false, 'false after toggling off' );
50 test( 'Reveal.isPaused', function() {
51 strictEqual( Reveal
.isPaused(), false, 'false by default' );
54 strictEqual( Reveal
.isPaused(), true, 'true after pausing' );
57 strictEqual( Reveal
.isPaused(), false, 'false after resuming' );
60 test( 'Reveal.isFirstSlide', function() {
62 strictEqual( Reveal
.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
65 strictEqual( Reveal
.isFirstSlide(), false, 'false after Reveal.slide( 1, 0 )' );
68 strictEqual( Reveal
.isFirstSlide(), true, 'true after Reveal.slide( 0, 0 )' );
71 test( 'Reveal.isFirstSlide after vertical slide', function() {
74 strictEqual( Reveal
.isFirstSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( 0, 0 )' );
77 test( 'Reveal.isLastSlide', function() {
79 strictEqual( Reveal
.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
81 var lastSlideIndex
= document
.querySelectorAll( '.reveal .slides>section' ).length
- 1;
83 Reveal
.slide( lastSlideIndex
, 0 );
84 strictEqual( Reveal
.isLastSlide(), true, 'true after Reveal.slide( '+ lastSlideIndex
+', 0 )' );
87 strictEqual( Reveal
.isLastSlide(), false, 'false after Reveal.slide( 0, 0 )' );
90 test( 'Reveal.isLastSlide after vertical slide', function() {
91 var lastSlideIndex
= document
.querySelectorAll( '.reveal .slides>section' ).length
- 1;
94 Reveal
.slide( lastSlideIndex
);
95 strictEqual( Reveal
.isLastSlide(), true, 'true after Reveal.slide( 1, 1 ) and then Reveal.slide( '+ lastSlideIndex
+', 0 )' );
98 test( 'Reveal.getTotalSlides', function() {
99 strictEqual( Reveal
.getTotalSlides(), 8, 'eight slides in total' );
102 test( 'Reveal.getIndices', function() {
103 var indices
= Reveal
.getIndices();
105 ok( indices
.hasOwnProperty( 'h' ), 'h exists' );
106 ok( indices
.hasOwnProperty( 'v' ), 'v exists' );
107 ok( indices
.hasOwnProperty( 'f' ), 'f exists' );
109 Reveal
.slide( 1, 0 );
110 strictEqual( Reveal
.getIndices().h
, 1, 'h 1' );
111 strictEqual( Reveal
.getIndices().v
, 0, 'v 0' );
113 Reveal
.slide( 1, 2 );
114 strictEqual( Reveal
.getIndices().h
, 1, 'h 1' );
115 strictEqual( Reveal
.getIndices().v
, 2, 'v 2' );
117 Reveal
.slide( 0, 0 );
118 strictEqual( Reveal
.getIndices().h
, 0, 'h 0' );
119 strictEqual( Reveal
.getIndices().v
, 0, 'v 0' );
122 test( 'Reveal.getSlide', function() {
123 equal( Reveal
.getSlide( 0 ), document
.querySelector( '.reveal .slides>section:first-child' ), 'gets correct first slide' );
124 equal( Reveal
.getSlide( 1 ), document
.querySelector( '.reveal .slides>section:nth-child(2)' ), 'no v index returns stack' );
125 equal( Reveal
.getSlide( 1, 0 ), document
.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(1)' ), 'v index 0 returns first vertical child' );
126 equal( Reveal
.getSlide( 1, 1 ), document
.querySelector( '.reveal .slides>section:nth-child(2)>section:nth-child(2)' ), 'v index 1 returns second vertical child' );
128 strictEqual( Reveal
.getSlide( 100 ), undefined, 'undefined when out of horizontal bounds' );
129 strictEqual( Reveal
.getSlide( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
132 test( 'Reveal.getSlideBackground', function() {
133 equal( Reveal
.getSlideBackground( 0 ), document
.querySelector( '.reveal .backgrounds>.slide-background:first-child' ), 'gets correct first background' );
134 equal( Reveal
.getSlideBackground( 1 ), document
.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2)' ), 'no v index returns stack' );
135 equal( Reveal
.getSlideBackground( 1, 0 ), document
.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(1)' ), 'v index 0 returns first vertical child' );
136 equal( Reveal
.getSlideBackground( 1, 1 ), document
.querySelector( '.reveal .backgrounds>.slide-background:nth-child(2) .slide-background:nth-child(2)' ), 'v index 1 returns second vertical child' );
138 strictEqual( Reveal
.getSlideBackground( 100 ), undefined, 'undefined when out of horizontal bounds' );
139 strictEqual( Reveal
.getSlideBackground( 1, 100 ), undefined, 'undefined when out of vertical bounds' );
142 test( 'Reveal.getSlideNotes', function() {
143 Reveal
.slide( 0, 0 );
144 ok( Reveal
.getSlideNotes() === 'speaker notes 1', 'works with <aside class="notes">' );
146 Reveal
.slide( 1, 0 );
147 ok( Reveal
.getSlideNotes() === 'speaker notes 2', 'works with <section data-notes="">' );
150 test( 'Reveal.getPreviousSlide/getCurrentSlide', function() {
151 Reveal
.slide( 0, 0 );
152 Reveal
.slide( 1, 0 );
154 var firstSlide
= document
.querySelector( '.reveal .slides>section:first-child' );
155 var secondSlide
= document
.querySelector( '.reveal .slides>section:nth-child(2)>section' );
157 equal( Reveal
.getPreviousSlide(), firstSlide
, 'previous is slide #0' );
158 equal( Reveal
.getCurrentSlide(), secondSlide
, 'current is slide #1' );
161 test( 'Reveal.getProgress', function() {
162 Reveal
.slide( 0, 0 );
163 strictEqual( Reveal
.getProgress(), 0, 'progress is 0 on first slide' );
165 var lastSlideIndex
= document
.querySelectorAll( '.reveal .slides>section' ).length
- 1;
167 Reveal
.slide( lastSlideIndex
, 0 );
168 strictEqual( Reveal
.getProgress(), 1, 'progress is 1 on last slide' );
171 test( 'Reveal.getScale', function() {
172 ok( typeof Reveal
.getScale() === 'number', 'has scale' );
175 test( 'Reveal.getConfig', function() {
176 ok( typeof Reveal
.getConfig() === 'object', 'has config' );
179 test( 'Reveal.configure', function() {
180 strictEqual( Reveal
.getConfig().loop
, false, '"loop" is false to start with' );
182 Reveal
.configure({ loop
: true });
183 strictEqual( Reveal
.getConfig().loop
, true, '"loop" has changed to true' );
185 Reveal
.configure({ loop
: false, customTestValue
: 1 });
186 strictEqual( Reveal
.getConfig().customTestValue
, 1, 'supports custom values' );
189 test( 'Reveal.availableRoutes', function() {
190 Reveal
.slide( 0, 0 );
191 deepEqual( Reveal
.availableRoutes(), { left
: false, up
: false, down
: false, right
: true }, 'correct for first slide' );
193 Reveal
.slide( 1, 0 );
194 deepEqual( Reveal
.availableRoutes(), { left
: true, up
: false, down
: true, right
: true }, 'correct for vertical slide' );
197 test( 'Reveal.next', function() {
198 Reveal
.slide( 0, 0 );
200 // Step through vertical child slides
202 deepEqual( Reveal
.getIndices(), { h
: 1, v
: 0, f
: undefined } );
205 deepEqual( Reveal
.getIndices(), { h
: 1, v
: 1, f
: undefined } );
208 deepEqual( Reveal
.getIndices(), { h
: 1, v
: 2, f
: undefined } );
210 // Step through fragments
212 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: -1 } );
215 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 0 } );
218 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 1 } );
221 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 2 } );
224 test( 'Reveal.next at end', function() {
227 // We're at the end, this should have no effect
229 deepEqual( Reveal
.getIndices(), { h
: 3, v
: 0, f
: undefined } );
232 deepEqual( Reveal
.getIndices(), { h
: 3, v
: 0, f
: undefined } );
236 // ---------------------------------------------------------------
239 QUnit
.module( 'Fragments' );
241 test( 'Sliding to fragments', function() {
242 Reveal
.slide( 2, 0, -1 );
243 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: -1 }, 'Reveal.slide( 2, 0, -1 )' );
245 Reveal
.slide( 2, 0, 0 );
246 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 0 }, 'Reveal.slide( 2, 0, 0 )' );
248 Reveal
.slide( 2, 0, 2 );
249 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 2 }, 'Reveal.slide( 2, 0, 2 )' );
251 Reveal
.slide( 2, 0, 1 );
252 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 1 }, 'Reveal.slide( 2, 0, 1 )' );
255 test( 'Hiding all fragments', function() {
256 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(1)' );
258 Reveal
.slide( 2, 0, 0 );
259 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.visible' ).length
, 1, 'one fragment visible when index is 0' );
261 Reveal
.slide( 2, 0, -1 );
262 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.visible' ).length
, 0, 'no fragments visible when index is -1' );
265 test( 'Current fragment', function() {
266 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(1)' );
268 Reveal
.slide( 2, 0 );
269 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.current-fragment' ).length
, 0, 'no current fragment at index -1' );
271 Reveal
.slide( 2, 0, 0 );
272 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.current-fragment' ).length
, 1, 'one current fragment at index 0' );
274 Reveal
.slide( 1, 0, 0 );
275 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.current-fragment' ).length
, 0, 'no current fragment when navigating to previous slide' );
277 Reveal
.slide( 3, 0, 0 );
278 strictEqual( fragmentSlide
.querySelectorAll( '.fragment.current-fragment' ).length
, 0, 'no current fragment when navigating to next slide' );
281 test( 'Stepping through fragments', function() {
282 Reveal
.slide( 2, 0, -1 );
287 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 0 }, 'next() goes to next fragment' );
290 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 1 }, 'right() goes to next fragment' );
293 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 2 }, 'down() goes to next fragment' );
295 Reveal
.down(); // moves to f #3
300 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 2 }, 'prev() goes to prev fragment' );
303 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 1 }, 'left() goes to prev fragment' );
306 deepEqual( Reveal
.getIndices(), { h
: 2, v
: 0, f
: 0 }, 'up() goes to prev fragment' );
309 test( 'Stepping past fragments', function() {
310 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(1)' );
312 Reveal
.slide( 0, 0, 0 );
313 equal( fragmentSlide
.querySelectorAll( '.fragment.visible' ).length
, 0, 'no fragments visible when on previous slide' );
315 Reveal
.slide( 3, 0, 0 );
316 equal( fragmentSlide
.querySelectorAll( '.fragment.visible' ).length
, 3, 'all fragments visible when on future slide' );
319 test( 'Fragment indices', function() {
320 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(2)' );
322 Reveal
.slide( 3, 0, 0 );
323 equal( fragmentSlide
.querySelectorAll( '.fragment.visible' ).length
, 2, 'both fragments of same index are shown' );
325 // This slide has three fragments, first one is index 0, second and third have index 1
326 Reveal
.slide( 2, 2, 0 );
327 equal( Reveal
.getIndices().f
, 0, 'returns correct index for first fragment' );
329 Reveal
.slide( 2, 2, 1 );
330 equal( Reveal
.getIndices().f
, 1, 'returns correct index for two fragments with same index' );
333 test( 'Index generation', function() {
334 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(1)' );
336 // These have no indices defined to start with
337 equal( fragmentSlide
.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
338 equal( fragmentSlide
.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
339 equal( fragmentSlide
.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '2' );
342 test( 'Index normalization', function() {
343 var fragmentSlide
= document
.querySelector( '#fragment-slides>section:nth-child(3)' );
345 // These start out as 1-4-4 and should normalize to 0-1-1
346 equal( fragmentSlide
.querySelectorAll( '.fragment' )[0].getAttribute( 'data-fragment-index' ), '0' );
347 equal( fragmentSlide
.querySelectorAll( '.fragment' )[1].getAttribute( 'data-fragment-index' ), '1' );
348 equal( fragmentSlide
.querySelectorAll( '.fragment' )[2].getAttribute( 'data-fragment-index' ), '1' );
351 asyncTest( 'fragmentshown event', function() {
354 var _onEvent = function( event
) {
355 ok( true, 'event fired' );
358 Reveal
.addEventListener( 'fragmentshown', _onEvent
);
360 Reveal
.slide( 2, 0 );
361 Reveal
.slide( 2, 0 ); // should do nothing
362 Reveal
.slide( 2, 0, 0 ); // should do nothing
365 Reveal
.prev(); // shouldn't fire fragmentshown
369 Reveal
.removeEventListener( 'fragmentshown', _onEvent
);
372 asyncTest( 'fragmenthidden event', function() {
375 var _onEvent = function( event
) {
376 ok( true, 'event fired' );
379 Reveal
.addEventListener( 'fragmenthidden', _onEvent
);
381 Reveal
.slide( 2, 0, 2 );
382 Reveal
.slide( 2, 0, 2 ); // should do nothing
385 Reveal
.next(); // shouldn't fire fragmenthidden
389 Reveal
.removeEventListener( 'fragmenthidden', _onEvent
);
393 // ---------------------------------------------------------------
396 QUnit
.module( 'Auto Sliding' );
398 test( 'Reveal.isAutoSliding', function() {
399 strictEqual( Reveal
.isAutoSliding(), false, 'false by default' );
401 Reveal
.configure({ autoSlide
: 10000 });
402 strictEqual( Reveal
.isAutoSliding(), true, 'true after starting' );
404 Reveal
.configure({ autoSlide
: 0 });
405 strictEqual( Reveal
.isAutoSliding(), false, 'false after setting to 0' );
408 test( 'Reveal.toggleAutoSlide', function() {
409 Reveal
.configure({ autoSlide
: 10000 });
411 Reveal
.toggleAutoSlide();
412 strictEqual( Reveal
.isAutoSliding(), false, 'false after first toggle' );
413 Reveal
.toggleAutoSlide();
414 strictEqual( Reveal
.isAutoSliding(), true, 'true after second toggle' );
416 Reveal
.configure({ autoSlide
: 0 });
419 asyncTest( 'autoslidepaused', function() {
422 var _onEvent = function( event
) {
423 ok( true, 'event fired' );
426 Reveal
.addEventListener( 'autoslidepaused', _onEvent
);
427 Reveal
.configure({ autoSlide
: 10000 });
428 Reveal
.toggleAutoSlide();
433 Reveal
.configure({ autoSlide
: 0 });
434 Reveal
.removeEventListener( 'autoslidepaused', _onEvent
);
437 asyncTest( 'autoslideresumed', function() {
440 var _onEvent = function( event
) {
441 ok( true, 'event fired' );
444 Reveal
.addEventListener( 'autoslideresumed', _onEvent
);
445 Reveal
.configure({ autoSlide
: 10000 });
446 Reveal
.toggleAutoSlide();
447 Reveal
.toggleAutoSlide();
452 Reveal
.configure({ autoSlide
: 0 });
453 Reveal
.removeEventListener( 'autoslideresumed', _onEvent
);
457 // ---------------------------------------------------------------
458 // CONFIGURATION VALUES
460 QUnit
.module( 'Configuration' );
462 test( 'Controls', function() {
463 var controlsElement
= document
.querySelector( '.reveal>.controls' );
465 Reveal
.configure({ controls
: false });
466 equal( controlsElement
.style
.display
, 'none', 'controls are hidden' );
468 Reveal
.configure({ controls
: true });
469 equal( controlsElement
.style
.display
, 'block', 'controls are visible' );
472 test( 'Progress', function() {
473 var progressElement
= document
.querySelector( '.reveal>.progress' );
475 Reveal
.configure({ progress
: false });
476 equal( progressElement
.style
.display
, 'none', 'progress are hidden' );
478 Reveal
.configure({ progress
: true });
479 equal( progressElement
.style
.display
, 'block', 'progress are visible' );
482 test( 'Loop', function() {
483 Reveal
.configure({ loop
: true });
485 Reveal
.slide( 0, 0 );
488 notEqual( Reveal
.getIndices().h
, 0, 'looped from start to end' );
491 equal( Reveal
.getIndices().h
, 0, 'looped from end to start' );
493 Reveal
.configure({ loop
: false });
497 // ---------------------------------------------------------------
498 // LAZY-LOADING TESTS
500 QUnit
.module( 'Lazy-Loading' );
502 test( 'img with data-src', function() {
503 strictEqual( document
.querySelectorAll( '.reveal section img[src]' ).length
, 1, 'Image source has been set' );
506 test( 'video with data-src', function() {
507 strictEqual( document
.querySelectorAll( '.reveal section video[src]' ).length
, 1, 'Video source has been set' );
510 test( 'audio with data-src', function() {
511 strictEqual( document
.querySelectorAll( '.reveal section audio[src]' ).length
, 1, 'Audio source has been set' );
514 test( 'iframe with data-src', function() {
515 Reveal
.slide( 0, 0 );
516 strictEqual( document
.querySelectorAll( '.reveal section iframe[src]' ).length
, 0, 'Iframe source is not set' );
517 Reveal
.slide( 2, 1 );
518 strictEqual( document
.querySelectorAll( '.reveal section iframe[src]' ).length
, 1, 'Iframe source is set' );
519 Reveal
.slide( 2, 2 );
520 strictEqual( document
.querySelectorAll( '.reveal section iframe[src]' ).length
, 0, 'Iframe source is not set' );
523 test( 'background images', function() {
524 var imageSource1
= Reveal
.getSlide( 0 ).getAttribute( 'data-background-image' );
525 var imageSource2
= Reveal
.getSlide( 1, 0 ).getAttribute( 'data-background' );
527 // check that the images are applied to the background elements
528 ok( Reveal
.getSlideBackground( 0 ).style
.backgroundImage
.indexOf( imageSource1
) !== -1, 'data-background-image worked' );
529 ok( Reveal
.getSlideBackground( 1, 0 ).style
.backgroundImage
.indexOf( imageSource2
) !== -1, 'data-background worked' );
533 // ---------------------------------------------------------------
536 QUnit
.module( 'Events' );
538 asyncTest( 'slidechanged', function() {
541 var _onEvent = function( event
) {
542 ok( true, 'event fired' );
545 Reveal
.addEventListener( 'slidechanged', _onEvent
);
547 Reveal
.slide( 1, 0 ); // should trigger
548 Reveal
.slide( 1, 0 ); // should do nothing
549 Reveal
.next(); // should trigger
550 Reveal
.slide( 3, 0 ); // should trigger
551 Reveal
.next(); // should do nothing
555 Reveal
.removeEventListener( 'slidechanged', _onEvent
);
559 asyncTest( 'paused', function() {
562 var _onEvent = function( event
) {
563 ok( true, 'event fired' );
566 Reveal
.addEventListener( 'paused', _onEvent
);
568 Reveal
.togglePause();
569 Reveal
.togglePause();
573 Reveal
.removeEventListener( 'paused', _onEvent
);
576 asyncTest( 'resumed', function() {
579 var _onEvent = function( event
) {
580 ok( true, 'event fired' );
583 Reveal
.addEventListener( 'resumed', _onEvent
);
585 Reveal
.togglePause();
586 Reveal
.togglePause();
590 Reveal
.removeEventListener( 'resumed', _onEvent
);