tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_animation_properties.html (45520B)


      1 <!doctype html>
      2 <head>
      3 <meta charset=utf-8>
      4 <title>Bug 1254419 - Test the values returned by
      5       KeyframeEffect.getProperties()</title>
      6 <script type="application/javascript" src="../testharness.js"></script>
      7 <script type="application/javascript" src="../testharnessreport.js"></script>
      8 <script type="application/javascript" src="../testcommon.js"></script>
      9 </head>
     10 <body>
     11 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1254419"
     12  target="_blank">Mozilla Bug 1254419</a>
     13 <div id="log"></div>
     14 <style>
     15 @property --my-color {
     16  syntax: "<color>";
     17  inherits: true;
     18  initial-value: "gold";
     19 }
     20 
     21 :root {
     22  --var-100px: 100px;
     23  --var-100px-200px: 100px 200px;
     24 }
     25 div {
     26  font-size: 10px; /* For calculating em-based units */
     27 }
     28 </style>
     29 <script>
     30 'use strict';
     31 
     32 var gTests = [
     33 
     34  // ---------------------------------------------------------------------
     35  //
     36  // Tests for property-indexed specifications
     37  //
     38  // ---------------------------------------------------------------------
     39 
     40  { desc:     'a one-property two-value property-indexed specification',
     41    frames:   { left: ['10px', '20px'] },
     42    expected: [ { property: 'left',
     43                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     44                            valueFormat(1, '20px', 'replace') ] } ]
     45  },
     46  { desc:     'a one-shorthand-property two-value property-indexed'
     47              + ' specification',
     48    frames:   { margin: ['10px', '10px 20px 30px 40px'] },
     49    expected: [ { property: 'margin-top',
     50                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     51                            valueFormat(1, '10px', 'replace') ] },
     52                { property: 'margin-right',
     53                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     54                            valueFormat(1, '20px', 'replace') ] },
     55                { property: 'margin-bottom',
     56                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     57                            valueFormat(1, '30px', 'replace') ] },
     58                { property: 'margin-left',
     59                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     60                            valueFormat(1, '40px', 'replace') ] } ]
     61  },
     62  { desc:     'a two-property (one shorthand and one of its longhand'
     63              + ' components) two-value property-indexed specification',
     64    frames:   { marginTop: ['50px', '60px'],
     65                margin: ['10px', '10px 20px 30px 40px'] },
     66    expected: [ { property: 'margin-top',
     67                  values: [ valueFormat(0, '50px', 'replace', 'linear'),
     68                            valueFormat(1, '60px', 'replace') ] },
     69                { property: 'margin-right',
     70                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     71                            valueFormat(1, '20px', 'replace') ] },
     72                { property: 'margin-bottom',
     73                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     74                            valueFormat(1, '30px', 'replace') ] },
     75                { property: 'margin-left',
     76                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     77                            valueFormat(1, '40px', 'replace') ] } ]
     78  },
     79  { desc:     'a two-property property-indexed specification with different'
     80              + ' numbers of values',
     81    frames:   { left: ['10px', '20px', '30px'],
     82                top: ['40px', '50px'] },
     83    expected: [ { property: 'left',
     84                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     85                            valueFormat(0.5, '20px', 'replace', 'linear'),
     86                            valueFormat(1, '30px', 'replace') ] },
     87                { property: 'top',
     88                  values: [ valueFormat(0, '40px', 'replace', 'linear'),
     89                            valueFormat(1, '50px', 'replace') ] } ]
     90  },
     91  { desc:     'a property-indexed specification with an invalid value',
     92    frames:   { left: ['10px', '20px', '30px', '40px', '50px'],
     93                top:  ['15px', '25px', 'invalid', '45px', '55px'] },
     94    expected: [ { property: 'left',
     95                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
     96                            valueFormat(0.25, '20px', 'replace', 'linear'),
     97                            valueFormat(0.5, '30px', 'replace', 'linear'),
     98                            valueFormat(0.75, '40px', 'replace', 'linear'),
     99                            valueFormat(1, '50px', 'replace') ] },
    100                { property: 'top',
    101                  values: [ valueFormat(0, '15px', 'replace', 'linear'),
    102                            valueFormat(0.25, '25px', 'replace', 'linear'),
    103                            valueFormat(0.75, '45px', 'replace', 'linear'),
    104                            valueFormat(1, '55px', 'replace') ] } ]
    105  },
    106  { desc:     'a one-property two-value property-indexed specification that'
    107              + ' needs to stringify its values',
    108    frames:   { opacity: [0, 1] },
    109    expected: [ { property: 'opacity',
    110                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    111                            valueFormat(1, '1', 'replace') ] } ]
    112  },
    113  { desc:     'a property-indexed keyframe where a lesser shorthand precedes'
    114              + ' a greater shorthand',
    115    frames:   { borderLeft: [ '1px solid rgb(1, 2, 3)',
    116                              '2px solid rgb(4, 5, 6)' ],
    117                border:     [ '3px dotted rgb(7, 8, 9)',
    118                              '4px dashed rgb(10, 11, 12)' ] },
    119    expected: [ { property: 'border-bottom-color',
    120                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    121                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    122                { property: 'border-left-color',
    123                  values: [ valueFormat(0, 'rgb(1, 2, 3)', 'replace', 'linear'),
    124                            valueFormat(1, 'rgb(4, 5, 6)', 'replace') ] },
    125                { property: 'border-right-color',
    126                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    127                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    128                { property: 'border-top-color',
    129                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    130                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    131                { property: 'border-bottom-width',
    132                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    133                            valueFormat(1, '4px', 'replace') ] },
    134                { property: 'border-left-width',
    135                  values: [ valueFormat(0, '1px', 'replace', 'linear'),
    136                            valueFormat(1, '2px', 'replace') ] },
    137                { property: 'border-right-width',
    138                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    139                            valueFormat(1, '4px', 'replace') ] },
    140                { property: 'border-top-width',
    141                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    142                            valueFormat(1, '4px', 'replace') ] },
    143                { property: 'border-bottom-style',
    144                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    145                            valueFormat(1, 'dashed', 'replace') ] },
    146                { property: 'border-left-style',
    147                  values: [ valueFormat(0, 'solid', 'replace', 'linear'),
    148                            valueFormat(1, 'solid', 'replace') ] },
    149                { property: 'border-right-style',
    150                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    151                            valueFormat(1, 'dashed', 'replace') ] },
    152                { property: 'border-top-style',
    153                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    154                            valueFormat(1, 'dashed', 'replace') ] },
    155                { property: 'border-image-outset',
    156                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    157                            valueFormat(1, '0', 'replace') ] },
    158                { property: 'border-image-repeat',
    159                  values: [ valueFormat(0, 'stretch', 'replace', 'linear'),
    160                            valueFormat(1, 'stretch', 'replace') ] },
    161                { property: 'border-image-slice',
    162                  values: [ valueFormat(0, '100%', 'replace', 'linear'),
    163                            valueFormat(1, '100%', 'replace') ] },
    164                { property: 'border-image-source',
    165                  values: [ valueFormat(0, 'none', 'replace', 'linear'),
    166                            valueFormat(1, 'none', 'replace') ] },
    167                { property: 'border-image-width',
    168                  values: [ valueFormat(0, '1', 'replace', 'linear'),
    169                            valueFormat(1, '1', 'replace') ] },
    170    ]
    171  },
    172  { desc:     'a property-indexed keyframe where a greater shorthand precedes'
    173              + ' a lesser shorthand',
    174    frames:   { border:     [ '3px dotted rgb(7, 8, 9)',
    175                              '4px dashed rgb(10, 11, 12)' ],
    176                borderLeft: [ '1px solid rgb(1, 2, 3)',
    177                              '2px solid rgb(4, 5, 6)' ] },
    178    expected: [ { property: 'border-bottom-color',
    179                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    180                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    181                { property: 'border-left-color',
    182                  values: [ valueFormat(0, 'rgb(1, 2, 3)', 'replace', 'linear'),
    183                            valueFormat(1, 'rgb(4, 5, 6)', 'replace') ] },
    184                { property: 'border-right-color',
    185                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    186                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    187                { property: 'border-top-color',
    188                  values: [ valueFormat(0, 'rgb(7, 8, 9)', 'replace', 'linear'),
    189                            valueFormat(1, 'rgb(10, 11, 12)', 'replace') ] },
    190                { property: 'border-bottom-width',
    191                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    192                            valueFormat(1, '4px', 'replace') ] },
    193                { property: 'border-left-width',
    194                  values: [ valueFormat(0, '1px', 'replace', 'linear'),
    195                            valueFormat(1, '2px', 'replace') ] },
    196                { property: 'border-right-width',
    197                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    198                            valueFormat(1, '4px', 'replace') ] },
    199                { property: 'border-top-width',
    200                  values: [ valueFormat(0, '3px', 'replace', 'linear'),
    201                            valueFormat(1, '4px', 'replace') ] },
    202                { property: 'border-bottom-style',
    203                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    204                            valueFormat(1, 'dashed', 'replace') ] },
    205                { property: 'border-left-style',
    206                  values: [ valueFormat(0, 'solid', 'replace', 'linear'),
    207                            valueFormat(1, 'solid', 'replace') ] },
    208                { property: 'border-right-style',
    209                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    210                            valueFormat(1, 'dashed', 'replace') ] },
    211                { property: 'border-top-style',
    212                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    213                            valueFormat(1, 'dashed', 'replace') ] },
    214                { property: 'border-image-outset',
    215                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    216                            valueFormat(1, '0', 'replace') ] },
    217                { property: 'border-image-repeat',
    218                  values: [ valueFormat(0, 'stretch', 'replace', 'linear'),
    219                            valueFormat(1, 'stretch', 'replace') ] },
    220                { property: 'border-image-slice',
    221                  values: [ valueFormat(0, '100%', 'replace', 'linear'),
    222                            valueFormat(1, '100%', 'replace') ] },
    223                { property: 'border-image-source',
    224                  values: [ valueFormat(0, 'none', 'replace', 'linear'),
    225                            valueFormat(1, 'none', 'replace') ] },
    226                { property: 'border-image-width',
    227                  values: [ valueFormat(0, '1', 'replace', 'linear'),
    228                            valueFormat(1, '1', 'replace') ] },
    229    ]
    230  },
    231  { desc:     'custom registered property',
    232    frames:   { "--my-color": ['red', 'blue'] },
    233    expected: [ { property: '--my-color',
    234                  values: [ valueFormat(0, 'red', 'replace', 'linear'),
    235                            valueFormat(1, 'blue', 'replace') ] } ]
    236  },
    237 
    238  // ---------------------------------------------------------------------
    239  //
    240  // Tests for keyframe sequences
    241  //
    242  // ---------------------------------------------------------------------
    243 
    244  { desc:     'a keyframe sequence specification with repeated values at'
    245              + ' offset 0/1 with different easings',
    246    frames:   [ { offset: 0.0, left: '100px', easing: 'ease' },
    247                { offset: 0.0, left: '200px', easing: 'ease' },
    248                { offset: 0.5, left: '300px', easing: 'linear' },
    249                { offset: 1.0, left: '400px', easing: 'ease-out' },
    250                { offset: 1.0, left: '500px', easing: 'step-end' } ],
    251    expected: [ { property: 'left',
    252                  values: [ valueFormat(0, '100px', 'replace'),
    253                            valueFormat(0, '200px', 'replace', 'ease'),
    254                            valueFormat(0.5, '300px', 'replace', 'linear'),
    255                            valueFormat(1, '400px', 'replace'),
    256                            valueFormat(1, '500px', 'replace') ] } ]
    257  },
    258  { desc:     'a one-property two-keyframe sequence',
    259    frames:   [ { offset: 0, left: '10px' },
    260                { offset: 1, left: '20px' } ],
    261    expected: [ { property: 'left',
    262                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    263                            valueFormat(1, '20px', 'replace') ] } ]
    264  },
    265  { desc:     'a two-property two-keyframe sequence',
    266    frames:   [ { offset: 0, left: '10px', top: '30px' },
    267                { offset: 1, left: '20px', top: '40px' } ],
    268    expected: [ { property: 'left',
    269                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    270                            valueFormat(1, '20px', 'replace') ] },
    271                { property: 'top',
    272                  values: [ valueFormat(0, '30px', 'replace', 'linear'),
    273                            valueFormat(1, '40px', 'replace') ] } ]
    274  },
    275  { desc:     'a one shorthand property two-keyframe sequence',
    276    frames:   [ { offset: 0, margin: '10px' },
    277                { offset: 1, margin: '20px 30px 40px 50px' } ],
    278    expected: [ { property: 'margin-top',
    279                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    280                            valueFormat(1, '20px', 'replace') ] },
    281                { property: 'margin-right',
    282                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    283                            valueFormat(1, '30px', 'replace') ] },
    284                { property: 'margin-bottom',
    285                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    286                            valueFormat(1, '40px', 'replace') ] },
    287                { property: 'margin-left',
    288                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    289                            valueFormat(1, '50px', 'replace') ] } ]
    290  },
    291  { desc:     'a two-property (a shorthand and one of its component longhands)'
    292              + ' two-keyframe sequence',
    293    frames:   [ { offset: 0, margin: '10px', marginTop: '20px' },
    294                { offset: 1, marginTop: '70px',
    295                             margin: '30px 40px 50px 60px' } ],
    296    expected: [ { property: 'margin-top',
    297                  values: [ valueFormat(0, '20px', 'replace', 'linear'),
    298                            valueFormat(1, '70px', 'replace') ] },
    299                { property: 'margin-right',
    300                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    301                            valueFormat(1, '40px', 'replace') ] },
    302                { property: 'margin-bottom',
    303                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    304                            valueFormat(1, '50px', 'replace') ] },
    305                { property: 'margin-left',
    306                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    307                            valueFormat(1, '60px', 'replace') ] } ]
    308  },
    309  { desc:     'a keyframe sequence with duplicate values for a given interior'
    310              + ' offset',
    311    frames:   [ { offset: 0.0, left: '10px' },
    312                { offset: 0.5, left: '20px' },
    313                { offset: 0.5, left: '30px' },
    314                { offset: 0.5, left: '40px' },
    315                { offset: 1.0, left: '50px' } ],
    316    expected: [ { property: 'left',
    317                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    318                            valueFormat(0.5, '20px', 'replace'),
    319                            valueFormat(0.5, '40px', 'replace', 'linear'),
    320                            valueFormat(1, '50px', 'replace') ] } ]
    321  },
    322  { desc:     'a keyframe sequence with duplicate values for offsets 0 and 1',
    323    frames:   [ { offset: 0, left: '10px' },
    324                { offset: 0, left: '20px' },
    325                { offset: 0, left: '30px' },
    326                { offset: 1, left: '40px' },
    327                { offset: 1, left: '50px' },
    328                { offset: 1, left: '60px' } ],
    329    expected: [ { property: 'left',
    330                  values: [ valueFormat(0, '10px', 'replace'),
    331                            valueFormat(0, '30px', 'replace', 'linear'),
    332                            valueFormat(1, '40px', 'replace'),
    333                            valueFormat(1, '60px', 'replace') ] } ]
    334  },
    335  { desc:     'a two-property four-keyframe sequence',
    336    frames:   [ { offset: 0, left: '10px' },
    337                { offset: 0, top: '20px' },
    338                { offset: 1, top: '30px' },
    339                { offset: 1, left: '40px' } ],
    340    expected: [ { property: 'left',
    341                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    342                            valueFormat(1, '40px', 'replace') ] },
    343                { property: 'top',
    344                  values: [ valueFormat(0, '20px', 'replace', 'linear'),
    345                            valueFormat(1, '30px', 'replace') ] } ]
    346  },
    347  { desc:     'a one-property keyframe sequence with some omitted offsets',
    348    frames:   [ { offset: 0.00, left: '10px' },
    349                { offset: 0.25, left: '20px' },
    350                { left: '30px' },
    351                { left: '40px' },
    352                { offset: 1.00, left: '50px' } ],
    353    expected: [ { property: 'left',
    354                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    355                            valueFormat(0.25, '20px', 'replace', 'linear'),
    356                            valueFormat(0.5, '30px', 'replace', 'linear'),
    357                            valueFormat(0.75, '40px', 'replace', 'linear'),
    358                            valueFormat(1, '50px', 'replace') ] } ]
    359  },
    360  { desc:     'a two-property keyframe sequence with some omitted offsets',
    361    frames:   [ { offset: 0.00, left: '10px', top: '20px' },
    362                { offset: 0.25, left: '30px' },
    363                { left: '40px' },
    364                { left: '50px', top: '60px' },
    365                { offset: 1.00, left: '70px', top: '80px' } ],
    366    expected: [ { property: 'left',
    367                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    368                            valueFormat(0.25, '30px', 'replace', 'linear'),
    369                            valueFormat(0.5, '40px', 'replace', 'linear'),
    370                            valueFormat(0.75, '50px', 'replace', 'linear'),
    371                            valueFormat(1, '70px', 'replace') ] },
    372                { property: 'top',
    373                  values: [ valueFormat(0, '20px', 'replace', 'linear'),
    374                            valueFormat(0.75, '60px', 'replace', 'linear'),
    375                            valueFormat(1, '80px', 'replace') ] } ]
    376  },
    377  { desc:     'a one-property keyframe sequence with all omitted offsets',
    378    frames:   [ { left: '10px' },
    379                { left: '20px' },
    380                { left: '30px' },
    381                { left: '40px' },
    382                { left: '50px' } ],
    383    expected: [ { property: 'left',
    384                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    385                            valueFormat(0.25, '20px', 'replace', 'linear'),
    386                            valueFormat(0.5, '30px', 'replace', 'linear'),
    387                            valueFormat(0.75, '40px', 'replace', 'linear'),
    388                            valueFormat(1, '50px', 'replace') ] } ]
    389  },
    390  { desc:     'a keyframe sequence with different easing values, but the'
    391              + ' same easing value for a given offset',
    392    frames:   [ { offset: 0.0, easing: 'ease',     left: '10px'},
    393                { offset: 0.0, easing: 'ease',     top: '20px'},
    394                { offset: 0.5, easing: 'linear',   left: '30px' },
    395                { offset: 0.5, easing: 'linear',   top: '40px' },
    396                { offset: 1.0, easing: 'step-end', left: '50px' },
    397                { offset: 1.0, easing: 'step-end', top: '60px' } ],
    398    expected: [ { property: 'left',
    399                  values: [ valueFormat(0, '10px', 'replace', 'ease'),
    400                            valueFormat(0.5, '30px', 'replace', 'linear'),
    401                            valueFormat(1, '50px', 'replace') ] },
    402                { property: 'top',
    403                  values: [ valueFormat(0, '20px', 'replace', 'ease'),
    404                            valueFormat(0.5, '40px', 'replace', 'linear'),
    405                            valueFormat(1, '60px', 'replace') ] } ]
    406  },
    407  { desc:     'a one-property two-keyframe sequence that needs to'
    408              + ' stringify its values',
    409    frames:   [ { offset: 0, opacity: 0 },
    410                { offset: 1, opacity: 1 } ],
    411    expected: [ { property: 'opacity',
    412                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    413                            valueFormat(1, '1', 'replace') ] } ]
    414  },
    415  { desc:     'a keyframe sequence where shorthand precedes longhand',
    416    frames:   [ { offset: 0, margin: '10px', marginRight: '20px' },
    417                { offset: 1, margin: '30px' } ],
    418    expected: [ { property: 'margin-top',
    419                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    420                            valueFormat(1, '30px', 'replace') ] },
    421                { property: 'margin-right',
    422                  values: [ valueFormat(0, '20px', 'replace', 'linear'),
    423                            valueFormat(1, '30px', 'replace') ] },
    424                { property: 'margin-bottom',
    425                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    426                            valueFormat(1, '30px', 'replace') ] },
    427                { property: 'margin-left',
    428                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    429                            valueFormat(1, '30px', 'replace') ] } ]
    430  },
    431  { desc:     'a keyframe sequence where longhand precedes shorthand',
    432    frames:   [ { offset: 0, marginRight: '20px', margin: '10px' },
    433                { offset: 1, margin: '30px' } ],
    434    expected: [ { property: 'margin-top',
    435                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    436                            valueFormat(1, '30px', 'replace') ] },
    437                { property: 'margin-right',
    438                  values: [ valueFormat(0, '20px', 'replace', 'linear'),
    439                            valueFormat(1, '30px', 'replace') ] },
    440                { property: 'margin-bottom',
    441                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    442                            valueFormat(1, '30px', 'replace') ] },
    443                { property: 'margin-left',
    444                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    445                            valueFormat(1, '30px', 'replace') ] } ]
    446  },
    447  { desc:     'a keyframe sequence where lesser shorthand precedes greater'
    448              + ' shorthand',
    449    frames:   [ { offset: 0, borderLeft: '1px solid rgb(1, 2, 3)',
    450                             border: '2px dotted rgb(4, 5, 6)' },
    451                { offset: 1, border: '3px dashed rgb(7, 8, 9)' } ],
    452    expected: [ { property: 'border-bottom-color',
    453                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    454                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    455                { property: 'border-left-color',
    456                  values: [ valueFormat(0, 'rgb(1, 2, 3)', 'replace', 'linear'),
    457                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    458                { property: 'border-right-color',
    459                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    460                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    461                { property: 'border-top-color',
    462                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    463                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    464                { property: 'border-bottom-width',
    465                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    466                            valueFormat(1, '3px', 'replace') ] },
    467                { property: 'border-left-width',
    468                  values: [ valueFormat(0, '1px', 'replace', 'linear'),
    469                            valueFormat(1, '3px', 'replace') ] },
    470                { property: 'border-right-width',
    471                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    472                            valueFormat(1, '3px', 'replace') ] },
    473                { property: 'border-top-width',
    474                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    475                            valueFormat(1, '3px', 'replace') ] },
    476                { property: 'border-bottom-style',
    477                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    478                            valueFormat(1, 'dashed', 'replace') ] },
    479                { property: 'border-left-style',
    480                  values: [ valueFormat(0, 'solid', 'replace', 'linear'),
    481                            valueFormat(1, 'dashed', 'replace') ] },
    482                { property: 'border-right-style',
    483                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    484                            valueFormat(1, 'dashed', 'replace') ] },
    485                { property: 'border-top-style',
    486                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    487                            valueFormat(1, 'dashed', 'replace') ] },
    488                { property: 'border-image-outset',
    489                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    490                            valueFormat(1, '0', 'replace') ] },
    491                { property: 'border-image-repeat',
    492                  values: [ valueFormat(0, 'stretch', 'replace', 'linear'),
    493                            valueFormat(1, 'stretch', 'replace') ] },
    494                { property: 'border-image-slice',
    495                  values: [ valueFormat(0, '100%', 'replace', 'linear'),
    496                            valueFormat(1, '100%', 'replace') ] },
    497                { property: 'border-image-source',
    498                  values: [ valueFormat(0, 'none', 'replace', 'linear'),
    499                            valueFormat(1, 'none', 'replace') ] },
    500                { property: 'border-image-width',
    501                  values: [ valueFormat(0, '1', 'replace', 'linear'),
    502                            valueFormat(1, '1', 'replace') ] },
    503    ]
    504  },
    505  { desc:     'a keyframe sequence where greater shorthand precedes'
    506              + ' lesser shorthand',
    507    frames:   [ { offset: 0, border: '2px dotted rgb(4, 5, 6)',
    508                             borderLeft: '1px solid rgb(1, 2, 3)' },
    509                { offset: 1, border: '3px dashed rgb(7, 8, 9)' } ],
    510    expected: [ { property: 'border-bottom-color',
    511                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    512                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    513                { property: 'border-left-color',
    514                  values: [ valueFormat(0, 'rgb(1, 2, 3)', 'replace', 'linear'),
    515                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    516                { property: 'border-right-color',
    517                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    518                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    519                { property: 'border-top-color',
    520                  values: [ valueFormat(0, 'rgb(4, 5, 6)', 'replace', 'linear'),
    521                            valueFormat(1, 'rgb(7, 8, 9)', 'replace') ] },
    522                { property: 'border-bottom-width',
    523                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    524                            valueFormat(1, '3px', 'replace') ] },
    525                { property: 'border-left-width',
    526                  values: [ valueFormat(0, '1px', 'replace', 'linear'),
    527                            valueFormat(1, '3px', 'replace') ] },
    528                { property: 'border-right-width',
    529                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    530                            valueFormat(1, '3px', 'replace') ] },
    531                { property: 'border-top-width',
    532                  values: [ valueFormat(0, '2px', 'replace', 'linear'),
    533                            valueFormat(1, '3px', 'replace') ] },
    534                { property: 'border-bottom-style',
    535                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    536                            valueFormat(1, 'dashed', 'replace') ] },
    537                { property: 'border-left-style',
    538                  values: [ valueFormat(0, 'solid', 'replace', 'linear'),
    539                            valueFormat(1, 'dashed', 'replace') ] },
    540                { property: 'border-right-style',
    541                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    542                            valueFormat(1, 'dashed', 'replace') ] },
    543                { property: 'border-top-style',
    544                  values: [ valueFormat(0, 'dotted', 'replace', 'linear'),
    545                            valueFormat(1, 'dashed', 'replace') ] },
    546                { property: 'border-image-outset',
    547                  values: [ valueFormat(0, '0', 'replace', 'linear'),
    548                            valueFormat(1, '0', 'replace') ] },
    549                { property: 'border-image-repeat',
    550                  values: [ valueFormat(0, 'stretch', 'replace', 'linear'),
    551                            valueFormat(1, 'stretch', 'replace') ] },
    552                { property: 'border-image-slice',
    553                  values: [ valueFormat(0, '100%', 'replace', 'linear'),
    554                            valueFormat(1, '100%', 'replace') ] },
    555                { property: 'border-image-source',
    556                  values: [ valueFormat(0, 'none', 'replace', 'linear'),
    557                            valueFormat(1, 'none', 'replace') ] },
    558                { property: 'border-image-width',
    559                  values: [ valueFormat(0, '1', 'replace', 'linear'),
    560                            valueFormat(1, '1', 'replace') ] },
    561    ]
    562  },
    563 
    564  // ---------------------------------------------------------------------
    565  //
    566  // Tests for unit conversion
    567  //
    568  // ---------------------------------------------------------------------
    569 
    570  { desc:     'em units are resolved to px values',
    571    frames:   { left: ['10em', '20em'] },
    572    expected: [ { property: 'left',
    573                  values: [ valueFormat(0, '100px', 'replace', 'linear'),
    574                            valueFormat(1, '200px', 'replace') ] } ]
    575  },
    576  { desc:     'calc() expressions are resolved to the equivalent units',
    577    frames:   { left: ['calc(10em + 10px)', 'calc(10em + 10%)'] },
    578    expected: [ { property: 'left',
    579                  values: [ valueFormat(0, '110px', 'replace', 'linear'),
    580                            valueFormat(1, 'calc(10% + 100px)', 'replace') ] } ]
    581  },
    582 
    583  // ---------------------------------------------------------------------
    584  //
    585  // Tests for CSS variable handling conversion
    586  //
    587  // ---------------------------------------------------------------------
    588 
    589  { desc:     'CSS variables are resolved to their corresponding values',
    590    frames:   { left: ['10px', 'var(--var-100px)'] },
    591    expected: [ { property: 'left',
    592                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    593                            valueFormat(1, '100px', 'replace') ] } ]
    594  },
    595  { desc:     'CSS variables in calc() expressions are resolved',
    596    frames:   { left: ['10px', 'calc(var(--var-100px) / 2 - 10%)'] },
    597    expected: [ { property: 'left',
    598                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    599                            valueFormat(1, 'calc(-10% + 50px)', 'replace') ] } ]
    600  },
    601  { desc:     'CSS variables in shorthands are resolved to their corresponding'
    602              + ' values',
    603    frames:   { margin: ['10px', 'var(--var-100px-200px)'] },
    604    expected: [ { property: 'margin-top',
    605                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    606                            valueFormat(1, '100px', 'replace') ] },
    607                { property: 'margin-right',
    608                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    609                            valueFormat(1, '200px', 'replace') ] },
    610                { property: 'margin-bottom',
    611                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    612                            valueFormat(1, '100px', 'replace') ] },
    613                { property: 'margin-left',
    614                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    615                            valueFormat(1, '200px', 'replace') ] } ]
    616  },
    617 
    618  // ---------------------------------------------------------------------
    619  //
    620  // Tests for properties that parse correctly but which we fail to
    621  // convert to computed values.
    622  //
    623  // ---------------------------------------------------------------------
    624 
    625  { desc:     'a missing property in initial keyframe',
    626    frames:   [ { },
    627                { margin: '5px' } ],
    628    expected: [ { property: 'margin-top',
    629                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    630                            valueFormat(1, '5px', 'replace') ] },
    631                { property: 'margin-right',
    632                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    633                            valueFormat(1, '5px', 'replace') ] },
    634                { property: 'margin-bottom',
    635                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    636                            valueFormat(1, '5px', 'replace') ] },
    637                { property: 'margin-left',
    638                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    639                            valueFormat(1, '5px', 'replace') ] } ]
    640  },
    641  { desc:     'a missing property in initial keyframe and there are some ' +
    642              'keyframes with the same offset',
    643    frames:   [ { },
    644                { margin: '10px', offset: 0.5 },
    645                { margin: '20px', offset: 0.5 },
    646                { margin: '30px'} ],
    647    expected: [ { property: 'margin-top',
    648                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    649                            valueFormat(0.5, '10px',  'replace'),
    650                            valueFormat(0.5, '20px',  'replace', 'linear'),
    651                            valueFormat(1,   '30px',  'replace') ] },
    652                { property: 'margin-right',
    653                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    654                            valueFormat(0.5, '10px',  'replace'),
    655                            valueFormat(0.5, '20px',  'replace', 'linear'),
    656                            valueFormat(1,   '30px',  'replace') ] },
    657                { property: 'margin-bottom',
    658                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    659                            valueFormat(0.5, '10px',  'replace'),
    660                            valueFormat(0.5, '20px',  'replace', 'linear'),
    661                            valueFormat(1,   '30px',  'replace') ] },
    662                { property: 'margin-left',
    663                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    664                            valueFormat(0.5, '10px',  'replace'),
    665                            valueFormat(0.5, '20px',  'replace', 'linear'),
    666                            valueFormat(1,   '30px',  'replace') ] } ]
    667  },
    668  { desc:     'a missing property in final keyframe',
    669    frames:   [ { margin: '5px' },
    670                { } ],
    671    expected: [ { property: 'margin-top',
    672                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    673                            valueFormat(1, undefined, 'replace') ] },
    674                { property: 'margin-right',
    675                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    676                            valueFormat(1, undefined, 'replace') ] },
    677                { property: 'margin-bottom',
    678                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    679                            valueFormat(1, undefined, 'replace') ] },
    680                { property: 'margin-left',
    681                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    682                            valueFormat(1, undefined, 'replace') ] } ]
    683  },
    684  { desc:     'a missing property in final keyframe and there are some ' +
    685              'keyframes with the same offsets',
    686    frames:   [ { margin: '5px' },
    687                { margin: '10px', offset: 0.5 },
    688                { margin: '20px', offset: 0.5 },
    689                { } ],
    690    expected: [ { property: 'margin-top',
    691                  values: [ valueFormat(0,   '5px', 'replace', 'linear'),
    692                            valueFormat(0.5, '10px', 'replace'),
    693                            valueFormat(0.5, '20px', 'replace', 'linear'),
    694                            valueFormat(1,   undefined, 'replace') ] },
    695                { property: 'margin-right',
    696                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    697                            valueFormat(0.5, '10px', 'replace'),
    698                            valueFormat(0.5, '20px', 'replace', 'linear'),
    699                            valueFormat(1, undefined, 'replace') ] },
    700                { property: 'margin-bottom',
    701                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    702                            valueFormat(0.5, '10px', 'replace'),
    703                            valueFormat(0.5, '20px', 'replace', 'linear'),
    704                            valueFormat(1, undefined, 'replace') ] },
    705                { property: 'margin-left',
    706                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    707                            valueFormat(0.5, '10px', 'replace'),
    708                            valueFormat(0.5, '20px', 'replace', 'linear'),
    709                            valueFormat(1, undefined, 'replace') ] } ]
    710  },
    711  { desc:     'a missing property in final keyframe where it forms the last'
    712              + ' segment in the series',
    713    frames:   [ { margin: '5px' },
    714                { marginLeft: '5px',
    715                  marginRight: '5px',
    716                  marginBottom: '5px' } ],
    717    expected: [ { property: 'margin-bottom',
    718                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    719                            valueFormat(1, '5px', 'replace') ] },
    720                { property: 'margin-left',
    721                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    722                            valueFormat(1, '5px', 'replace') ] },
    723                { property: 'margin-right',
    724                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    725                            valueFormat(1, '5px', 'replace') ] },
    726                { property: 'margin-top',
    727                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    728                            valueFormat(1, undefined, 'replace') ] } ]
    729  },
    730  { desc:     'a missing property in initial keyframe along with other values',
    731    frames:   [ {                left: '10px' },
    732                { margin: '5px', left: '20px' } ],
    733    expected: [ { property: 'left',
    734                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    735                            valueFormat(1, '20px', 'replace') ] },
    736                { property: 'margin-top',
    737                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    738                            valueFormat(1, '5px', 'replace') ] },
    739                { property: 'margin-right',
    740                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    741                            valueFormat(1, '5px', 'replace') ] },
    742                { property: 'margin-bottom',
    743                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    744                            valueFormat(1, '5px', 'replace') ] },
    745                { property: 'margin-left',
    746                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    747                            valueFormat(1, '5px', 'replace') ] } ]
    748  },
    749  { desc:     'a missing property in final keyframe along with other values',
    750    frames:   [ { margin: '5px', left: '10px' },
    751                {                left: '20px' } ],
    752    expected: [ { property: 'left',
    753                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    754                            valueFormat(1, '20px', 'replace') ] },
    755                { property: 'margin-top',
    756                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    757                            valueFormat(1, undefined, 'replace') ] },
    758                { property: 'margin-right',
    759                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    760                            valueFormat(1, undefined, 'replace') ] },
    761                { property: 'margin-bottom',
    762                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    763                            valueFormat(1, undefined, 'replace') ] },
    764                { property: 'margin-left',
    765                  values: [ valueFormat(0, '5px', 'replace', 'linear'),
    766                            valueFormat(1, undefined, 'replace') ] } ]
    767  },
    768  { desc:     'missing properties in both of initial and final keyframe',
    769    frames:   [ { left: '5px', offset: 0.5 } ],
    770    expected: [ { property: 'left',
    771                  values: [ valueFormat(0,   undefined, 'replace', 'linear'),
    772                            valueFormat(0.5, '5px',     'replace', 'linear'),
    773                            valueFormat(1,   undefined, 'replace') ] } ]
    774  },
    775  { desc:     'missing propertes in both of initial and final keyframe along '
    776              + 'with other values',
    777    frames:   [ { left:  '5px',  offset: 0 },
    778                { right: '5px',  offset: 0.5 },
    779                { left:  '10px', offset: 1 } ],
    780    expected: [ { property: 'left',
    781                  values: [ valueFormat(0, '5px',  'replace', 'linear'),
    782                            valueFormat(1, '10px', 'replace') ] },
    783                { property: 'right',
    784                  values: [ valueFormat(0,   undefined, 'replace', 'linear'),
    785                            valueFormat(0.5, '5px',     'replace', 'linear'),
    786                            valueFormat(1,   undefined, 'replace') ] } ]
    787  },
    788 
    789  { desc:     'a missing property in final keyframe with duplicate offset ' +
    790              + 'along with other values',
    791    frames:   [ { left: '5px',  right: '5px', offset: 0 },
    792                { left: '8px',  right: '8px', offset: 0 },
    793                { left: '10px',               offset: 1 } ],
    794    expected: [ { property: 'left',
    795                  values: [ valueFormat(0, '5px',  'replace'),
    796                            valueFormat(0, '8px',  'replace', 'linear'),
    797                            valueFormat(1, '10px', 'replace') ] },
    798                { property: 'right',
    799                  values: [ valueFormat(0, '5px',     'replace'),
    800                            valueFormat(0, '8px',     'replace', 'linear'),
    801                            valueFormat(1, undefined, 'replace') ] } ]
    802  },
    803 
    804  { desc:     'a missing property in initial keyframe with duplicate offset '
    805              + 'along with other values',
    806    frames:   [ { left: '10px',              offset: 0 },
    807                { left: '8px', right: '8px', offset: 1 },
    808                { left: '5px', right: '5px', offset: 1 } ],
    809    expected: [ { property: 'left',
    810                  values: [ valueFormat(0, '10px', 'replace', 'linear'),
    811                            valueFormat(1, '8px',  'replace'),
    812                            valueFormat(1, '5px',  'replace') ] },
    813                { property: 'right',
    814                  values: [ valueFormat(0, undefined, 'replace', 'linear'),
    815                            valueFormat(1, '8px',     'replace'),
    816                            valueFormat(1, '5px',     'replace') ] } ]
    817  },
    818 ];
    819 
    820 gTests.forEach(function(subtest) {
    821  test(function(t) {
    822    var div = addDiv(t);
    823    var animation = div.animate(subtest.frames, 100 * MS_PER_SEC);
    824    // Flush styles since getProperties currently does not. Rather, it
    825    // returns the actual properties in use at the current time.
    826    // However, we want to test what these properties will look like
    827    // after the next restyle.
    828    getComputedStyle(div).opacity;
    829    assert_properties_equal(
    830      animation.effect.getProperties(),
    831      subtest.expected
    832    );
    833  }, subtest.desc);
    834 });
    835 
    836 </script>
    837 </body>