Bug 1498368 [wpt PR 13469] - [css-properties-values-api] Avoid viewport dependent tests., a=testonly
☠☠ backed out by 09dd66ffc95a ☠ ☠
authorAnders Hartvoll Ruud <andruud@chromium.org>
Mon, 15 Oct 2018 17:16:16 +0000
changeset 489897 92bf8a8afc4e449ba8e225b4cb57fa1aefde5e13
parent 489896 2ff5ad4582f9969cc97e265d5f992a31a3bf2b2d
child 489898 c6cefa08ec89a993bc3d8a34655d13bf9c192ae3
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewerstestonly
bugs1498368, 13469, 641877, 1275893, 598847
milestone64.0a1
Bug 1498368 [wpt PR 13469] - [css-properties-values-api] Avoid viewport dependent tests., a=testonly Automatic update from web-platform-tests[css-properties-values-api] Avoid viewport dependent tests. The test registered-property-computation.html fails on wpt.fyi, because it assumes that the tests are run in a viewport with specific dimensions. This CL fixes that by using a standard property as a reference. For instance, to figure out the expected value in pixels for '10vw', we compute min-height:10vw and use that result as the expected value. Also added some generally useful utils, and rewrote the test using those utils to make the test more understandable. R=futhark@chromium.org Bug: 641877 Change-Id: Ie1ceb334eefee6e76015447f24148638ad8c55a6 Reviewed-on: https://chromium-review.googlesource.com/c/1275893 Reviewed-by: Rune Lillesveen <futhark@chromium.org> Commit-Queue: Anders Ruud <andruud@chromium.org> Cr-Commit-Position: refs/heads/master@{#598847} -- wpt-commits: 674e8801c0e11fbd489fb065785b2717d6220a9b wpt-pr: 13469
testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
testing/web-platform/tests/css/css-properties-values-api/resources/utils.js
testing/web-platform/tests/css/css-properties-values-api/self-utils.html
--- a/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
+++ b/testing/web-platform/tests/css/css-properties-values-api/registered-property-computation.html
@@ -1,117 +1,115 @@
-<!DOCTYPE HTML>
+<!DOCTYPE html>
 <link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api/#calculation-of-computed-values" />
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="./resources/utils.js"></script>
 
 <style>
 #divWithFontSizeSet, #parentDiv {
     font-size: 10px;
 }
-#divWithFontSizeSet, #divWithFontSizeInherited {
-    --length-1: 12px;
-    --length-2: 13vw;
-    --length-3: 14em;
-    --length-4: 15vmin;
-    --length-5: calc(16px - 7em + 10vh);
-    --length-6: var(--length-3);
-    --length-percentage-1: 17em;
-    --length-percentage-2: 18%;
-    --length-percentage-3: calc(19em - 2%);
-    --csv-1: 10px, 3em;
-    --csv-2: 4em ,9px;
-    --csv-3: 8em;
-    --csv-4: 3% , 10vmax  , 22px;
-    --csv-5: calc(50% + 1em), 4px;
-    --csv-6: calc(13% + 37px);
-    --list-1: 10px 3em;
-    --list-2: 4em 9px;
-    --list-3: 3% 10vmax 22px;
-    --list-4: calc(50% + 1em) 4px;
-    --transform-function-1: translateX(2px);
-    --transform-function-2: translateX(10em);
-    --transform-function-3: translateX(calc(11em + 10%));
-    --transform-function-4: translateX(10%) scale(2);
-}
 </style>
 
 <div id=divWithFontSizeSet></div>
 <div id=parentDiv>
     <div id=divWithFontSizeInherited></div>
 </div>
+<div id="ref"></div>
 
 <script>
-test(() => {
-    CSS.registerProperty({name: '--length-1', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-2', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-3', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-4', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-5', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-6', syntax: '<length>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-percentage-1', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-percentage-2', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--length-percentage-3', syntax: '<length-percentage>', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-1', syntax: '<length>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-2', syntax: '<length>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-3', syntax: '<length>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-4', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-5', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--csv-6', syntax: '<length-percentage>#', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--list-1', syntax: '<length>+', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--list-2', syntax: '<length>+', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--list-3', syntax: '<length-percentage>+', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--list-4', syntax: '<length-percentage>+', initialValue: '0px', inherits: false});
-    CSS.registerProperty({name: '--transform-function-1', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
-    CSS.registerProperty({name: '--transform-function-2', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
-    CSS.registerProperty({name: '--transform-function-3', syntax: '<transform-function>', initialValue: 'translateX(0px)', inherits: false});
-    CSS.registerProperty({name: '--transform-function-4', syntax: '<transform-function>+', initialValue: 'translateX(0px)', inherits: false});
-}, "CSS.registerProperty");
+
+for (let element of [divWithFontSizeSet, divWithFontSizeInherited]) {
+    let id = element.id;
+
+    // Generate a property and temporarily set its value. Then call 'fn' with
+    // the name of the generated property.
+    function with_custom_property(reg, value, fn) {
+        let name = generate_property(reg);
+
+        // Because we want to include the parsing step, insert a stylesheet
+        // node with textContent.
+        let node = document.createElement('style');
+        node.textContent = `#${id} { ${name}: ${value}; }`;
+        document.body.append(node);
+
+        try {
+            fn(name);
+        } finally {
+            node.remove();
+        }
+    }
 
-for (var element of [divWithFontSizeSet, divWithFontSizeInherited]) {
-    var id = element.id;
-    var computedStyle = getComputedStyle(element);
+    function assert_computed_value(syntax, value, expected) {
+        with_custom_property(syntax, value, (name) => {
+            let actual = getComputedStyle(element).getPropertyValue(name);
+            assert_equals(actual, expected);
+        });
+    }
+
+    // Computes an absolute reference value for some length.
+    //
+    // E.g. to figure out how many pixels '10vh' is, do length_ref('10vh').
+    function length_ref(value, refnode = ref) {
+        try {
+            // The reference property 'min-height' is chosen arbitrarily, but
+            // avoid properties with "resolved value is used value"-behavior
+            // [1], as it may affect rounding, and custom properties do not
+            // have this behavior.
+            //
+            // [1] https://drafts.csswg.org/cssom/#resolved-values
+            const ref_property = 'min-height';
+            refnode.style = `${ref_property}: ${value}`;
+            return getComputedStyle(refnode).getPropertyValue(ref_property);
+        } finally {
+            refnode.style = '';
+        }
+    }
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--length-1'), '12px');
-        assert_equals(computedStyle.getPropertyValue('--length-2'), '104px');
-        assert_equals(computedStyle.getPropertyValue('--length-3'), '140px');
-        assert_equals(computedStyle.getPropertyValue('--length-4'), '90px');
-        assert_equals(computedStyle.getPropertyValue('--length-5'), '6px');
-        assert_equals(computedStyle.getPropertyValue('--length-6'), '140px');
+        assert_computed_value('<length>', '12px', '12px');
+        assert_computed_value('<length>', '13vw', length_ref('13vw'));
+        assert_computed_value('<length>', '14em', '140px');
+        assert_computed_value('<length>', '15vmin', length_ref('15vmin'));
+        assert_computed_value('<length>', 'calc(16px - 7em + 10vh)', length_ref('calc(10vh - 54px)'));
+        with_custom_property('<length>', '14em', (name) => {
+            assert_computed_value('<length>', `var(${name})`, '140px');
+        });
     }, "<length> values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--length-percentage-1'), '170px');
-        assert_equals(computedStyle.getPropertyValue('--length-percentage-2'), '18%');
-        assert_equals(computedStyle.getPropertyValue('--length-percentage-3'), 'calc(190px + -2%)');
+        assert_computed_value('<length-percentage>', '17em', '170px');
+        assert_computed_value('<length-percentage>', '18%', '18%');
+        assert_computed_value('<length-percentage>', 'calc(19em - 2%)', 'calc(190px + -2%)');
     }, "<length-percentage> values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--csv-1'), '10px, 30px');
-        assert_equals(computedStyle.getPropertyValue('--csv-2'), '40px, 9px');
-        assert_equals(computedStyle.getPropertyValue('--csv-3'), '80px');
+        assert_computed_value('<length>#', '10px, 3em', '10px, 30px');
+        assert_computed_value('<length>#', '10px, 3em', '10px, 30px');
+        assert_computed_value('<length>#', '4em ,9px', '40px, 9px');
+        assert_computed_value('<length>#', '8em', '80px');
     }, "<length># values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--csv-4'), '3%, 80px, 22px');
-        assert_equals(computedStyle.getPropertyValue('--csv-5'), 'calc(10px + 50%), 4px');
-        assert_equals(computedStyle.getPropertyValue('--csv-6'), 'calc(37px + 13%)');
+        assert_computed_value('<length-percentage>#', '3% , 10vmax  , 22px', ['3%', length_ref('10vmax'), '22px'].join(', '));
+        assert_computed_value('<length-percentage>#', 'calc(50% + 1em), 4px', 'calc(10px + 50%), 4px');
+        assert_computed_value('<length-percentage>#', 'calc(13% + 37px)', 'calc(37px + 13%)');
     }, "<length-percentage># values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--list-1'), '10px 30px');
-        assert_equals(computedStyle.getPropertyValue('--list-2'), '40px 9px');
+        assert_computed_value('<length>+', '10px 3em', '10px 30px');
+        assert_computed_value('<length>+', '4em 9px', '40px 9px');
     }, "<length>+ values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--list-3'), '3% 80px 22px');
-        assert_equals(computedStyle.getPropertyValue('--list-4'), 'calc(10px + 50%) 4px');
+        assert_computed_value('<length-percentage>+', '3% 10vmax 22px', ['3%', length_ref('10vmax'), '22px'].join(' '));
+        assert_computed_value('<length-percentage>+', 'calc(50% + 1em) 4px', 'calc(10px + 50%) 4px');
     }, "<length-percentage>+ values are computed correctly for " + id);
 
     test(function() {
-        assert_equals(computedStyle.getPropertyValue('--transform-function-1'), 'translateX(2px)');
-        assert_equals(computedStyle.getPropertyValue('--transform-function-2'), 'translateX(100px)');
-        assert_equals(computedStyle.getPropertyValue('--transform-function-3'), 'translateX(calc(110px + 10%))');
-        assert_equals(computedStyle.getPropertyValue('--transform-function-4'), 'translateX(10%) scale(2)');
+        assert_computed_value('<transform-function>', 'translateX(2px)', 'translateX(2px)');
+        assert_computed_value('<transform-function>', 'translateX(10em)', 'translateX(100px)');
+        assert_computed_value('<transform-function>', 'translateX(calc(11em + 10%))', 'translateX(calc(110px + 10%))');
+        assert_computed_value('<transform-function>+', 'translateX(10%) scale(2)', 'translateX(10%) scale(2)');
     }, "<transform-function> values are computed correctly for " + id);
 }
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/resources/utils.js
@@ -0,0 +1,86 @@
+let next_property_id = 1;
+
+// Generate a unique property name on the form --prop-N.
+function generate_name() {
+  return `--prop-${next_property_id++}`;
+}
+
+// Produce a compatible initial value for the specified syntax.
+function any_initial_value(syntax) {
+  let components = syntax.split('|').map(x => x.trim())
+  let first_component = components[0];
+
+  if (first_component.endsWith('+') || first_component.endsWith('#'))
+    first_component = first_component.slice(0, -1);
+
+  switch (first_component) {
+    case '*':
+    case '<custom-ident>':
+      return 'NULL';
+    case '<angle>':
+      return '0deg';
+    case '<color>':
+      return 'rgb(0, 0, 0)';
+    case '<image>':
+    case '<url>':
+      return 'url(0)';
+    case '<integer>':
+    case '<length-percentage>':
+    case '<length>':
+    case '<number>':
+      return '0';
+    case '<percentage>':
+      return '0%';
+    case '<resolution>':
+      return '0dpi';
+    case '<time>':
+      return '0s';
+    case '<transform-function>':
+    case '<transform-list>':
+      return 'matrix(0, 0, 0, 0, 0, 0)';
+    default:
+      // We assume syntax is a specific custom ident.
+      return first_component;
+  }
+}
+
+// Registers a unique property on the form '--prop-N' and returns the name.
+// Any value except 'syntax' may be omitted, in which case the property will
+// not inherit, and some undefined (but compatible) initial value will be
+// generated. If a single string is used as the argument, it is assumed to be
+// the syntax.
+function generate_property(reg) {
+  let syntax = typeof(reg) === 'string' ? reg : reg.syntax;
+  let initial = typeof(reg.initialValue) === 'undefined' ? any_initial_value(syntax)
+                                                         : reg.initialValue;
+  let inherits = typeof(reg.inherits) === 'undefined' ? false : reg.inherits;
+
+  let name = generate_name();
+  CSS.registerProperty({
+    name: name,
+    syntax: syntax,
+    initialValue: initial,
+    inherits: inherits
+  });
+  return name;
+}
+
+function all_syntaxes() {
+  return [
+    '*',
+    '<angle>',
+    '<color>',
+    '<custom-ident>',
+    '<image>',
+    '<integer>',
+    '<length-percentage>',
+    '<length>',
+    '<number>',
+    '<percentage>',
+    '<resolution>',
+    '<time>',
+    '<transform-function>',
+    '<transform-list>',
+    '<url>'
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/css/css-properties-values-api/self-utils.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Self-test for utils.js</title>
+<link rel="help" href="https://drafts.css-houdini.org/css-properties-values-api-1/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="./resources/utils.js"></script>
+<div id=outer><div id=inner></div></div>
+<script>
+
+test(function(){
+  let syntaxes = all_syntaxes().concat([
+    'foo',
+    'bar | <length>',
+    '<angle> | <length>'
+  ]);
+  // Don't throw:
+  syntaxes.forEach(generate_property);
+}, 'Default initial values of generated properties are valid (self-test).');
+
+test(function(){
+  try {
+    let inherited = generate_property({ syntax: '<length>', inherits: true });
+    let non_inherited = generate_property({ syntax: '<length>', inherits: false, initialValue: '5px' });
+    outer.style = `${inherited}: 10px; ${non_inherited}: 11px;`;
+    assert_equals(getComputedStyle(outer).getPropertyValue(inherited), '10px');
+    assert_equals(getComputedStyle(outer).getPropertyValue(non_inherited), '11px');
+    assert_equals(getComputedStyle(inner).getPropertyValue(inherited), '10px');
+    assert_equals(getComputedStyle(inner).getPropertyValue(non_inherited), '5px');
+  } finally {
+    outer.style = '';
+    inner.style = '';
+  }
+}, 'Generated properties respect inherits flag');
+
+</script>