Bug 1498368 [wpt PR 13469] - [css-properties-values-api] Avoid viewport dependent tests., a=testonly
authorAnders Hartvoll Ruud <andruud@chromium.org>
Mon, 15 Oct 2018 17:16:16 +0000
changeset 500207 052a4647bc04700502dacfbe14c1bbc1c2d658f2
parent 500206 cd6f94d81963ad91334bec0adfb82f5ea6680a8d
child 500208 483aee01b7d1ba1b68e3f04e8700a7950ab6caec
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1498368, 13469, 641877, 1275893, 598847
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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>