tor-browser

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

check-layout-th.js (10265B)


      1 (function() {
      2 // Test is initiated from body.onload, so explicit done() call is required.
      3 setup({ explicit_done: true });
      4 
      5 function checkSubtreeExpectedValues(t, parent, prefix)
      6 {
      7    var checkedLayout = checkExpectedValues(t, parent, prefix);
      8    Array.prototype.forEach.call(parent.childNodes, function(node) {
      9        checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
     10    });
     11    return checkedLayout;
     12 }
     13 
     14 function checkAttribute(output, node, attribute)
     15 {
     16    var result = node.getAttribute && node.getAttribute(attribute);
     17    output.checked |= !!result;
     18    return result;
     19 }
     20 
     21 function assert_tolerance(actual, expected, message)
     22 {
     23    if (isNaN(expected) || isNaN(actual) || Math.abs(actual - expected) >= 1) {
     24        assert_equals(actual, Number(expected), message);
     25    }
     26 }
     27 
     28 function checkDataKeys(node) {
     29  // The purpose of this list of data-* attributes is simply to ensure typos
     30  // in tests are caught. It is therefore "ok" to add to this list for
     31  // specific tests.
     32    var validData = new Set([
     33        "data-anchor-polyfill",
     34        "data-expected-width",
     35        "data-expected-height",
     36        "data-offset-x",
     37        "data-offset-y",
     38        "data-expected-client-width",
     39        "data-expected-client-height",
     40        "data-expected-scroll-width",
     41        "data-expected-scroll-height",
     42        "data-expected-bounding-client-rect-width",
     43        "data-expected-bounding-client-rect-height",
     44        "data-total-x",
     45        "data-total-y",
     46        "data-expected-display",
     47        "data-expected-padding-top",
     48        "data-expected-padding-bottom",
     49        "data-expected-padding-left",
     50        "data-expected-padding-right",
     51        "data-expected-margin-top",
     52        "data-expected-margin-bottom",
     53        "data-expected-margin-left",
     54        "data-expected-margin-right"
     55    ]);
     56    if (!node || !node.getAttributeNames)
     57        return;
     58    // Use "data-test" prefix if you need custom-named data elements.
     59    for (let name of node.getAttributeNames()) {
     60        if (name.startsWith("data-") && !name.startsWith("data-test"))
     61            assert_true(validData.has(name), name + " is a valid data attribute");
     62    }
     63 }
     64 
     65 function checkExpectedValues(t, node, prefix)
     66 {
     67    checkDataKeys(node);
     68    var output = { checked: false };
     69 
     70    var expectedWidth = checkAttribute(output, node, "data-expected-width");
     71    if (expectedWidth) {
     72        assert_tolerance(node.offsetWidth, expectedWidth, prefix + "width");
     73    }
     74 
     75    var expectedHeight = checkAttribute(output, node, "data-expected-height");
     76    if (expectedHeight) {
     77        assert_tolerance(node.offsetHeight, expectedHeight, prefix + "height");
     78    }
     79 
     80    var expectedOffset = checkAttribute(output, node, "data-offset-x");
     81    if (expectedOffset) {
     82        assert_tolerance(node.offsetLeft, expectedOffset, prefix + "offsetLeft");
     83    }
     84 
     85    var expectedOffset = checkAttribute(output, node, "data-offset-y");
     86    if (expectedOffset) {
     87        assert_tolerance(node.offsetTop, expectedOffset, prefix + "offsetTop");
     88    }
     89 
     90    var expectedWidth = checkAttribute(output, node, "data-expected-client-width");
     91    if (expectedWidth) {
     92        assert_tolerance(node.clientWidth, expectedWidth, prefix + "clientWidth");
     93    }
     94 
     95    var expectedHeight = checkAttribute(output, node, "data-expected-client-height");
     96    if (expectedHeight) {
     97        assert_tolerance(node.clientHeight, expectedHeight, prefix + "clientHeight");
     98    }
     99 
    100    var expectedWidth = checkAttribute(output, node, "data-expected-scroll-width");
    101    if (expectedWidth) {
    102        assert_tolerance(node.scrollWidth, expectedWidth, prefix + "scrollWidth");
    103    }
    104 
    105    var expectedHeight = checkAttribute(output, node, "data-expected-scroll-height");
    106    if (expectedHeight) {
    107        assert_tolerance(node.scrollHeight, expectedHeight, prefix + "scrollHeight");
    108    }
    109 
    110    var expectedWidth = checkAttribute(output, node, "data-expected-bounding-client-rect-width");
    111    if (expectedWidth) {
    112        assert_tolerance(node.getBoundingClientRect().width, expectedWidth, prefix + "getBoundingClientRect().width");
    113    }
    114 
    115    var expectedHeight = checkAttribute(output, node, "data-expected-bounding-client-rect-height");
    116    if (expectedHeight) {
    117        assert_tolerance(node.getBoundingClientRect().height, expectedHeight, prefix + "getBoundingClientRect().height");
    118    }
    119 
    120    var expectedOffset = checkAttribute(output, node, "data-total-x");
    121    if (expectedOffset) {
    122        var totalLeft = node.clientLeft + node.offsetLeft;
    123        assert_tolerance(totalLeft, expectedOffset, prefix +
    124                         "clientLeft+offsetLeft (" + node.clientLeft + " + " + node.offsetLeft + ")");
    125    }
    126 
    127    var expectedOffset = checkAttribute(output, node, "data-total-y");
    128    if (expectedOffset) {
    129        var totalTop = node.clientTop + node.offsetTop;
    130        assert_tolerance(totalTop, expectedOffset, prefix +
    131                         "clientTop+offsetTop (" + node.clientTop + " + " + node.offsetTop + ")");
    132    }
    133 
    134    var expectedDisplay = checkAttribute(output, node, "data-expected-display");
    135    if (expectedDisplay) {
    136        var actualDisplay = getComputedStyle(node).display;
    137        assert_equals(actualDisplay, expectedDisplay, prefix + "display");
    138    }
    139 
    140    var expectedPaddingTop = checkAttribute(output, node, "data-expected-padding-top");
    141    if (expectedPaddingTop) {
    142        var actualPaddingTop = getComputedStyle(node).paddingTop;
    143        // Trim the unit "px" from the output.
    144        actualPaddingTop = actualPaddingTop.slice(0, -2);
    145        assert_equals(actualPaddingTop, expectedPaddingTop, prefix + "padding-top");
    146    }
    147 
    148    var expectedPaddingBottom = checkAttribute(output, node, "data-expected-padding-bottom");
    149    if (expectedPaddingBottom) {
    150        var actualPaddingBottom = getComputedStyle(node).paddingBottom;
    151        // Trim the unit "px" from the output.
    152        actualPaddingBottom = actualPaddingBottom.slice(0, -2);
    153        assert_equals(actualPaddingBottom, expectedPaddingBottom, prefix + "padding-bottom");
    154    }
    155 
    156    var expectedPaddingLeft = checkAttribute(output, node, "data-expected-padding-left");
    157    if (expectedPaddingLeft) {
    158        var actualPaddingLeft = getComputedStyle(node).paddingLeft;
    159        // Trim the unit "px" from the output.
    160        actualPaddingLeft = actualPaddingLeft.slice(0, -2);
    161        assert_equals(actualPaddingLeft, expectedPaddingLeft, prefix + "padding-left");
    162    }
    163 
    164    var expectedPaddingRight = checkAttribute(output, node, "data-expected-padding-right");
    165    if (expectedPaddingRight) {
    166        var actualPaddingRight = getComputedStyle(node).paddingRight;
    167        // Trim the unit "px" from the output.
    168        actualPaddingRight = actualPaddingRight.slice(0, -2);
    169        assert_equals(actualPaddingRight, expectedPaddingRight, prefix + "padding-right");
    170    }
    171 
    172    var expectedMarginTop = checkAttribute(output, node, "data-expected-margin-top");
    173    if (expectedMarginTop) {
    174        var actualMarginTop = getComputedStyle(node).marginTop;
    175        // Trim the unit "px" from the output.
    176        actualMarginTop = actualMarginTop.slice(0, -2);
    177        assert_equals(actualMarginTop, expectedMarginTop, prefix + "margin-top");
    178    }
    179 
    180    var expectedMarginBottom = checkAttribute(output, node, "data-expected-margin-bottom");
    181    if (expectedMarginBottom) {
    182        var actualMarginBottom = getComputedStyle(node).marginBottom;
    183        // Trim the unit "px" from the output.
    184        actualMarginBottom = actualMarginBottom.slice(0, -2);
    185        assert_equals(actualMarginBottom, expectedMarginBottom, prefix + "margin-bottom");
    186    }
    187 
    188    var expectedMarginLeft = checkAttribute(output, node, "data-expected-margin-left");
    189    if (expectedMarginLeft) {
    190        var actualMarginLeft = getComputedStyle(node).marginLeft;
    191        // Trim the unit "px" from the output.
    192        actualMarginLeft = actualMarginLeft.slice(0, -2);
    193        assert_equals(actualMarginLeft, expectedMarginLeft, prefix + "margin-left");
    194    }
    195 
    196    var expectedMarginRight = checkAttribute(output, node, "data-expected-margin-right");
    197    if (expectedMarginRight) {
    198        var actualMarginRight = getComputedStyle(node).marginRight;
    199        // Trim the unit "px" from the output.
    200        actualMarginRight = actualMarginRight.slice(0, -2);
    201        assert_equals(actualMarginRight, expectedMarginRight, prefix + "margin-right");
    202    }
    203 
    204    return output.checked;
    205 }
    206 
    207 var testNumber = 0;
    208 var highlightError = false; // displays outline around failed test element.
    209 var printDomOnError = true; // prints dom when test fails.
    210 
    211 window.checkLayout = function(selectorList, callDone = true)
    212 {
    213    if (!selectorList) {
    214        console.error("You must provide a CSS selector of nodes to check.");
    215        return;
    216    }
    217    var nodes = document.querySelectorAll(selectorList);
    218    nodes = Array.prototype.slice.call(nodes);
    219    var checkedLayout = false;
    220    Array.prototype.forEach.call(nodes, function(node) {
    221        const title = node.title ? `: ${node.title}` : '';
    222        test(function(t) {
    223            var container = node.parentNode.className == 'container' ? node.parentNode : node;
    224            var prefix =
    225                printDomOnError ? '\n' + container.outerHTML + '\n' : '';
    226            var passed = false;
    227            try {
    228                checkedLayout |= checkExpectedValues(t, node.parentNode, prefix);
    229                checkedLayout |= checkSubtreeExpectedValues(t, node, prefix);
    230                passed = true;
    231            } finally {
    232              if (!passed && highlightError) {
    233                if (!document.getElementById('testharness_error_css')) {
    234                  var style = document.createElement('style');
    235                  style.id = 'testharness_error_css';
    236                  style.textContent = '.testharness_error { outline: red dotted 2px !important; }';
    237                  document.body.appendChild(style);
    238                }
    239                if (node)
    240                  node.classList.add('testharness_error');
    241              }
    242                checkedLayout |= !passed;
    243            }
    244        }, `${selectorList} ${++testNumber}${title}`);
    245    });
    246    if (!checkedLayout) {
    247        console.error("No valid data-* attributes found in selector list : " + selectorList);
    248    }
    249    if (callDone)
    250        done();
    251 };
    252 
    253 })();