@@ -10,10 +10,24 @@ import {
1010 sharedTestTeardown ,
1111} from './test_helpers/setup_teardown.js' ;
1212
13- suite ( 'Aria ' , function ( ) {
13+ suite ( 'ARIA ' , function ( ) {
1414 setup ( function ( ) {
1515 sharedTestSetup . call ( this ) ;
16- this . workspace = Blockly . inject ( 'blocklyDiv' , { } ) ;
16+ Blockly . defineBlocksWithJsonArray ( [
17+ {
18+ type : 'basic_block' ,
19+ message0 : '%1' ,
20+ args0 : [
21+ {
22+ type : 'field_input' ,
23+ name : 'TEXT' ,
24+ text : 'default' ,
25+ } ,
26+ ] ,
27+ } ,
28+ ] ) ;
29+ const toolbox = document . getElementById ( 'toolbox-categories' ) ;
30+ this . workspace = Blockly . inject ( 'blocklyDiv' , { toolbox} ) ;
1731 this . liveRegion = document . getElementById ( 'blocklyAriaAnnounce' ) ;
1832 } ) ;
1933
@@ -263,4 +277,177 @@ suite('Aria', function () {
263277 assert . equal ( element . getAttribute ( 'aria-label' ) , 'one two three' ) ;
264278 } ) ;
265279 } ) ;
280+
281+ suite ( 'Blocks' , function ( ) {
282+ setup ( function ( ) {
283+ this . makeBlock = ( blockType ) => {
284+ const block = this . workspace . newBlock ( blockType ) ;
285+ block . initSvg ( ) ;
286+ block . render ( ) ;
287+ Blockly . getFocusManager ( ) . focusNode ( block ) ;
288+ return block ;
289+ } ;
290+ } ) ;
291+
292+ test ( 'Statement blocks have correct role description' , function ( ) {
293+ const block = this . makeBlock ( 'text_print' ) ;
294+ const roleDescription = Blockly . utils . aria . getState (
295+ block . getSvgRoot ( ) ,
296+ Blockly . utils . aria . State . ROLEDESCRIPTION ,
297+ ) ;
298+ assert . equal ( roleDescription , 'statement' ) ;
299+ } ) ;
300+
301+ test ( 'Value blocks have correct role description' , function ( ) {
302+ const block = this . makeBlock ( 'logic_boolean' ) ;
303+ const roleDescription = Blockly . utils . aria . getState (
304+ block . getSvgRoot ( ) ,
305+ Blockly . utils . aria . State . ROLEDESCRIPTION ,
306+ ) ;
307+ assert . equal ( roleDescription , 'value' ) ;
308+ } ) ;
309+
310+ test ( 'Container blocks have correct role description' , function ( ) {
311+ const block = this . makeBlock ( 'controls_if' ) ;
312+ const roleDescription = Blockly . utils . aria . getState (
313+ block . getSvgRoot ( ) ,
314+ Blockly . utils . aria . State . ROLEDESCRIPTION ,
315+ ) ;
316+ assert . equal ( roleDescription , 'container' ) ;
317+ } ) ;
318+
319+ test ( 'Workspace blocks have the correct role' , function ( ) {
320+ const block = this . makeBlock ( 'text_print' ) ;
321+ const role = Blockly . utils . aria . getRole ( block . getSvgRoot ( ) ) ;
322+ assert . equal ( role , Blockly . utils . aria . Role . FIGURE ) ;
323+ } ) ;
324+
325+ test ( 'Flyout blocks have the correct role' , function ( ) {
326+ Blockly . getFocusManager ( ) . focusNode (
327+ this . workspace . getToolbox ( ) . getToolboxItems ( ) [ 0 ] ,
328+ ) ;
329+ const block = this . workspace . getFlyout ( ) . getWorkspace ( ) . getTopBlocks ( ) [ 0 ] ;
330+ const role = Blockly . utils . aria . getRole ( block . getSvgRoot ( ) ) ;
331+ assert . equal ( role , Blockly . utils . aria . Role . LISTITEM ) ;
332+ } ) ;
333+
334+ test ( 'Root workspace blocks indicate that in their labels' , function ( ) {
335+ const block = this . makeBlock ( 'text_print' ) ;
336+ const label = Blockly . utils . aria . getState (
337+ block . getSvgRoot ( ) ,
338+ Blockly . utils . aria . State . LABEL ,
339+ ) ;
340+ assert . isTrue ( label . startsWith ( 'Begin stack' ) ) ;
341+ } ) ;
342+
343+ test ( 'Flyout blocks are not labeled as beginning a stack' , function ( ) {
344+ Blockly . getFocusManager ( ) . focusNode (
345+ this . workspace . getToolbox ( ) . getToolboxItems ( ) [ 0 ] ,
346+ ) ;
347+ const block = this . workspace . getFlyout ( ) . getWorkspace ( ) . getTopBlocks ( ) [ 0 ] ;
348+ const label = Blockly . utils . aria . getState (
349+ block . getSvgRoot ( ) ,
350+ Blockly . utils . aria . State . LABEL ,
351+ ) ;
352+ assert . notInclude ( label , 'Begin stack' ) ;
353+ } ) ;
354+
355+ test ( 'Nested statement blocks in first statement input do not include their parent input in their label' , function ( ) {
356+ const ifBlock = this . makeBlock ( 'controls_ifelse' ) ;
357+ const printBlock = this . makeBlock ( 'text_print' ) ;
358+ ifBlock . getInput ( 'IF0' ) . connection . connect ( printBlock . previousConnection ) ;
359+ const label = Blockly . utils . aria . getState (
360+ printBlock . getSvgRoot ( ) ,
361+ Blockly . utils . aria . State . LABEL ,
362+ ) ;
363+ assert . isFalse ( label . startsWith ( 'Begin do' ) ) ;
364+ } ) ;
365+
366+ test ( 'Nested statement blocks in subsequent statement inputs include their parent input in their label' , function ( ) {
367+ const ifBlock = this . makeBlock ( 'controls_ifelse' ) ;
368+ const printBlock = this . makeBlock ( 'text_print' ) ;
369+ ifBlock
370+ . getInput ( 'ELSE' )
371+ . connection . connect ( printBlock . previousConnection ) ;
372+ const label = Blockly . utils . aria . getState (
373+ printBlock . getSvgRoot ( ) ,
374+ Blockly . utils . aria . State . LABEL ,
375+ ) ;
376+ assert . isTrue ( label . startsWith ( 'Begin else' ) ) ;
377+ } ) ;
378+
379+ test ( 'Disabled blocks indicate that in their label' , function ( ) {
380+ const block = this . makeBlock ( 'text_print' ) ;
381+ let label = Blockly . utils . aria . getState (
382+ block . getSvgRoot ( ) ,
383+ Blockly . utils . aria . State . LABEL ,
384+ ) ;
385+ assert . notInclude ( label , 'disabled' ) ;
386+ block . setDisabledReason ( true , 'testing' ) ;
387+ label = Blockly . utils . aria . getState (
388+ block . getSvgRoot ( ) ,
389+ Blockly . utils . aria . State . LABEL ,
390+ ) ;
391+ assert . include ( label , 'disabled' ) ;
392+ } ) ;
393+
394+ test ( 'Collapsed blocks indicate that in their label' , function ( ) {
395+ const block = this . makeBlock ( 'text_print' ) ;
396+ let label = Blockly . utils . aria . getState (
397+ block . getSvgRoot ( ) ,
398+ Blockly . utils . aria . State . LABEL ,
399+ ) ;
400+ assert . notInclude ( label , 'collapsed' ) ;
401+ block . setCollapsed ( true ) ;
402+ label = Blockly . utils . aria . getState (
403+ block . getSvgRoot ( ) ,
404+ Blockly . utils . aria . State . LABEL ,
405+ ) ;
406+ assert . include ( label , 'collapsed' ) ;
407+ } ) ;
408+
409+ test ( 'Shadow blocks indicate that in their label' , function ( ) {
410+ const block = this . makeBlock ( 'text_print' ) ;
411+ const text = this . makeBlock ( 'text' ) ;
412+ text . outputConnection . connect ( block . inputList [ 0 ] . connection ) ;
413+ let label = Blockly . utils . aria . getState (
414+ text . getSvgRoot ( ) ,
415+ Blockly . utils . aria . State . LABEL ,
416+ ) ;
417+ assert . notInclude ( label , 'replaceable' ) ;
418+ text . setShadow ( true ) ;
419+ label = Blockly . utils . aria . getState (
420+ text . getSvgRoot ( ) ,
421+ Blockly . utils . aria . State . LABEL ,
422+ ) ;
423+ assert . include ( label , 'replaceable' ) ;
424+ } ) ;
425+
426+ test ( 'Blocks without inputs are properly labeled' , function ( ) {
427+ const block = this . makeBlock ( 'math_random_float' ) ;
428+ let label = Blockly . utils . aria . getState (
429+ block . getSvgRoot ( ) ,
430+ Blockly . utils . aria . State . LABEL ,
431+ ) ;
432+ assert . notInclude ( label , 'input' ) ;
433+ } ) ;
434+
435+ test ( 'Blocks with one input are properly labeled' , function ( ) {
436+ const block = this . makeBlock ( 'logic_negate' ) ;
437+ let label = Blockly . utils . aria . getState (
438+ block . getSvgRoot ( ) ,
439+ Blockly . utils . aria . State . LABEL ,
440+ ) ;
441+ assert . isTrue ( label . endsWith ( 'has input' ) ) ;
442+ } ) ;
443+
444+ test ( 'Blocks with multiple inputs are properly labeled' , function ( ) {
445+ const block = this . makeBlock ( 'logic_ternary' ) ;
446+ let label = Blockly . utils . aria . getState (
447+ block . getSvgRoot ( ) ,
448+ Blockly . utils . aria . State . LABEL ,
449+ ) ;
450+ assert . isTrue ( label . endsWith ( 'has inputs' ) ) ;
451+ } ) ;
452+ } ) ;
266453} ) ;
0 commit comments