Bug 1323328 - Part 3: Add VR display request present mochitest; r=kip

MozReview-Commit-ID: 13WuFhUFcTo

--HG--
extra : rebase_source : 00d5c0f36f3550c19367c4a9b6882c10175a0862
This commit is contained in:
Daosheng Mu 2017-03-02 00:00:23 +08:00
Родитель cfca85c8aa
Коммит d7b6a3ff79
8 изменённых файлов: 252 добавлений и 0 удалений

Просмотреть файл

@ -27,3 +27,5 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [ LOCAL_INCLUDES += [
'/dom/base' '/dom/base'
] ]
MOCHITEST_MANIFESTS += ['test/mochitest.ini']

Просмотреть файл

@ -0,0 +1,45 @@
var VRServiceTest;
var VRSimulationDriver = (function() {
"use strict";
var AttachWebVRDisplay = function() {
return VRServiceTest.attachVRDisplay("VRDisplayTest");
};
var SetVRDisplayPose = function(vrDisplay, position,
linearVelocity, linearAcceleration,
orientation, angularVelocity,
angularAcceleration) {
vrDisplay.setPose(position, linearVelocity, linearAcceleration,
orientation, angularVelocity, angularAcceleration);
};
var SetEyeResolution = function(width, height) {
vrDisplay.setEyeResolution(width, height);
}
var SetEyeParameter = function(vrDisplay, eye, offsetX, offsetY, offsetZ,
upDegree, rightDegree, downDegree, leftDegree) {
vrDisplay.setEyeParameter(eye, offsetX, offsetY, offsetZ, upDegree, rightDegree,
downDegree, leftDegree);
}
var UpdateVRDisplay = function(vrDisplay) {
vrDisplay.update();
}
var API = {
AttachWebVRDisplay: AttachWebVRDisplay,
SetVRDisplayPose: SetVRDisplayPose,
SetEyeResolution: SetEyeResolution,
SetEyeParameter: SetEyeParameter,
UpdateVRDisplay: UpdateVRDisplay,
none: false
};
return API;
}());

Просмотреть файл

@ -0,0 +1,21 @@
var WebVRHelpers = (function() {
"use strict";
var RequestPresentOnVRDisplay = function(vrDisplay, vrLayers, callback) {
if (callback) {
callback();
}
return vrDisplay.requestPresent(vrLayers);
};
var API = {
RequestPresentOnVRDisplay: RequestPresentOnVRDisplay,
none: false
};
return API;
}());

Просмотреть файл

@ -0,0 +1,9 @@
[DEFAULT]
support-files =
VRSimulationDriver.js
requestPresent.js
runVRTest.js
WebVRHelpers.js
[test_vrDisplay_requestPresent.html]
skip-if = true

Просмотреть файл

@ -0,0 +1,34 @@
// requestPresent.js
//
// This file provides helpers for testing VRDisplay requestPresent.
function setupVRDisplay(test) {
assert_equals(typeof (navigator.getVRDisplays), "function", "'navigator.getVRDisplays()' must be defined.");
return VRSimulationDriver.AttachWebVRDisplay().then(() => {
return navigator.getVRDisplays();
}).then((displays) => {
assert_equals(displays.length, 1, "displays.length must be one after attach.");
vrDisplay = displays[0];
return validateNewVRDisplay(test, vrDisplay);
});
}
// Validate the settings off a freshly created VRDisplay (prior to calling
// requestPresent).
function validateNewVRDisplay(test, display) {
assert_true(display.capabilities.canPresent, "display.capabilities.canPresent must always be true for HMDs.");
assert_equals(display.capabilities.maxLayers, 1, "display.capabilities.maxLayers must always be 1 when display.capabilities.canPresent is true for current spec revision.");
assert_false(display.isPresenting, "display.isPresenting must be false before calling requestPresent.");
assert_equals(display.getLayers().length, 0, "display.getLayers() should have no layers if not presenting.");
var promise = display.exitPresent();
return promise_rejects(test, null, promise);
}
// Validate the settings off a VRDisplay after requestPresent promise is
// rejected or after exitPresent is fulfilled.
function validateDisplayNotPresenting(test, display) {
assert_false(display.isPresenting, "display.isPresenting must be false if requestPresent is rejected or after exitPresent is fulfilled.");
assert_equals(display.getLayers().length, 0, "display.getLayers() should have no layers if requestPresent is rejected or after exitPresent is fulfilled.");
var promise = display.exitPresent();
return promise_rejects(test, null, promise);
}

9
dom/vr/test/runVRTest.js Normal file
Просмотреть файл

@ -0,0 +1,9 @@
function runVRTest(callback) {
SpecialPowers.pushPrefEnv({"set" : [["dom.vr.enabled", true],
["dom.vr.puppet.enabled", true],
["dom.vr.test.enabled", true]]},
() => {
VRServiceTest = navigator.requestVRServiceTest();
callback();
});
}

Просмотреть файл

@ -0,0 +1,130 @@
<!DOCTYPE html>
<html>
<head>
<title>VRDisplay RequestPresent</title>
<meta name="timeout" content="long"/>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="VRSimulationDriver.js"></script>
<script src="WebVRHelpers.js"></script>
<script src="requestPresent.js"></script>
<script src="runVRTest.js"></script>
</head>
<body id="body">
<canvas id="webglCanvas"></canvas>
<div id="testDiv"></div>
<script>
"use strict";
var vrDisplay;
var canvas = document.getElementById('webglCanvas');
var div = document.getElementById('testDiv');
function startTest() {
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{}]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with empty frames");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: [0.0, 0.0] }]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with incorrect bounds (bounds arrays must be 0 or 4 long)");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: div }]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with invalid source (must be canvas element)");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: [div] }]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with invalid bounds data type (must be able to convert to float)");
const invalidBounds = [
[2.0, 0.0, 0.0, 0.0],
[0.0, 2.0, 0.0, 0.0],
[0.0, 0.0, 2.0, 0.0],
[0.0, 0.0, 0.0, 2.0],
[-1.0, 0.0, 0.0, 0.0],
[0.0, -1.0, 0.0, 0.0],
[0.0, 0.0, -1.0, 0.0],
[0.0, 0.0, 0.0, -1.0]];
invalidBounds.forEach((bound) => {
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas, leftBounds: bound }]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with bounds in invalid range: [" + bound + "]");
});
promise_test((test) => {
return setupVRDisplay(test).then(() => {
var promise = vrDisplay.requestPresent({ source: canvas });
return promise_rejects(test, null, promise);
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected without user initiated action");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return promise_rejects(test, null, WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }, { source: canvas }]));
}).then(() => {
return validateDisplayNotPresenting(test, vrDisplay);
});
}, "WebVR requestPresent rejected with more frames than max layers");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
function requestAgain() {
// Callback for immediate requestPresent call for further testing.
// Cache this promise on global object since it seems to be the only object
// in scope across calls.
window.promiseSecond = vrDisplay.requestPresent([{ source: canvas }]);
}
return WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }], requestAgain);
}).then(() => {
// First promise succeeded
assert_true(vrDisplay.isPresenting, "First promise should successfully fulfill");
// Now, validate that the subsequent requestPresent was rejected
return promise_rejects(test, null, window.promiseSecond);
}).then(() => {
delete window.promiseSecond;
assert_true(vrDisplay.isPresenting, "Should still be presenting after rejected second promise");
return vrDisplay.exitPresent();
});
}, "WebVR requestPresent fails while another one is in progress");
promise_test((test) => {
return setupVRDisplay(test).then(() => {
return WebVRHelpers.RequestPresentOnVRDisplay(vrDisplay, [{ source: canvas }]);
}).then(() => {
assert_true(vrDisplay.isPresenting, "vrDisplay.isPresenting must be true if requestPresent is fulfilled.");
assert_equals(vrDisplay.getLayers().length, 1, "vrDisplay.getLayers() should return one layer.");
return vrDisplay.exitPresent();
}).then(() => {
assert_false(vrDisplay.isPresenting, "vrDisplay.isPresenting must be false if exitPresent is fulfilled.");
// exitPresent() should reject since we are no longer presenting.
return promise_rejects(test, null, vrDisplay.exitPresent());
});
}, "WebVR requestPresent fulfilled");
}
runVRTest(startTest);
</script>
</body>
</html>

Просмотреть файл

@ -5036,6 +5036,8 @@ pref("gfx.vr.osvr.utilLibPath", "");
pref("gfx.vr.osvr.commonLibPath", ""); pref("gfx.vr.osvr.commonLibPath", "");
pref("gfx.vr.osvr.clientLibPath", ""); pref("gfx.vr.osvr.clientLibPath", "");
pref("gfx.vr.osvr.clientKitLibPath", ""); pref("gfx.vr.osvr.clientKitLibPath", "");
// Puppet device, used for simulating VR hardware within tests and dev tools
pref("dom.vr.puppet.enabled", false);
pref("dom.vr.test.enabled", false); pref("dom.vr.test.enabled", false);
// MMS UA Profile settings // MMS UA Profile settings
pref("wap.UAProf.url", ""); pref("wap.UAProf.url", "");