| // Copyright 2011 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| goog.provide('goog.ui.ModalPopupTest'); |
| goog.setTestOnly('goog.ui.ModalPopupTest'); |
| |
| goog.require('goog.a11y.aria'); |
| goog.require('goog.a11y.aria.State'); |
| goog.require('goog.dispose'); |
| goog.require('goog.dom'); |
| goog.require('goog.events'); |
| goog.require('goog.events.EventTarget'); |
| goog.require('goog.fx.Transition'); |
| goog.require('goog.fx.css3'); |
| goog.require('goog.string'); |
| goog.require('goog.style'); |
| goog.require('goog.testing.MockClock'); |
| goog.require('goog.testing.jsunit'); |
| goog.require('goog.ui.ModalPopup'); |
| goog.require('goog.ui.PopupBase'); |
| |
| var popup; |
| var main; |
| var mockClock; |
| |
| |
| function setUp() { |
| main = /** @type {!Element}*/ (goog.dom.getElement('main')); |
| mockClock = new goog.testing.MockClock(true); |
| } |
| |
| |
| function tearDown() { |
| goog.dispose(popup); |
| mockClock.dispose(); |
| goog.a11y.aria.removeState(main, goog.a11y.aria.State.HIDDEN); |
| } |
| |
| |
| function testDispose() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| goog.dispose(popup); |
| assertNull(goog.dom.getElementByClass('goog-modalpopup-bg')); |
| assertNull(goog.dom.getElementByClass('goog-modalpopup')); |
| assertEquals(0, goog.dom.getElementsByTagNameAndClass('span').length); |
| } |
| |
| |
| function testRenderWithoutIframeMask() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| assertEquals(0, goog.dom.getElementsByTagNameAndClass( |
| 'iframe', 'goog-modalpopup-bg').length); |
| |
| var bg = goog.dom.getElementsByTagNameAndClass('div', 'goog-modalpopup-bg'); |
| assertEquals(1, bg.length); |
| var content = goog.dom.getElementByClass('goog-modalpopup'); |
| assertNotNull(content); |
| var tabCatcher = goog.dom.getElementsByTagNameAndClass('span'); |
| assertEquals(1, tabCatcher.length); |
| |
| assertTrue(goog.dom.compareNodeOrder(bg[0], content) < 0); |
| assertTrue(goog.dom.compareNodeOrder(content, tabCatcher[0]) < 0); |
| assertTrue(goog.string.isEmptyOrWhitespace(goog.string.makeSafe( |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)))); |
| popup.setVisible(true); |
| assertTrue(goog.string.isEmptyOrWhitespace(goog.string.makeSafe( |
| goog.a11y.aria.getState( |
| popup.getElementStrict(), goog.a11y.aria.State.HIDDEN)))); |
| assertEquals('true', |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| popup.setVisible(false); |
| assertTrue(goog.string.isEmptyOrWhitespace(goog.string.makeSafe( |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)))); |
| } |
| |
| |
| function testRenderWithIframeMask() { |
| popup = new goog.ui.ModalPopup(true); |
| popup.render(); |
| |
| var iframe = goog.dom.getElementsByTagNameAndClass( |
| 'iframe', 'goog-modalpopup-bg'); |
| assertEquals(1, iframe.length); |
| var bg = goog.dom.getElementsByTagNameAndClass('div', 'goog-modalpopup-bg'); |
| assertEquals(1, bg.length); |
| var content = goog.dom.getElementByClass('goog-modalpopup'); |
| assertNotNull(content); |
| var tabCatcher = goog.dom.getElementsByTagNameAndClass('span'); |
| assertEquals(1, tabCatcher.length); |
| |
| assertTrue(goog.dom.compareNodeOrder(iframe[0], bg[0]) < 0); |
| assertTrue(goog.dom.compareNodeOrder(bg[0], content) < 0); |
| assertTrue(goog.dom.compareNodeOrder(content, tabCatcher[0]) < 0); |
| assertTrue(goog.string.isEmptyOrWhitespace(goog.string.makeSafe( |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)))); |
| popup.setVisible(true); |
| assertTrue(goog.string.isEmptyOrWhitespace(goog.string.makeSafe( |
| goog.a11y.aria.getState( |
| popup.getElementStrict(), goog.a11y.aria.State.HIDDEN)))); |
| assertEquals('true', |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| popup.setVisible(false); |
| assertTrue(goog.string.isEmptyOrWhitespace( |
| goog.string.makeSafe( |
| goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)))); |
| } |
| |
| |
| function testRenderWithAriaState() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| goog.a11y.aria.setState(main, goog.a11y.aria.State.HIDDEN, true); |
| popup.setVisible(true); |
| assertEquals( |
| 'true', goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| popup.setVisible(false); |
| assertEquals( |
| 'true', goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| |
| goog.a11y.aria.setState(main, goog.a11y.aria.State.HIDDEN, false); |
| popup.setVisible(true); |
| assertEquals( |
| 'false', goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| popup.setVisible(false); |
| assertEquals( |
| 'false', goog.a11y.aria.getState(main, goog.a11y.aria.State.HIDDEN)); |
| } |
| |
| |
| function testRenderDoesNotShowAnyElement() { |
| popup = new goog.ui.ModalPopup(true); |
| popup.render(); |
| |
| var iframe = goog.dom.getElementsByTagNameAndClass( |
| 'iframe', 'goog-modalpopup-bg'); |
| assertFalse(goog.style.isElementShown(iframe[0])); |
| var bg = goog.dom.getElementsByTagNameAndClass('div', 'goog-modalpopup-bg'); |
| assertFalse(goog.style.isElementShown(bg[0])); |
| assertFalse(goog.style.isElementShown( |
| goog.dom.getElementByClass('goog-modalpopup'))); |
| var tabCatcher = goog.dom.getElementsByTagNameAndClass('span'); |
| assertFalse(goog.style.isElementShown(tabCatcher[0])); |
| } |
| |
| |
| function testIframeOpacityIsSetToZero() { |
| popup = new goog.ui.ModalPopup(true); |
| popup.render(); |
| |
| var iframe = goog.dom.getElementsByTagNameAndClass( |
| 'iframe', 'goog-modalpopup-bg')[0]; |
| assertEquals(0, goog.style.getOpacity(iframe)); |
| } |
| |
| |
| function testEventFiredOnShow() { |
| popup = new goog.ui.ModalPopup(true); |
| popup.render(); |
| |
| var beforeShowCallCount = 0; |
| var beforeShowHandler = function() { |
| beforeShowCallCount++; |
| }; |
| var showCallCount = false; |
| var showHandler = function() { |
| assertEquals('BEFORE_SHOW is not dispatched before SHOW', |
| 1, beforeShowCallCount); |
| showCallCount++; |
| }; |
| |
| goog.events.listen( |
| popup, goog.ui.PopupBase.EventType.BEFORE_SHOW, beforeShowHandler); |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.SHOW, showHandler); |
| |
| popup.setVisible(true); |
| |
| assertEquals(1, beforeShowCallCount); |
| assertEquals(1, showCallCount); |
| } |
| |
| |
| function testEventFiredOnHide() { |
| popup = new goog.ui.ModalPopup(true); |
| popup.render(); |
| popup.setVisible(true); |
| |
| var beforeHideCallCount = 0; |
| var beforeHideHandler = function() { |
| beforeHideCallCount++; |
| }; |
| var hideCallCount = false; |
| var hideHandler = function() { |
| assertEquals('BEFORE_HIDE is not dispatched before HIDE', |
| 1, beforeHideCallCount); |
| hideCallCount++; |
| }; |
| |
| goog.events.listen( |
| popup, goog.ui.PopupBase.EventType.BEFORE_HIDE, beforeHideHandler); |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.HIDE, hideHandler); |
| |
| popup.setVisible(false); |
| |
| assertEquals(1, beforeHideCallCount); |
| assertEquals(1, hideCallCount); |
| } |
| |
| |
| function testShowEventFiredWithNoTransition() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| var showHandlerCalled = false; |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.SHOW, function() { |
| showHandlerCalled = true; |
| }); |
| |
| popup.setVisible(true); |
| assertTrue(showHandlerCalled); |
| } |
| |
| function testHideEventFiredWithNoTransition() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| var hideHandlerCalled = false; |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.HIDE, function() { |
| hideHandlerCalled = true; |
| }); |
| |
| popup.setVisible(true); |
| popup.setVisible(false); |
| assertTrue(hideHandlerCalled); |
| } |
| |
| function testTransitionsPlayedOnShow() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| var mockPopupShowTransition = new MockTransition(); |
| var mockPopupHideTransition = new MockTransition(); |
| var mockBgShowTransition = new MockTransition(); |
| var mockBgHideTransition = new MockTransition(); |
| |
| var showHandlerCalled = false; |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.SHOW, function() { |
| showHandlerCalled = true; |
| }); |
| |
| popup.setTransition(mockPopupShowTransition, mockPopupHideTransition, |
| mockBgShowTransition, mockBgHideTransition); |
| assertFalse(mockPopupShowTransition.wasPlayed); |
| assertFalse(mockBgShowTransition.wasPlayed); |
| |
| popup.setVisible(true); |
| assertTrue(mockPopupShowTransition.wasPlayed); |
| assertTrue(mockBgShowTransition.wasPlayed); |
| |
| assertFalse(showHandlerCalled); |
| mockPopupShowTransition.dispatchEvent(goog.fx.Transition.EventType.END); |
| assertTrue(showHandlerCalled); |
| } |
| |
| |
| function testTransitionsPlayedOnHide() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| var mockPopupShowTransition = new MockTransition(); |
| var mockPopupHideTransition = new MockTransition(); |
| var mockBgShowTransition = new MockTransition(); |
| var mockBgHideTransition = new MockTransition(); |
| |
| var hideHandlerCalled = false; |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.HIDE, function() { |
| hideHandlerCalled = true; |
| }); |
| |
| popup.setTransition(mockPopupShowTransition, mockPopupHideTransition, |
| mockBgShowTransition, mockBgHideTransition); |
| popup.setVisible(true); |
| assertFalse(mockPopupHideTransition.wasPlayed); |
| assertFalse(mockBgHideTransition.wasPlayed); |
| |
| popup.setVisible(false); |
| assertTrue(mockPopupHideTransition.wasPlayed); |
| assertTrue(mockBgHideTransition.wasPlayed); |
| |
| assertFalse(hideHandlerCalled); |
| mockPopupHideTransition.dispatchEvent(goog.fx.Transition.EventType.END); |
| assertTrue(hideHandlerCalled); |
| } |
| |
| |
| function testTransitionsAndDisposingOnHideWorks() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.HIDE, function() { |
| popup.dispose(); |
| }); |
| |
| var popupShowTransition = goog.fx.css3.fadeIn(popup.getElement(), |
| 0.1 /* duration */); |
| var popupHideTransition = goog.fx.css3.fadeOut(popup.getElement(), |
| 0.1 /* duration */); |
| var bgShowTransition = goog.fx.css3.fadeIn(popup.getElement(), |
| 0.1 /* duration */); |
| var bgHideTransition = goog.fx.css3.fadeOut(popup.getElement(), |
| 0.1 /* duration */); |
| |
| popup.setTransition(popupShowTransition, popupHideTransition, |
| bgShowTransition, bgHideTransition); |
| popup.setVisible(true); |
| popup.setVisible(false); |
| // Nothing to assert. We only want to ensure that there is no error. |
| } |
| |
| |
| function testSetVisibleWorksCorrectlyWithTransitions() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| popup.setTransition( |
| goog.fx.css3.fadeIn(popup.getElement(), 1), |
| goog.fx.css3.fadeIn(popup.getBackgroundElement(), 1), |
| goog.fx.css3.fadeOut(popup.getElement(), 1), |
| goog.fx.css3.fadeOut(popup.getBackgroundElement(), 1)); |
| |
| // Consecutive calls to setVisible works without needing to wait for |
| // transition to finish. |
| popup.setVisible(true); |
| assertTrue(popup.isVisible()); |
| popup.setVisible(false); |
| assertFalse(popup.isVisible()); |
| mockClock.tick(1100); |
| |
| // Calling setVisible(true) immediately changed the state to visible. |
| popup.setVisible(true); |
| assertTrue(popup.isVisible()); |
| mockClock.tick(1100); |
| |
| // Consecutive calls to setVisible, in opposite order. |
| popup.setVisible(false); |
| popup.setVisible(true); |
| assertTrue(popup.isVisible()); |
| mockClock.tick(1100); |
| |
| // Calling setVisible(false) immediately changed the state to not visible. |
| popup.setVisible(false); |
| assertFalse(popup.isVisible()); |
| mockClock.tick(1100); |
| } |
| |
| |
| function testTransitionsDisposed() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| |
| var transition = goog.fx.css3.fadeIn(popup.getElement(), 0.1 /* duration */); |
| |
| var hideHandlerCalled = false; |
| goog.events.listen(popup, goog.ui.PopupBase.EventType.HIDE, function() { |
| hideHandlerCalled = true; |
| }); |
| |
| popup.setTransition(transition, transition, transition, transition); |
| popup.dispose(); |
| |
| transition.dispatchEvent(goog.fx.Transition.EventType.END); |
| assertFalse(hideHandlerCalled); |
| } |
| |
| |
| function testBackgroundHeight() { |
| // Insert an absolutely-positioned element larger than the viewport. |
| var viewportSize = goog.dom.getViewportSize(); |
| var w = viewportSize.width * 2; |
| var h = viewportSize.height * 2; |
| var dummy = goog.dom.createElement('div'); |
| dummy.style.position = 'absolute'; |
| goog.style.setSize(dummy, w, h); |
| document.body.appendChild(dummy); |
| |
| try { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| popup.setVisible(true); |
| |
| var size = goog.style.getSize(popup.getBackgroundElement()); |
| assertTrue('Background element must cover the size of the content', |
| size.width >= w && size.height >= h); |
| } finally { |
| goog.dom.removeNode(dummy); |
| } |
| } |
| |
| |
| function testSetupBackwardTabWrapResetsFlagAfterTimeout() { |
| popup.setupBackwardTabWrap(); |
| assertTrue('Backward tab wrap should be in progress', |
| popup.backwardTabWrapInProgress_); |
| mockClock.tick(1); |
| assertFalse('Backward tab wrap flag should be reset after delay', |
| popup.backwardTabWrapInProgress_); |
| } |
| |
| |
| function testPopupGetsFocus() { |
| popup = new goog.ui.ModalPopup(); |
| popup.render(); |
| popup.setVisible(true); |
| assertTrue('Dialog must receive initial focus', |
| goog.dom.getActiveElement(document) == popup.getElement()); |
| } |
| |
| |
| function testDecoratedPopupGetsFocus() { |
| var dialogElem = goog.dom.createElement('div'); |
| document.body.appendChild(dialogElem); |
| popup = new goog.ui.ModalPopup(); |
| popup.decorate(dialogElem); |
| popup.setVisible(true); |
| assertTrue('Dialog must receive initial focus', |
| goog.dom.getActiveElement(document) == popup.getElement()); |
| goog.dom.removeNode(dialogElem); |
| } |
| |
| |
| |
| /** |
| * @implements {goog.fx.Transition} |
| * @extends {goog.events.EventTarget} |
| * @constructor |
| */ |
| var MockTransition = function() { |
| MockTransition.base(this, 'constructor'); |
| this.wasPlayed = false; |
| }; |
| goog.inherits(MockTransition, goog.events.EventTarget); |
| |
| |
| MockTransition.prototype.play = function() { |
| this.wasPlayed = true; |
| }; |
| |
| |
| MockTransition.prototype.stop = goog.nullFunction; |