tor-browser

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

helper_interrupted_reflow.html (22194B)


      1 <!DOCTYPE html>
      2 <html>
      3 <!--
      4 https://bugzilla.mozilla.org/show_bug.cgi?id=1292781
      5 -->
      6 <head>
      7  <title>Test for bug 1292781</title>
      8  <script src="/tests/SimpleTest/EventUtils.js"></script>
      9  <script src="/tests/SimpleTest/paint_listener.js"></script>
     10  <script type="application/javascript" src="apz_test_utils.js"></script>
     11  <script type="application/javascript" src="apz_test_native_event_utils.js"></script>
     12  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
     13  <style>
     14    .outer {
     15        height: 400px;
     16        width: 415px;
     17        overflow: hidden;
     18        position: relative;
     19    }
     20    .inner {
     21        height: 100%;
     22        outline: none;
     23        overflow-x: hidden;
     24        overflow-y: scroll;
     25        position: relative;
     26    }
     27    .inner div:nth-child(even) {
     28        background-color: lightblue;
     29    }
     30    .inner div:nth-child(odd) {
     31        background-color: lightgreen;
     32    }
     33    .outer.contentBefore::before {
     34        top: 0;
     35        content: '';
     36        display: block;
     37        height: 2px;
     38        position: absolute;
     39        width: 100%;
     40        z-index: 99;
     41    }
     42  </style>
     43 </head>
     44 <body>
     45 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1292781">Mozilla Bug 1292781</a>
     46 <p id="display"></p>
     47 <div id="content">
     48 <p>The frame reconstruction should not leave this scrollframe in a bad state</p>
     49 <div class="outer">
     50  <div class="inner">
     51    this is the top of the scrollframe.
     52    <div>this is a box</div>
     53    <div>this is a box</div>
     54    <div>this is a box</div>
     55    <div>this is a box</div>
     56    this is near the top of the scrollframe.
     57    <div>this is a box</div>
     58    <div>this is a box</div>
     59    <div>this is a box</div>
     60    <div>this is a box</div>
     61    <div>this is a box</div>
     62    <div>this is a box</div>
     63    <div>this is a box</div>
     64    <div>this is a box</div>
     65    <div>this is a box</div>
     66    <div>this is a box</div>
     67    <div>this is a box</div>
     68    <div>this is a box</div>
     69    <div>this is a box</div>
     70    <div>this is a box</div>
     71    <div>this is a box</div>
     72    <div>this is a box</div>
     73    <div>this is a box</div>
     74    <div>this is a box</div>
     75    <div>this is a box</div>
     76    <div>this is a box</div>
     77    <div>this is a box</div>
     78    <div>this is a box</div>
     79    <div>this is a box</div>
     80    <div>this is a box</div>
     81    <div>this is a box</div>
     82    <div>this is a box</div>
     83    <div>this is a box</div>
     84    <div>this is a box</div>
     85    <div>this is a box</div>
     86    <div>this is a box</div>
     87    <div>this is a box</div>
     88    <div>this is a box</div>
     89    <div>this is a box</div>
     90    <div>this is a box</div>
     91    <div>this is a box</div>
     92    <div>this is a box</div>
     93    <div>this is a box</div>
     94    <div>this is a box</div>
     95    <div>this is a box</div>
     96    <div>this is a box</div>
     97    <div>this is a box</div>
     98    <div>this is a box</div>
     99    <div>this is a box</div>
    100    <div>this is a box</div>
    101    <div>this is a box</div>
    102    <div>this is a box</div>
    103    <div>this is a box</div>
    104    <div>this is a box</div>
    105    <div>this is a box</div>
    106    <div>this is a box</div>
    107    <div>this is a box</div>
    108    <div>this is a box</div>
    109    <div>this is a box</div>
    110    <div>this is a box</div>
    111    <div>this is a box</div>
    112    <div>this is a box</div>
    113    <div>this is a box</div>
    114    <div>this is a box</div>
    115    <div>this is a box</div>
    116    <div>this is a box</div>
    117    <div>this is a box</div>
    118    <div>this is a box</div>
    119    <div>this is a box</div>
    120    <div>this is a box</div>
    121    <div>this is a box</div>
    122    <div>this is a box</div>
    123    <div>this is a box</div>
    124    <div>this is a box</div>
    125    <div>this is a box</div>
    126    <div>this is a box</div>
    127    <div>this is a box</div>
    128    <div>this is a box</div>
    129    <div>this is a box</div>
    130    <div>this is a box</div>
    131    <div>this is a box</div>
    132    <div>this is a box</div>
    133    <div>this is a box</div>
    134    <div>this is a box</div>
    135    <div>this is a box</div>
    136    <div>this is a box</div>
    137    <div>this is a box</div>
    138    <div>this is a box</div>
    139    <div>this is a box</div>
    140    <div>this is a box</div>
    141    <div>this is a box</div>
    142    <div>this is a box</div>
    143    <div>this is a box</div>
    144    <div>this is a box</div>
    145    <div>this is a box</div>
    146    <div>this is a box</div>
    147    <div>this is a box</div>
    148    <div>this is a box</div>
    149    <div>this is a box</div>
    150    <div>this is a box</div>
    151    <div>this is a box</div>
    152    <div>this is a box</div>
    153    <div>this is a box</div>
    154    <div>this is a box</div>
    155    <div>this is a box</div>
    156    <div>this is a box</div>
    157    <div>this is a box</div>
    158    <div>this is a box</div>
    159    <div>this is a box</div>
    160    <div>this is a box</div>
    161    <div>this is a box</div>
    162    <div>this is a box</div>
    163    <div>this is a box</div>
    164    <div>this is a box</div>
    165    <div>this is a box</div>
    166    <div>this is a box</div>
    167    <div>this is a box</div>
    168    <div>this is a box</div>
    169    <div>this is a box</div>
    170    <div>this is a box</div>
    171    <div>this is a box</div>
    172    <div>this is a box</div>
    173    <div>this is a box</div>
    174    <div>this is a box</div>
    175    <div>this is a box</div>
    176    <div>this is a box</div>
    177    <div>this is a box</div>
    178    <div>this is a box</div>
    179    <div>this is a box</div>
    180    <div>this is a box</div>
    181    <div>this is a box</div>
    182    <div>this is a box</div>
    183    <div>this is a box</div>
    184    <div>this is a box</div>
    185    <div>this is a box</div>
    186    <div>this is a box</div>
    187    <div>this is a box</div>
    188    <div>this is a box</div>
    189    <div>this is a box</div>
    190    <div>this is a box</div>
    191    <div>this is a box</div>
    192    <div>this is a box</div>
    193    <div>this is a box</div>
    194    <div>this is a box</div>
    195    <div>this is a box</div>
    196    <div>this is a box</div>
    197    <div>this is a box</div>
    198    <div>this is a box</div>
    199    <div>this is a box</div>
    200    <div>this is a box</div>
    201    <div>this is a box</div>
    202    <div>this is a box</div>
    203    <div>this is a box</div>
    204    <div>this is a box</div>
    205    <div>this is a box</div>
    206    <div>this is a box</div>
    207    <div>this is a box</div>
    208    <div>this is a box</div>
    209    <div>this is a box</div>
    210    <div>this is a box</div>
    211    <div>this is a box</div>
    212    <div>this is a box</div>
    213    <div>this is a box</div>
    214    <div>this is a box</div>
    215    <div>this is a box</div>
    216    <div>this is a box</div>
    217    <div>this is a box</div>
    218    <div>this is a box</div>
    219    <div>this is a box</div>
    220    <div>this is a box</div>
    221    <div>this is a box</div>
    222    <div>this is a box</div>
    223    <div>this is a box</div>
    224    <div>this is a box</div>
    225    <div>this is a box</div>
    226    <div>this is a box</div>
    227    <div>this is a box</div>
    228    <div>this is a box</div>
    229    <div>this is a box</div>
    230    <div>this is a box</div>
    231    <div>this is a box</div>
    232    <div>this is a box</div>
    233    <div>this is a box</div>
    234    <div>this is a box</div>
    235    <div>this is a box</div>
    236    <div>this is a box</div>
    237    <div>this is a box</div>
    238    <div>this is a box</div>
    239    <div>this is a box</div>
    240    <div>this is a box</div>
    241    <div>this is a box</div>
    242    <div>this is a box</div>
    243    <div>this is a box</div>
    244    <div>this is a box</div>
    245    <div>this is a box</div>
    246    <div>this is a box</div>
    247    <div>this is a box</div>
    248    <div>this is a box</div>
    249    <div>this is a box</div>
    250    <div>this is a box</div>
    251    <div>this is a box</div>
    252    <div>this is a box</div>
    253    <div>this is a box</div>
    254    <div>this is a box</div>
    255    <div>this is a box</div>
    256    <div>this is a box</div>
    257    <div>this is a box</div>
    258    <div>this is a box</div>
    259    <div>this is a box</div>
    260    <div>this is a box</div>
    261    <div>this is a box</div>
    262    <div>this is a box</div>
    263    <div>this is a box</div>
    264    <div>this is a box</div>
    265    <div>this is a box</div>
    266    <div>this is a box</div>
    267    <div>this is a box</div>
    268    <div>this is a box</div>
    269    <div>this is a box</div>
    270    <div>this is a box</div>
    271    <div>this is a box</div>
    272    <div>this is a box</div>
    273    <div>this is a box</div>
    274    <div>this is a box</div>
    275    <div>this is a box</div>
    276    <div>this is a box</div>
    277    <div>this is a box</div>
    278    <div>this is a box</div>
    279    <div>this is a box</div>
    280    <div>this is a box</div>
    281    <div>this is a box</div>
    282    <div>this is a box</div>
    283    <div>this is a box</div>
    284    <div>this is a box</div>
    285    <div>this is a box</div>
    286    <div>this is a box</div>
    287    <div>this is a box</div>
    288    <div>this is a box</div>
    289    <div>this is a box</div>
    290    <div>this is a box</div>
    291    <div>this is a box</div>
    292    <div>this is a box</div>
    293    <div>this is a box</div>
    294    <div>this is a box</div>
    295    <div>this is a box</div>
    296    <div>this is a box</div>
    297    <div>this is a box</div>
    298    <div>this is a box</div>
    299    <div>this is a box</div>
    300    <div>this is a box</div>
    301    <div>this is a box</div>
    302    <div>this is a box</div>
    303    <div>this is a box</div>
    304    <div>this is a box</div>
    305    <div>this is a box</div>
    306    <div>this is a box</div>
    307    <div>this is a box</div>
    308    <div>this is a box</div>
    309    <div>this is a box</div>
    310    <div>this is a box</div>
    311    <div>this is a box</div>
    312    <div>this is a box</div>
    313    <div>this is a box</div>
    314    <div>this is a box</div>
    315    <div>this is a box</div>
    316    <div>this is a box</div>
    317    <div>this is a box</div>
    318    <div>this is a box</div>
    319    <div>this is a box</div>
    320    <div>this is a box</div>
    321    <div>this is a box</div>
    322    <div>this is a box</div>
    323    <div>this is a box</div>
    324    <div>this is a box</div>
    325    <div>this is a box</div>
    326    <div>this is a box</div>
    327    <div>this is a box</div>
    328    <div>this is a box</div>
    329    <div>this is a box</div>
    330    <div>this is a box</div>
    331    <div>this is a box</div>
    332    <div>this is a box</div>
    333    <div>this is a box</div>
    334    <div>this is a box</div>
    335    <div>this is a box</div>
    336    <div>this is a box</div>
    337    <div>this is a box</div>
    338    <div>this is a box</div>
    339    <div>this is a box</div>
    340    <div>this is a box</div>
    341    <div>this is a box</div>
    342    <div>this is a box</div>
    343    <div>this is a box</div>
    344    <div>this is a box</div>
    345    <div>this is a box</div>
    346    <div>this is a box</div>
    347    <div>this is a box</div>
    348    <div>this is a box</div>
    349    <div>this is a box</div>
    350    <div>this is a box</div>
    351    <div>this is a box</div>
    352    <div>this is a box</div>
    353    <div>this is a box</div>
    354    <div>this is a box</div>
    355    <div>this is a box</div>
    356    <div>this is a box</div>
    357    <div>this is a box</div>
    358    <div>this is a box</div>
    359    <div>this is a box</div>
    360    <div>this is a box</div>
    361    <div>this is a box</div>
    362    <div>this is a box</div>
    363    <div>this is a box</div>
    364    <div>this is a box</div>
    365    <div>this is a box</div>
    366    <div>this is a box</div>
    367    <div>this is a box</div>
    368    <div>this is a box</div>
    369    <div>this is a box</div>
    370    <div>this is a box</div>
    371    <div>this is a box</div>
    372    <div>this is a box</div>
    373    <div>this is a box</div>
    374    <div>this is a box</div>
    375    <div>this is a box</div>
    376    <div>this is a box</div>
    377    <div>this is a box</div>
    378    <div>this is a box</div>
    379    <div>this is a box</div>
    380    <div>this is a box</div>
    381    <div>this is a box</div>
    382    <div>this is a box</div>
    383    <div>this is a box</div>
    384    <div>this is a box</div>
    385    <div>this is a box</div>
    386    <div>this is a box</div>
    387    <div>this is a box</div>
    388    <div>this is a box</div>
    389    <div>this is a box</div>
    390    <div>this is a box</div>
    391    <div>this is a box</div>
    392    <div>this is a box</div>
    393    <div>this is a box</div>
    394    <div>this is a box</div>
    395    <div>this is a box</div>
    396    <div>this is a box</div>
    397    <div>this is a box</div>
    398    <div>this is a box</div>
    399    <div>this is a box</div>
    400    <div>this is a box</div>
    401    <div>this is a box</div>
    402    <div>this is a box</div>
    403    <div>this is a box</div>
    404    <div>this is a box</div>
    405    <div>this is a box</div>
    406    <div>this is a box</div>
    407    <div>this is a box</div>
    408    <div>this is a box</div>
    409    <div>this is a box</div>
    410    <div>this is a box</div>
    411    <div>this is a box</div>
    412    <div>this is a box</div>
    413    <div>this is a box</div>
    414    <div>this is a box</div>
    415    <div>this is a box</div>
    416    <div>this is a box</div>
    417    <div>this is a box</div>
    418    <div>this is a box</div>
    419    <div>this is a box</div>
    420    <div>this is a box</div>
    421    <div>this is a box</div>
    422    <div>this is a box</div>
    423    <div>this is a box</div>
    424    <div>this is a box</div>
    425    <div>this is a box</div>
    426    <div>this is a box</div>
    427    <div>this is a box</div>
    428    <div>this is a box</div>
    429    <div>this is a box</div>
    430    <div>this is a box</div>
    431    <div>this is a box</div>
    432    <div>this is a box</div>
    433    <div>this is a box</div>
    434    <div>this is a box</div>
    435    <div>this is a box</div>
    436    <div>this is a box</div>
    437    <div>this is a box</div>
    438    <div>this is a box</div>
    439    <div>this is a box</div>
    440    <div>this is a box</div>
    441    <div>this is a box</div>
    442    <div>this is a box</div>
    443    <div>this is a box</div>
    444    <div>this is a box</div>
    445    <div>this is a box</div>
    446    <div>this is a box</div>
    447    <div>this is a box</div>
    448    <div>this is a box</div>
    449    <div>this is a box</div>
    450    <div>this is a box</div>
    451    <div>this is a box</div>
    452    <div>this is a box</div>
    453    <div>this is a box</div>
    454    <div>this is a box</div>
    455    <div>this is a box</div>
    456    <div>this is a box</div>
    457    <div>this is a box</div>
    458    <div>this is a box</div>
    459    <div>this is a box</div>
    460    <div>this is a box</div>
    461    <div>this is a box</div>
    462    <div>this is a box</div>
    463    <div>this is a box</div>
    464    <div>this is a box</div>
    465    <div>this is a box</div>
    466    <div>this is a box</div>
    467    <div>this is a box</div>
    468    <div>this is a box</div>
    469    <div>this is a box</div>
    470    <div>this is a box</div>
    471    <div>this is a box</div>
    472    <div>this is a box</div>
    473    <div>this is a box</div>
    474    <div>this is a box</div>
    475    <div>this is a box</div>
    476    <div>this is a box</div>
    477    <div>this is a box</div>
    478    <div>this is a box</div>
    479    <div>this is a box</div>
    480    <div>this is a box</div>
    481    <div>this is a box</div>
    482    <div>this is a box</div>
    483    <div>this is a box</div>
    484    <div>this is a box</div>
    485    <div>this is a box</div>
    486    <div>this is a box</div>
    487    <div>this is a box</div>
    488    <div>this is a box</div>
    489    <div>this is a box</div>
    490    <div>this is a box</div>
    491    <div>this is a box</div>
    492    <div>this is a box</div>
    493    <div>this is a box</div>
    494    <div>this is a box</div>
    495    <div>this is a box</div>
    496    <div>this is a box</div>
    497    <div>this is a box</div>
    498    <div>this is a box</div>
    499    <div>this is a box</div>
    500    <div>this is a box</div>
    501    <div>this is a box</div>
    502    <div>this is a box</div>
    503    <div>this is a box</div>
    504    <div>this is a box</div>
    505    <div>this is a box</div>
    506    <div>this is a box</div>
    507    <div>this is a box</div>
    508    <div>this is a box</div>
    509    <div>this is a box</div>
    510    <div>this is a box</div>
    511    <div>this is a box</div>
    512    <div>this is a box</div>
    513    <div>this is a box</div>
    514    <div>this is a box</div>
    515    <div>this is a box</div>
    516    <div>this is a box</div>
    517    <div>this is a box</div>
    518    <div>this is a box</div>
    519    <div>this is a box</div>
    520    <div>this is a box</div>
    521    <div>this is a box</div>
    522    <div>this is a box</div>
    523    <div>this is a box</div>
    524    <div>this is a box</div>
    525    <div>this is a box</div>
    526    <div>this is a box</div>
    527    <div>this is a box</div>
    528    <div>this is a box</div>
    529    <div>this is a box</div>
    530    <div>this is a box</div>
    531    <div>this is a box</div>
    532    <div>this is a box</div>
    533    <div>this is a box</div>
    534    <div>this is a box</div>
    535    <div>this is a box</div>
    536    <div>this is a box</div>
    537    <div>this is a box</div>
    538    <div>this is a box</div>
    539    <div>this is a box</div>
    540    <div>this is a box</div>
    541    <div>this is a box</div>
    542    <div>this is a box</div>
    543    <div>this is a box</div>
    544    <div>this is a box</div>
    545    <div>this is a box</div>
    546    <div>this is a box</div>
    547    <div>this is a box</div>
    548    <div>this is a box</div>
    549    this is near the bottom of the scrollframe.
    550    <div>this is a box</div>
    551    <div>this is a box</div>
    552    <div>this is a box</div>
    553    <div>this is a box</div>
    554    <div>this is a box</div>
    555    this is the bottom of the scrollframe.
    556  </div>
    557 </div>
    558 </div>
    559 
    560 <pre id="test">
    561 <script type="text/javascript">
    562 
    563 const is = window.opener.is;
    564 const ok = window.opener.ok;
    565 const SimpleTest = window.opener.SimpleTest;
    566 
    567 // Returns a list of async scroll offsets that the |inner| element had, one for
    568 // each paint.
    569 function getAsyncScrollOffsets(aPaintsToIgnore) {
    570  var offsets = [];
    571  var compositorTestData = SpecialPowers.getDOMWindowUtils(window).getCompositorAPZTestData();
    572  var buckets = compositorTestData.paints.slice(aPaintsToIgnore);
    573  ok(buckets.length >= 3, "Expected at least three paints in the compositor test data");
    574  var childIsLayerized = false;
    575  for (var i = 0; i < buckets.length; ++i) {
    576    var apzcTree = buildApzcTree(convertScrollFrameData(buckets[i].scrollFrames));
    577    var rcd = findRcdNode(apzcTree);
    578    if (rcd == null) {
    579      continue;
    580    }
    581    if (rcd.children.length) {
    582      // The child may not be layerized in the first few paints, but once it is
    583      // layerized, it should stay layerized.
    584      childIsLayerized = true;
    585    }
    586    if (!childIsLayerized) {
    587      continue;
    588    }
    589 
    590    ok(rcd.children.length == 1, "Root content APZC has exactly one child");
    591    offsets.push(parsePoint(rcd.children[0].asyncScrollOffset));
    592  }
    593  return offsets;
    594 }
    595 
    596 async function test() {
    597  var utils = SpecialPowers.DOMWindowUtils;
    598 
    599  // The APZ test data accumulates whenever a test turns it on. We just want
    600  // the data for this test, so we check how many frames are already recorded
    601  // and discard those later.
    602  var framesToSkip = SpecialPowers.getDOMWindowUtils(window).getCompositorAPZTestData().paints.length;
    603 
    604  var elm = document.getElementsByClassName("inner")[0];
    605  // Set a zero-margin displayport to ensure that the element is async-scrollable
    606  // otherwise on Fennec it is not
    607  utils.setDisplayPortMarginsForElement(0, 0, 0, 0, elm, 0);
    608 
    609  var maxScroll = elm.scrollTopMax;
    610  elm.scrollTop = maxScroll;
    611  await promiseAllPaintsDone();
    612  await promiseOnlyApzControllerFlushed();
    613 
    614  // Take control of the refresh driver
    615  utils.advanceTimeAndRefresh(0);
    616 
    617  // Force the next reflow to get interrupted
    618  utils.forceReflowInterrupt();
    619 
    620  // Make a change that triggers frame reconstruction, and then tick the refresh
    621  // driver so that layout processes the pending restyles and then runs an
    622  // interruptible reflow. That reflow *will* be interrupted (because of the flag
    623  // we set above), and we should end up with a transient 0,0 scroll offset
    624  // being sent to the compositor.
    625  elm.parentNode.classList.add("contentBefore");
    626  utils.advanceTimeAndRefresh(0);
    627  // On android, and maybe non-e10s platforms generally, we need to manually
    628  // kick the paint to send the layer transaction to the compositor.
    629  await promiseAllPaintsDone();
    630 
    631  // Read the main-thread scroll offset; although this is temporarily 0,0 that
    632  // temporary value is never exposed to content - instead reading this value
    633  // will finish doing the interrupted reflow from above and then report the
    634  // correct scroll offset.
    635  is(elm.scrollTop, maxScroll, "Main-thread scroll position was restored");
    636 
    637  // .. and now flush everything to make sure the state gets pushed over to the
    638  // compositor and APZ as well.
    639  utils.restoreNormalRefresh();
    640  await promiseApzFlushedRepaints();
    641 
    642  // Now we pull the compositor data and check it. What we expect to see is that
    643  // the scroll position goes to maxScroll, then drops to 0 and then goes back
    644  // to maxScroll. This test is specifically testing that last bit - that it
    645  // properly gets restored from 0 to maxScroll.
    646  // The one hitch is that on Android this page is loaded with some amount of
    647  // zoom, and the async scroll is in ParentLayerPixel coordinates, so it will
    648  // not match maxScroll exactly. Since we can't reliably compute what that
    649  // ParentLayer scroll will be, we just make sure the async scroll is nonzero
    650  // and use the first value we encounter to verify that it got restored properly.
    651  // The other alternative is to spawn this test into a new window with 1.0 zoom
    652  // but I'm tired of doing that for pretty much every test.
    653  var state = 0;
    654  var asyncScrollOffsets = getAsyncScrollOffsets(framesToSkip);
    655  dump("Got scroll offsets: " + JSON.stringify(asyncScrollOffsets) + "\n");
    656  var maxScrollParentLayerPixels = maxScroll;
    657  while (asyncScrollOffsets.length) {
    658    let offset = asyncScrollOffsets.shift();
    659    switch (state) {
    660      // 0 is the initial state, the scroll offset might be zero but should
    661      // become non-zero from when we set scrollTop to scrollTopMax
    662      case 0:
    663        if (offset.y == 0) {
    664          break;
    665        }
    666        if (getPlatform() == "android") {
    667          ok(offset.y > 0, "Async scroll y of scrollframe is " + offset.y);
    668          maxScrollParentLayerPixels = offset.y;
    669        } else {
    670          is(offset.y, maxScrollParentLayerPixels, "Async scroll y of scrollframe is " + offset.y);
    671        }
    672        state = 1;
    673        break;
    674 
    675      // state 1 starts out at maxScrollParentLayerPixels, should drop to 0
    676      // because of the interrupted reflow putting the scroll into a transient
    677      // zero state
    678      case 1:
    679        if (offset.y == maxScrollParentLayerPixels) {
    680          break;
    681        }
    682        is(offset.y, 0, "Async scroll position was temporarily 0");
    683        state = 2;
    684        break;
    685 
    686      // state 2 starts out the transient 0 scroll offset, and we expect the
    687      // scroll position to get restored back to maxScrollParentLayerPixels
    688      case 2:
    689        if (offset.y == 0) {
    690          break;
    691        }
    692        is(offset.y, maxScrollParentLayerPixels, "Async scroll y of scrollframe restored to " + offset.y);
    693        state = 3;
    694        break;
    695 
    696      // Terminal state. The scroll position should stay at maxScrollParentLayerPixels
    697      case 3:
    698        is(offset.y, maxScrollParentLayerPixels, "Scroll position maintained");
    699        break;
    700    }
    701  }
    702  is(state, 3, "The scroll position did drop to 0 and then get restored properly");
    703 
    704  window.opener.finishTest();
    705 }
    706 
    707 waitUntilApzStable()
    708 .then(async () => test());
    709 
    710 </script>
    711 </body>
    712 </html>