1 <!doctype html> 2 <!-- 3 @license 4 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 5 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8 Code distributed by Google as part of the polymer project is also 9 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10 --> 11 <html> 12 <head> 13 <title>active-state</title> 14 15 <script src="../../webcomponentsjs/webcomponents-lite.js"></script> 16 <script src="../../web-component-tester/browser.js"></script> 17 <script src="../../iron-test-helpers/mock-interactions.js"></script> 18 <link rel="import" href="test-elements.html"> 19 <link rel="import" href="../../paper-input/paper-input.html"> 20 </head> 21 <body> 22 <test-fixture id="TrivialActiveState"> 23 <template> 24 <test-button></test-button> 25 </template> 26 </test-fixture> 27 28 <test-fixture id="ToggleActiveState"> 29 <template> 30 <test-button toggles></test-button> 31 </template> 32 </test-fixture> 33 34 <test-fixture id="ButtonWithNativeInput"> 35 <template> 36 <test-light-dom><input id="input"></test-light-dom> 37 </template> 38 </test-fixture> 39 40 <test-fixture id="ButtonWithPaperInput"> 41 <template> 42 <test-light-dom><paper-input id="input"></paper-input></test-light-dom> 43 </template> 44 </test-fixture> 45 46 <script> 47 suite('active-state', function() { 48 var activeTarget; 49 50 setup(function() { 51 activeTarget = fixture('TrivialActiveState'); 52 }); 53 54 suite('active state with toggles attribute', function() { 55 setup(function() { 56 activeTarget = fixture('ToggleActiveState'); 57 }); 58 59 suite('when down', function() { 60 test('is pressed', function() { 61 MockInteractions.down(activeTarget); 62 expect(activeTarget.hasAttribute('pressed')).to.be.eql(true); 63 }); 64 }); 65 66 suite('when clicked', function() { 67 test('is activated', function(done) { 68 MockInteractions.downAndUp(activeTarget, function() { 69 try { 70 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 71 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 72 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('true'); 73 done(); 74 } catch (e) { 75 done(e); 76 } 77 }); 78 }); 79 80 test('is deactivated by a subsequent click', function(done) { 81 MockInteractions.downAndUp(activeTarget, function() { 82 MockInteractions.downAndUp(activeTarget, function() { 83 try { 84 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 85 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 86 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('false'); 87 done(); 88 } catch (e) { 89 done(e); 90 } 91 }); 92 }); 93 }); 94 95 test('the correct aria attribute is set', function(done) { 96 activeTarget.ariaActiveAttribute = 'aria-checked'; 97 MockInteractions.downAndUp(activeTarget, function() { 98 try { 99 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 100 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(true); 101 expect(activeTarget.getAttribute('aria-checked')).to.be.eql('true'); 102 done(); 103 } catch (e) { 104 done(e); 105 } 106 }); 107 }); 108 109 test('the aria attribute is updated correctly', function(done) { 110 activeTarget.ariaActiveAttribute = 'aria-checked'; 111 MockInteractions.downAndUp(activeTarget, function() { 112 try { 113 expect(activeTarget.hasAttribute('active')).to.be.eql(true); 114 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(true); 115 expect(activeTarget.getAttribute('aria-checked')).to.be.eql('true'); 116 117 activeTarget.ariaActiveAttribute = 'aria-pressed'; 118 expect(activeTarget.hasAttribute('aria-checked')).to.be.eql(false); 119 expect(activeTarget.hasAttribute('aria-pressed')).to.be.eql(true); 120 expect(activeTarget.getAttribute('aria-pressed')).to.be.eql('true'); 121 done(); 122 } catch (e) { 123 done(e); 124 } 125 }); 126 }); 127 }); 128 }); 129 130 suite('without toggles attribute', function() { 131 suite('when mouse is down', function() { 132 test('does not get an active attribute', function() { 133 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 134 MockInteractions.down(activeTarget); 135 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 136 }); 137 }); 138 139 suite('when mouse is up', function() { 140 test('does not get an active attribute', function() { 141 MockInteractions.down(activeTarget); 142 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 143 MockInteractions.up(activeTarget); 144 expect(activeTarget.hasAttribute('active')).to.be.eql(false); 145 }); 146 }); 147 }); 148 149 suite('when space is pressed', function() { 150 test('triggers a click event', function(done) { 151 activeTarget.addEventListener('click', function() { 152 done(); 153 }); 154 MockInteractions.pressSpace(activeTarget); 155 }); 156 157 test('only triggers click after the key is released', function(done) { 158 var keyupTriggered = false; 159 160 activeTarget.addEventListener('keyup', function() { 161 keyupTriggered = true; 162 }); 163 164 activeTarget.addEventListener('click', function() { 165 try { 166 expect(keyupTriggered).to.be.eql(true); 167 done(); 168 } catch (e) { 169 done(e); 170 } 171 }); 172 173 MockInteractions.pressSpace(activeTarget); 174 }); 175 }); 176 177 suite('when enter is pressed', function() { 178 test('triggers a click event', function(done) { 179 activeTarget.addEventListener('click', function() { 180 done(); 181 }); 182 183 MockInteractions.pressEnter(activeTarget); 184 }); 185 186 test('only triggers click before the key is released', function(done) { 187 var keyupTriggered = false; 188 189 activeTarget.addEventListener('keyup', function() { 190 keyupTriggered = true; 191 }); 192 193 activeTarget.addEventListener('click', function() { 194 try { 195 expect(keyupTriggered).to.be.eql(false); 196 done(); 197 } catch (e) { 198 done(e); 199 } 200 }); 201 202 MockInteractions.pressEnter(activeTarget); 203 }); 204 }); 205 206 suite('nested native input inside button', function() { 207 test('space in light child input does not trigger a button click event', function(done) { 208 var item = fixture('ButtonWithNativeInput'); 209 var input = item.querySelector('#input'); 210 211 var itemClickHandler = sinon.spy(); 212 item.addEventListener('click', itemClickHandler); 213 214 input.focus(); 215 MockInteractions.pressSpace(input); 216 Polymer.Base.async(function(){ 217 expect(itemClickHandler.callCount).to.be.equal(0); 218 done(); 219 }, 1); 220 }); 221 222 test('space in button triggers a button click event', function(done) { 223 var item = fixture('ButtonWithNativeInput'); 224 var input = item.querySelector('#input'); 225 226 var itemClickHandler = sinon.spy(); 227 item.addEventListener('click', itemClickHandler); 228 229 MockInteractions.pressSpace(item); 230 231 Polymer.Base.async(function(){ 232 // You need two ticks, one for the MockInteractions event, and one 233 // for the button event. 234 Polymer.Base.async(function(){ 235 expect(itemClickHandler.callCount).to.be.equal(1); 236 done(); 237 }, 1); 238 }, 1); 239 }); 240 }); 241 242 suite('nested paper-input inside button', function() { 243 test('space in light child input does not trigger a button click event', function(done) { 244 var item = fixture('ButtonWithPaperInput'); 245 var input = item.querySelector('#input'); 246 247 var itemClickHandler = sinon.spy(); 248 item.addEventListener('click', itemClickHandler); 249 250 input.focus(); 251 MockInteractions.pressSpace(input); 252 Polymer.Base.async(function(){ 253 expect(itemClickHandler.callCount).to.be.equal(0); 254 done(); 255 }, 1); 256 }); 257 258 test('space in button triggers a button click event', function(done) { 259 var item = fixture('ButtonWithPaperInput'); 260 var input = item.querySelector('#input'); 261 262 var itemClickHandler = sinon.spy(); 263 item.addEventListener('click', itemClickHandler); 264 265 MockInteractions.pressSpace(item); 266 Polymer.Base.async(function(){ 267 // You need two ticks, one for the MockInteractions event, and one 268 // for the button event. 269 Polymer.Base.async(function(){ 270 expect(itemClickHandler.callCount).to.be.equal(1); 271 done(); 272 }, 1); 273 }, 1); 274 }); 275 }); 276 277 }); 278 </script> 279 </body> 280 </html> 281