UNPKG

spincycle

Version:

A reactive message router and object manager that lets clients subscribe to object property changes on the server

409 lines (356 loc) 15.5 kB
<!doctype html> <!-- @license Copyright (c) 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> <html> <head> <title>paper-dialog-behavior tests</title> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes"> <script src="../../webcomponentsjs/webcomponents-lite.js"></script> <script src="../../web-component-tester/browser.js"></script> <link rel="import" href="../../paper-icon-button/paper-icon-button.html"> <link rel="import" href="../../iron-icons/iron-icons.html"> <link rel="import" href="../../iron-test-helpers/iron-test-helpers.html"> <link rel="import" href="test-dialog.html"> <link rel="import" href="test-buttons.html"> </head> <body> <test-fixture id="basic"> <template> <test-dialog> <p>Dialog</p> <div class="buttons"> <button extra>extra</button> <button dialog-dismiss>dismiss</button> <button dialog-confirm>confirm</button> </div> </test-dialog> </template> </test-fixture> <test-fixture id="buttons"> <template> <test-dialog> <p>Dialog with test-buttons</p> <test-buttons class="buttons"></test-buttons> </test-dialog> </template> </test-fixture> <test-fixture id="custom-element-button"> <template> <test-dialog> <p>Dialog</p> <div class="buttons"> <paper-icon-button icon="cancel" dialog-dismiss></paper-icon-button> <paper-icon-button icon="add-circle" dialog-confirm></paper-icon-button> <paper-icon-button icon="favorite"></paper-icon-button> </div> </test-dialog> </template> </test-fixture> <test-fixture id="modal"> <template> <test-dialog modal> <p>Dialog</p> <div class="buttons"> <button dialog-dismiss>dismiss</button> <button dialog-confirm autofocus>confirm</button> </div> </test-dialog> </template> </test-fixture> <test-fixture id="like-modal"> <template> <test-dialog no-cancel-on-esc-key no-cancel-on-outside-click with-backdrop> <p>Dialog</p> </test-dialog> </template> </test-fixture> <test-fixture id="header"> <template> <test-dialog> <h2>Dialog</h2> <div class="buttons"> <button dialog-dismiss>dismiss</button> <button dialog-confirm autofocus>confirm</button> </div> </test-dialog> </template> </test-fixture> <test-fixture id="header-with-id"> <template> <test-dialog> <h2 id="header">Dialog</h2> <div class="buttons"> <button dialog-dismiss>dismiss</button> <button dialog-confirm autofocus>confirm</button> </div> </test-dialog> </template> </test-fixture> <test-fixture id="multiple"> <template> <test-dialog modal id="dialog1"> <p>Dialog 1</p> </test-dialog> <test-dialog modal id="dialog2"> <p>Dialog 2</p> </test-dialog> </template> </test-fixture> <test-fixture id="nestedmodals"> <template> <test-dialog modal opened> <p>Dialog 1</p> <div class="buttons"> <button dialog-dismiss>dismiss</button> <button dialog-confirm autofocus>confirm</button> </div> <test-dialog modal opened> <p>Dialog 2</p> <div class="buttons"> <button dialog-dismiss>dismiss</button> <button dialog-confirm autofocus>confirm</button> </div> </test-dialog> </test-dialog> </template> </test-fixture> <script> function runAfterOpen(dialog, callback) { dialog.addEventListener('iron-overlay-opened', callback); dialog.open(); } suite('basic', function() { test('clicking dialog does not cancel the dialog', function(done) { var dialog = fixture('basic'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function() { assert('dialog should not close'); }); MockInteractions.tap(dialog); setTimeout(function() { done(); }, 100); }); }); test('clicking dialog-dismiss button closes the dialog without confirmation', function(done) { var dialog = fixture('basic'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isFalse(event.detail.confirmed, 'dialog is not confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-dismiss]')); }); }); test('dialog-dismiss on a custom element is handled', function(done) { var dialog = fixture('custom-element-button'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isFalse(event.detail.confirmed, 'dialog is not confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-dismiss]')); }); }); test('dialog-dismiss button inside a custom element is handled', function(done) { var dialog = fixture('buttons'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isFalse(event.detail.confirmed, 'dialog is not confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('test-buttons').$.dismiss); }); }); test('clicking dialog-confirm button closes the dialog with confirmation', function(done) { var dialog = fixture('basic'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isTrue(event.detail.confirmed, 'dialog is confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-confirm]')); }); }); test('dialog-confirm on a custom element handled', function(done) { var dialog = fixture('custom-element-button'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isTrue(event.detail.confirmed, 'dialog is confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('[dialog-confirm]')); }); }); test('dialog-confirm button inside a custom element is handled', function(done) { var dialog = fixture('buttons'); runAfterOpen(dialog, function() { dialog.addEventListener('iron-overlay-closed', function(event) { assert.isFalse(event.detail.canceled, 'dialog is not canceled'); assert.isTrue(event.detail.confirmed, 'dialog is confirmed'); done(); }); MockInteractions.tap(Polymer.dom(dialog).querySelector('test-buttons').$.confirm); }); }); test('clicking dialog-dismiss button closes only the dialog where is contained', function(done) { var dialog = fixture('nestedmodals'); var innerDialog = Polymer.dom(dialog).querySelector('test-dialog'); MockInteractions.tap(Polymer.dom(innerDialog).querySelector('[dialog-dismiss]')); setTimeout(function() { assert.isFalse(innerDialog.opened, 'inner dialog is closed'); assert.isTrue(dialog.opened, 'dialog is still open'); done(); }, 10); }); test('clicking dialog-confirm button closes only the dialog where is contained', function(done) { var dialog = fixture('nestedmodals'); var innerDialog = Polymer.dom(dialog).querySelector('test-dialog'); MockInteractions.tap(Polymer.dom(innerDialog).querySelector('[dialog-confirm]')); setTimeout(function() { assert.isFalse(innerDialog.opened, 'inner dialog is closed'); assert.isTrue(dialog.opened, 'dialog is still open'); done(); }, 10); }); var properties = ['noCancelOnEscKey', 'noCancelOnOutsideClick', 'withBackdrop']; properties.forEach(function(property) { test('modal sets ' + property + ' to true', function() { var dialog = fixture('modal'); assert.isTrue(dialog[property], property); }); test('modal toggling keeps current value of ' + property, function() { var dialog = fixture('modal'); // Changed to false while modal is true. dialog[property] = false; dialog.modal = false; assert.isFalse(dialog[property], property + ' is false'); }); test('modal toggling keeps previous value of ' + property, function() { var dialog = fixture('basic'); // Changed before modal is true. dialog[property] = true; // Toggle twice to trigger observer. dialog.modal = true; dialog.modal = false; assert.isTrue(dialog[property], property + ' is still true'); }); test('default modal does not override ' + property +' (attribute)', function() { // Property is set on ready from attribute. var dialog = fixture('like-modal'); assert.isTrue(dialog[property], property + ' is true'); }); test('modal toggling keeps previous value of ' + property + ' (attribute)', function() { // Property is set on ready from attribute. var dialog = fixture('like-modal'); // Toggle twice to trigger observer. dialog.modal = true; dialog.modal = false; assert.isTrue(dialog[property], property + ' is still true'); }); }); test('clicking outside a modal dialog does not move focus from dialog', function(done) { var dialog = fixture('modal'); runAfterOpen(dialog, function() { MockInteractions.tap(document.body); setTimeout(function() { assert.equal(document.activeElement, Polymer.dom(dialog).querySelector('[autofocus]'), 'document.activeElement is the autofocused button'); done(); }, 10); }); }); test('removing a child element on click does not cause an exception', function(done) { var dialog = fixture('basic'); runAfterOpen(dialog, function() { var button = Polymer.dom(dialog).querySelector('[extra]'); button.addEventListener('click', function(event) { Polymer.dom(event.target.parentNode).removeChild(event.target); // should not throw exception here done(); }); MockInteractions.tap(button); }); }); test('multiple modal dialogs opened, handle focus change', function(done) { var dialogs = fixture('multiple'); runAfterOpen(dialogs[0], function() { runAfterOpen(dialogs[1], function() { // Each modal dialog will trap the focus within its children. // Multiple modal dialogs doing it might result in an infinite loop // dialog1 focus -> dialog2 focus -> dialog1 focus -> dialog2 focus... // causing a "Maximum call stack size exceeded" error. // Wait 50ms and verify this does not happen. Polymer.Base.async(function() { // Should not enter in an infinite loop. done(); }, 50); }); }); }); test('multiple modal dialogs opened, handle outside click', function(done) { var dialogs = fixture('multiple'); runAfterOpen(dialogs[0], function() { runAfterOpen(dialogs[1], function() { // Click should be handled only by dialogs[1]. MockInteractions.tap(document.body); // Each modal dialog will trap the focus within its children. // Multiple modal dialogs doing it might result in an infinite loop // dialog1 focus -> dialog2 focus -> dialog1 focus -> dialog2 focus... // causing a "Maximum call stack size exceeded" error. // Wait 50ms and verify this does not happen. Polymer.Base.async(function() { // Should not enter in an infinite loop. done(); }, 50); }); }); }); test('focus is given to the autofocus element when clicking on backdrop', function(done) { var dialog = fixture('modal'); dialog.addEventListener('iron-overlay-opened', onFirstOpen); dialog.open(); function onFirstOpen() { dialog.removeEventListener('iron-overlay-opened', onFirstOpen); dialog.addEventListener('iron-overlay-closed', onFirstClose); // Set the focus on dismiss button MockInteractions.focus(Polymer.dom(dialog).querySelector('[dialog-dismiss]')); // Close the dialog dialog.close(); } function onFirstClose() { dialog.removeEventListener('iron-overlay-closed', onFirstClose); dialog.addEventListener('iron-overlay-opened', onSecondOpen); dialog.open(); } function onSecondOpen() { MockInteractions.tap(document.body); setTimeout(function() { assert.equal(document.activeElement, Polymer.dom(dialog).querySelector('[autofocus]'), 'document.activeElement is the autofocused button'); done(); }, 10); } }); }); suite('a11y', function() { test('dialog has role="dialog"', function() { var dialog = fixture('basic'); assert.equal(dialog.getAttribute('role'), 'dialog', 'has role="dialog"'); }); }); </script> </body> </html>