Bug 1516219 [wpt PR 7335] - Add media capture depth dictionary test, a=testonly
authorkaixinjxq <xiuqix.jiang@intel.com>
Thu, 31 Jan 2019 15:43:00 +0000
changeset 457841 8b41d4f59a4184d129082af76c221ca5db1164c6
parent 457840 cc252c714f1c41d53103c420db0e88d716db3112
child 457842 7d41cf15351f82e46d51367a7a73d31e816f6673
push id35518
push useropoprus@mozilla.com
push dateFri, 08 Feb 2019 09:55:14 +0000
treeherdermozilla-central@3a3e393396f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1516219
milestone67.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 1516219 [wpt PR 7335] - Add media capture depth dictionary test, a=testonly Automatic update from web-platform-tests Add media capture depth dictionary test (#7335) -- wpt-commits: fc8ca52dec5112eacd8507a2dfe3984a1290387d wpt-pr: 7335
testing/web-platform/tests/mediacapture-depth/META.yml
testing/web-platform/tests/mediacapture-depth/dictionary-helper.js
testing/web-platform/tests/mediacapture-depth/dictionary-manual.https.html
--- a/testing/web-platform/tests/mediacapture-depth/META.yml
+++ b/testing/web-platform/tests/mediacapture-depth/META.yml
@@ -1,5 +1,6 @@
 spec: https://w3c.github.io/mediacapture-depth/
 suggested_reviewers:
   - anssiko
   - Honry
   - robman
+  - astojilj
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/mediacapture-depth/dictionary-helper.js
@@ -0,0 +1,141 @@
+"use strict";
+
+// Helper assertion functions to validate dictionary fields
+// on dictionary objects returned from APIs
+
+function assert_string(object) {
+  assert_equals(typeof object, "string",
+    `Expect ${object} to be string`);
+}
+
+function assert_string_field(object, field) {
+  const str = object[field];
+  assert_equals(typeof str, "string",
+    `Expect dictionary.${field} to be string`);
+}
+
+function assert_number_field(object, field) {
+  const num = object[field];
+  assert_equals(typeof num, "number",
+    `Expect dictionary.${field} to be number`);
+}
+
+function assert_boolean_field(object, field, value = "") {
+  const bool = object[field];
+  assert_equals(typeof bool, "boolean",
+    `Expect dictionary.${field} to be boolean`);
+  if (object[field] !== "") {
+    assert_equals(object[field], value,
+      `Expect default value of dictionary.${field} to be ${value}`);
+  }
+}
+
+function assert_array_field(object, field) {
+  assert_true(Array.isArray(object[field]),
+    `Expect dictionary.${field} to be array`);
+}
+
+function assert_enum_field(object, field, validValues) {
+  assert_string_field(object, field);
+  assert_true(validValues.includes(object[field]),
+    `Expect dictionary.${field} to have one of the valid enum values: ${validValues}`);
+}
+
+function assert_number_range_field(object, field, key) {
+  const num = object[field][key];
+  assert_equals(typeof num, "number",
+    `Expect dictionary.${field}.${key} to be number`);
+}
+
+function assert_boolean_range_field(object, field, key) {
+  const bool = object[field][key];
+  assert_equals(typeof bool, "boolean",
+    `Expect dictionary.${field}.${key} to be boolean`);
+}
+
+function assert_number_or_number_range_field(object, field) {
+  if (typeof object[field] !== "object") {
+    assert_number_field(object, field);
+  } else {
+    if (object[field]["max"] !== undefined)
+      assert_number_range_field(object, field, "max");
+    if (object[field]["min"] !== undefined)
+      assert_number_range_field(object, field, "min");
+    if (object[field]["max"] === undefined &&
+        object[field]["min"] === undefined)
+      assert_unreached();
+  }
+}
+
+function assert_constrain_string_field(object, field) {
+  // test DOMString type
+  if (typeof object[field] !== "object") {
+    assert_string_field(object, field);
+  // test ConstrainDOMStringParameters type
+  } else if (typeof object[field]["exact"] !== undefined || typeof object[field]["ideal"] !== undefined) {
+    if (object[field]["exact"] !== undefined) {
+      // test DOMString type key value of ConstrainDOMStringParameters dictionary
+      if (typeof object[field] !== "object") {
+        assert_string_field(object[field], "exact");
+      // test sequence<DOMString> type key value of ConstrainDOMStringParameters dictionary
+      } else {
+        assert_array_field(object[field], "exact");
+        for(const item of object[field]["exact"]) {
+          assert_string(item);
+        }
+      }
+    }
+    if (object[field]["ideal"] !== undefined) {
+      // test DOMString type key value of ConstrainDOMStringParameters dictionary
+      if (typeof object[field] !== "object") {
+        assert_string_field(object[field], "ideal");
+      // test sequence<DOMString> type key value of ConstrainDOMStringParameters dictionary
+      } else {
+        assert_array_field(object[field], "ideal");
+        for(const item of object[field]["ideal"]) {
+          assert_string(item);
+        }
+      }
+    }
+  // test sequence<DOMString> type
+  } else {
+    assert_array_field(object, field);
+    for(const item of object[field]) {
+      assert_string(item);
+    }
+  }
+}
+
+function assert_constrain_number_field(object, field) {
+  if (typeof object[field] !== "object") {
+    assert_number_field(object, field);
+  } else {
+    if (object[field]["max"] !== undefined)
+      assert_number_range_field(object, field, "max");
+    if (object[field]["min"] !== undefined)
+      assert_number_range_field(object, field, "min");
+    if (object[field]["exact"] !== undefined)
+      assert_number_range_field(object, field, "exact");
+    if (object[field]["ideal"] !== undefined)
+      assert_number_range_field(object, field, "ideal");
+    if (object[field]["max"] === undefined &&
+        object[field]["min"] === undefined &&
+        object[field]["exact"] === undefined &&
+        object[field]["ideal"] === undefined)
+      assert_unreached();
+  }
+}
+
+function assert_constrain_boolean_field(object, field) {
+  if (typeof object[field] !== "object") {
+    assert_boolean_field(object, field);
+  } else {
+    if (object[field]["exact"] !== undefined)
+      assert_boolean_range_field(object, field, "exact");
+    if (object[field]["ideal"] !== undefined)
+      assert_boolean_range_field(object, field, "ideal");
+    if (object[field]["exact"] === undefined &&
+        object[field]["ideal"] === undefined)
+      assert_unreached();
+  }
+}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/mediacapture-depth/dictionary-manual.https.html
@@ -0,0 +1,277 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Media Capture Depth Dictionary Test</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://w3c.github.io/mediacapture-depth/#extensions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="dictionary-helper.js"></script>
+<meta name="flags" content="interact">
+
+<h2>Preconditions</h2>
+<ol>
+  <li>
+    Use a test device with depth camera(embedded or external).
+  </li>
+  <li>
+    When prompted, accept to share your depth/color(RGB) stream.
+  </li>
+</ol>
+
+<div id="log"></div>
+
+<script>
+
+let advanced_constraints_depth = [{
+  videoKind: "depth",
+  focalLengthX: 0.5,
+  focalLengthY: 0.5,
+  principalPointX: 0.1,
+  principalPointY: 0.1,
+  deprojectionDistortionCoefficients: true,
+  projectionDistortionCoefficients: true,
+  depthNear: 0.5,
+  depthFar: 1,
+  depthToVideoTransform: true
+}];
+
+let advanced_constraints_color = [{
+  videoKind: "color",
+  focalLengthX: 0.5,
+  focalLengthY: 0.5,
+  principalPointX: 0.1,
+  principalPointY: 0.1,
+  deprojectionDistortionCoefficients: true,
+  projectionDistortionCoefficients: true
+}];
+
+/*
+  partial dictionary MediaTrackCapabilities {
+    // Apply to both depth stream track and color stream track:
+    DOMString               videoKind;
+    (double or DoubleRange) focalLengthX;
+    (double or DoubleRange) focalLengthY;
+    (double or DoubleRange) principalPointX;
+    (double or DoubleRange) principalPointY;
+    boolean                 deprojectionDistortionCoefficients;
+    boolean                 projectionDistortionCoefficients;
+    // Apply to depth stream track:
+    (double or DoubleRange) depthNear;
+    (double or DoubleRange) depthFar;
+    boolean                 depthToVideoTransform;
+  };
+
+  dictionary DoubleRange {
+    double max;
+    double min;
+  };
+*/
+
+function validateMediaTrackCapabilities(capabilities, type) {
+  assert_string_field(capabilities, 'videoKind');
+  assert_number_or_number_range_field(capabilities, 'focalLengthX');
+  assert_number_or_number_range_field(capabilities, 'focalLengthY');
+  assert_number_or_number_range_field(capabilities, 'principalPointX');
+  assert_number_or_number_range_field(capabilities, 'principalPointY');
+  assert_boolean_field(capabilities, 'deprojectionDistortionCoefficients');
+  assert_boolean_field(capabilities, 'projectionDistortionCoefficients');
+  if (type == "depth") {
+    assert_number_or_number_range_field(capabilities, 'depthNear');
+    assert_number_or_number_range_field(capabilities, 'depthFar');
+    assert_boolean_field(capabilities, 'depthToVideoTransform');
+  }
+}
+
+/*
+  partial dictionary MediaTrackConstraintSet {
+    // Apply to both depth stream track and color stream track:
+    ConstrainDOMString videoKind;
+    ConstrainDouble    focalLengthX;
+    ConstrainDouble    focalLengthY;
+    ConstrainDouble    principalPointX;
+    ConstrainDouble    principalPointY;
+    ConstrainBoolean   deprojectionDistortionCoefficients;
+    ConstrainBoolean   projectionDistortionCoefficients;
+    // Apply to depth stream track:
+    ConstrainDouble    depthNear;
+    ConstrainDouble    depthFar;
+    ConstrainBoolean   depthToVideoTransform;
+  };
+
+  typedef (DOMString or sequence<DOMString> or ConstrainDOMStringParameters) ConstrainDOMString;
+
+  dictionary ConstrainDOMStringParameters {
+    (DOMString or sequence<DOMString>) exact;
+    (DOMString or sequence<DOMString>) ideal;
+  };
+
+  typedef (double or ConstrainDoubleRange) ConstrainDouble;
+
+  dictionary DoubleRange {
+    double max;
+    double min;
+  };
+
+  dictionary ConstrainDoubleRange : DoubleRange {
+    double exact;
+    double ideal;
+  };
+
+  typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean;
+
+  dictionary ConstrainBooleanParameters {
+    boolean exact;
+    boolean ideal;
+  };
+*/
+
+function validateMediaTrackConstraintSet(constraints, type) {
+  assert_constrain_string_field(constraints, 'videoKind');
+  assert_constrain_number_field(constraints, 'focalLengthX');
+  assert_constrain_number_field(constraints, 'focalLengthY');
+  assert_constrain_number_field(constraints, 'principalPointX');
+  assert_constrain_number_field(constraints, 'principalPointY');
+  assert_constrain_boolean_field(constraints, 'deprojectionDistortionCoefficients');
+  assert_constrain_boolean_field(constraints, 'projectionDistortionCoefficients');
+  if (type == "depth") {
+    assert_constrain_number_field(constraints, 'depthNear');
+    assert_constrain_number_field(constraints, 'depthFar');
+    assert_constrain_boolean_field(constraints, 'depthToVideoTransform');
+  }
+}
+
+/*
+  partial dictionary MediaTrackSettings {
+    // Apply to both depth stream track and color stream track:
+    DOMString              videoKind;
+    double                 focalLengthX;
+    double                 focalLengthY;
+    double                 principalPointX;
+    double                 principalPointY;
+    DistortionCoefficients deprojectionDistortionCoefficients;
+    DistortionCoefficients projectionDistortionCoefficients;
+    // Apply to depth stream track:
+    double                 depthNear;
+    double                 depthFar;
+    Transformation         depthToVideoTransform;
+  };
+
+  dictionary DistortionCoefficients {
+    double k1;
+    double k2;
+    double p1;
+    double p2;
+    double k3;
+  };
+
+  dictionary Transformation {
+    Float32Array transformationMatrix;
+    DOMString    videoDeviceId;
+  };
+
+  enum VideoKindEnum {
+    "color",
+    "depth"
+  };
+*/
+
+function validateDistortionCoefficients(coefficients) {
+  assert_number_field(coefficients, 'k1');
+  assert_number_field(coefficients, 'k2');
+  assert_number_field(coefficients, 'p1');
+  assert_number_field(coefficients, 'p2');
+  assert_number_field(coefficients, 'k3');
+}
+
+function validateTransformation(depthToVideoTransform) {
+  assert_array_field(depthToVideoTransform, 'transformationMatrix');
+  assert_string_field(depthToVideoTransform, 'videoDeviceId');
+}
+
+function validateMediaTrackSettings(settings, type) {
+  assert_string_field(settings, 'videoKind');
+  assert_enum_field(settings, 'videoKind', ['color', 'depth'])
+  assert_number_field(settings, 'focalLengthX');
+  assert_number_field(settings, 'focalLengthY');
+  assert_number_field(settings, 'principalPointX');
+  assert_number_field(settings, 'principalPointY');
+  if (settings.deprojectionDistortionCoefficients) {
+    validateDistortionCoefficients(settings.deprojectionDistortionCoefficients);
+  }
+  if (settings.projectionDistortionCoefficients) {
+    validateDistortionCoefficients(settings.projectionDistortionCoefficients);
+  }
+  if (type == "depth") {
+    assert_number_field(settings, 'depthNear');
+    assert_number_field(settings, 'depthFar');
+    if (settings.depthToVideoTransform) {
+      validateTransformation(settings.depthToVideoTransform);
+    }
+  }
+}
+
+/*
+  partial dictionary MediaTrackSupportedConstraints {
+    // Apply to both depth stream track and color stream track:
+    boolean videoKind = true;
+    boolean focalLengthX = false;
+    boolean focalLengthY = false;
+    boolean principalPointX = false;
+    boolean principalPointY = false;
+    boolean deprojectionDistortionCoefficients = false;
+    boolean projectionDistortionCoefficients = false;
+    // Apply to depth stream track:
+    boolean depthNear = false;
+    boolean depthFar = false;
+    boolean depthToVideoTransform = false;
+  };
+*/
+
+function validateMediaTrackSupportedConstraints(supports) {
+  assert_boolean_field(supports, 'videoKind', true);
+  assert_boolean_field(supports, 'focalLengthX', false);
+  assert_boolean_field(supports, 'focalLengthY', false);
+  assert_boolean_field(supports, 'principalPointX', false);
+  assert_boolean_field(supports, 'principalPointY', false);
+  assert_boolean_field(supports, 'deprojectionDistortionCoefficients', false);
+  assert_boolean_field(supports, 'projectionDistortionCoefficients', false);
+  assert_boolean_field(supports, 'depthNear', false);
+  assert_boolean_field(supports, 'depthFar', false);
+  assert_boolean_field(supports, 'depthToVideoTransform', false);
+}
+
+function runDictionaryTests(type, constraints) {
+  promise_test(t => {
+    return navigator.mediaDevices.getUserMedia({video: {advanced: constraints}})
+    .then(stream => {
+      let capabilities = stream.getTracks()[0].getCapabilities();
+      validateMediaTrackCapabilities(capabilities, type);
+    });
+  }, `MediaTrackCapabilities dictionary of ${type} include attributes are correct`);
+
+  promise_test(t => {
+    return navigator.mediaDevices.getUserMedia({video: {advanced: constraints}})
+    .then(stream => {
+      let constraints = stream.getTracks()[0].getConstraints()["advanced"][0];
+      validateMediaTrackConstraintSet(constraints);
+    });
+  }, `MediaTrackConstraintSet dictionary of ${type} include attributes are correct`);
+
+  promise_test(t => {
+    return navigator.mediaDevices.getUserMedia({video: {advanced: constraints}})
+    .then(stream => {
+      let settings = stream.getTracks()[0].getSettings();
+      validateMediaTrackSettings(settings, type);
+    });
+  }, `MediaTrackSettings dictionary of ${type} include attributes are correct`);
+}
+
+test(() => {
+  let supports = navigator.mediaDevices.getSupportedConstraints();
+  validateMediaTrackSupportedConstraints(supports);
+}, "MediaTrackSupportedConstraints dictionary include attributes are correct");
+
+runDictionaryTests("depth", advanced_constraints_depth);
+runDictionaryTests("color", advanced_constraints_color);
+
+</script>