Skip to content

Commit

Permalink
[WPT] Introduce a test-only-api helper script
Browse files Browse the repository at this point in the history
including a helper function to load Mojo JS bindings. This will enable
us to have better control over loading of *.mojom.js (notably disable
automatic dependency loading) and reduce code duplication.

Refactor WebXR tests to use this helper script, and add missing
dependencies that were previously auto loaded. (WebUSB & WebBluetooth
changes to follow.)

Note that upstream WPT still does not have *.mojom.js available so tests
will continue to fail there (but with a clearer error). Test results on
Chromium waterfall should not change.

Bug: 1094512
Change-Id: If660c4788c185bc7baf9ce6edbb691333e509d4a
  • Loading branch information
Hexcles authored and chromium-wpt-export-bot committed Jun 30, 2020
1 parent 1753398 commit 95c9418
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 22 deletions.
2 changes: 2 additions & 0 deletions lint.ignore
Expand Up @@ -688,6 +688,7 @@ MISSING-LINK: css/filter-effects/*.any.js

# Tests that use WebKit/Blink testing APIs
LAYOUTTESTS APIS: import-maps/common/resources/common-test-helper.js
LAYOUTTESTS APIS: resources/test-only-api.js
LAYOUTTESTS APIS: resources/chromium/enable-hyperlink-auditing.js
LAYOUTTESTS APIS: resources/chromium/generic_sensor_mocks.js
LAYOUTTESTS APIS: resources/chromium/nfc-mock.js
Expand All @@ -709,6 +710,7 @@ WEB-PLATFORM.TEST:web-bundle/resources/wbn/*.wbn
# Tests that depend on resources in /gen/ in Chromium:
# https://github.com/web-platform-tests/wpt/issues/16455
# Please consult with ecosystem-infra@chromium.org before adding more.
MISSING DEPENDENCY: resources/test-only-api.js
MISSING DEPENDENCY: idle-detection/interceptor.https.html
MISSING DEPENDENCY: credential-management/support/otpcredential-helper.js
MISSING DEPENDENCY: web-nfc/resources/nfc-helpers.js
Expand Down
68 changes: 68 additions & 0 deletions resources/test-only-api.js
@@ -0,0 +1,68 @@
'use strict';

/* Whether the browser is Chromium-based with MojoJS enabled */
const isChromiumBased = 'MojoInterfaceInterceptor' in self;
/* Whether the browser is WebKit-based with internal test-only API enabled */
const isWebKitBased = !isChromiumBased && 'internals' in self;

/**
* Loads a script in a window or worker.
*
* @param {string} path - A script path
* @returns {Promise}
*/
function loadScript(path) {
if (typeof document === 'undefined') {
// Workers (importScripts is synchronous and may throw.)
importScripts(path);
return Promise.resolve();
} else {
// Window
const script = document.createElement('script');
script.src = path;
script.async = false;
const p = new Promise((resolve, reject) => {
script.onload = () => { resolve(); };
script.onerror = e => { reject(e); };
})
document.head.appendChild(script);
return p;
}
}

/**
* A helper for Chromium-based browsers to load Mojo JS bindingds
*
* This is an async function that works in both workers and windows. It first
* loads mojo_bindings.js, disables automatic dependency loading, and loads all
* resources sequentially. The promise resolves if everything loads
* successfully, or rejects if any exception is raised. If testharness.js is
* used, an uncaught exception will terminate the test with a harness error
* (unless `allow_uncaught_exception` is true), which is usually the desired
* behaviour. Only call this function if isChromiumBased === true.
*
* @param {Array.<string>} resources - A list of scripts to load: Mojo JS
* bindings should be of the form '/gen/../*.mojom.js', the ordering of which
* does not matter. Do not include mojo_bindings.js in this list. You may
* include other non-mojom.js scripts for convenience.
* @returns {Promise}
*/
async function loadMojoResources(resources) {
if (!('MojoInterfaceInterceptor' in self)) {
throw new Error('MojoJS not enabled; start Chrome with --enable-blink-features=MojoJS,MojoJSTest');
}
if (resources.length == 0) {
return;
}

// We want to load mojo_bindings.js separately to set mojo.config.
if (resources.some(p => p.endsWith('/mojo_bindings.js'))) {
throw new Error('Do not load mojo_bindings.js explicitly.');
}
await loadScript('/gen/layout_test_data/mojo/public/js/mojo_bindings.js');
mojo.config.autoLoadMojomDeps = false;

for (const path of resources) {
await loadScript(path);
}
}
2 changes: 2 additions & 0 deletions resources/test-only-api.js.headers
@@ -0,0 +1,2 @@
Content-Type: text/javascript; charset=utf-8
Cache-Control: max-age=3600
53 changes: 31 additions & 22 deletions webxr/resources/webxr_util.js
@@ -1,3 +1,5 @@
'use strict';

// These tests rely on the User Agent providing an implementation of the
// WebXR Testing API (https://github.com/immersive-web/webxr-test-api).
//
Expand All @@ -9,22 +11,34 @@

// Debugging message helper, by default does nothing. Implementations can
// override this.
var xr_debug = function(name, msg) {}
var isChromiumBased = 'MojoInterfaceInterceptor' in self;
var isWebKitBased = 'internals' in self && 'xrTest' in internals;
var xr_debug = function(name, msg) {};

function xr_promise_test(name, func, properties) {
promise_test(async (t) => {
// Perform any required test setup:
xr_debug(name, 'setup');

// Only set up once.
if (!navigator.xr.test) {
// Load test-only API helpers.
const script = document.createElement('script');
script.src = '/resources/test-only-api.js';
script.async = false;
const p = new Promise((resolve, reject) => {
script.onload = () => { resolve(); };
script.onerror = e => { reject(e); };
})
document.head.appendChild(script);
await p;

if (isChromiumBased) {
// Chrome setup
await loadChromiumResources();
} else if (isWebKitBased) {
// WebKit setup
await setupWebKitWebXRTestAPI();
} else {
assert_implements(false, "missing navigator.xr.test");
}
}

Expand Down Expand Up @@ -185,19 +199,27 @@ function forEachWebxrObject(callback) {
}

// Code for loading test API in Chromium.
function loadChromiumResources() {
async function loadChromiumResources() {
let chromiumResources = [
'/gen/layout_test_data/mojo/public/js/mojo_bindings.js',
'/gen/mojo/public/mojom/base/time.mojom.js',
'/gen/gpu/ipc/common/mailbox_holder.mojom.js',
'/gen/mojo/public/mojom/base/shared_memory.mojom.js',
'/gen/mojo/public/mojom/base/unguessable_token.mojom.js',
'/gen/gpu/ipc/common/sync_token.mojom.js',
'/gen/ui/display/mojom/display.mojom.js',
'/gen/gpu/ipc/common/mailbox.mojom.js',
'/gen/gpu/ipc/common/mailbox_holder.mojom.js',
'/gen/ui/gfx/geometry/mojom/geometry.mojom.js',
'/gen/ui/gfx/mojom/native_handle_types.mojom.js',
'/gen/ui/gfx/mojom/buffer_types.mojom.js',
'/gen/ui/gfx/mojom/color_space.mojom.js',
'/gen/ui/gfx/mojom/display_color_spaces.mojom.js',
'/gen/ui/gfx/mojom/gpu_fence_handle.mojom.js',
'/gen/ui/gfx/mojom/transform.mojom.js',
'/gen/ui/display/mojom/display.mojom.js',
'/gen/device/gamepad/public/mojom/gamepad.mojom.js',
'/gen/device/vr/public/mojom/vr_service.mojom.js',
'/resources/chromium/webxr-test-math-helper.js',
'/resources/chromium/webxr-test.js',
// Required only by resources/chromium/webxr-test.js
'/resources/testdriver.js',
'/resources/testdriver-vendor.js',
];
Expand All @@ -210,22 +232,9 @@ function loadChromiumResources() {
chromiumResources = chromiumResources.concat(additionalChromiumResources);
}

let chain = Promise.resolve();
chromiumResources.forEach(path => {
let script = document.createElement('script');
script.src = path;
script.async = false;
chain = chain.then(() => new Promise(resolve => {
script.onload = () => resolve();
}));
document.head.appendChild(script);
});

chain = chain.then(() => {
xr_debug = navigator.xr.test.Debug;
});
await loadMojoResources(chromiumResources);

return chain;
xr_debug = navigator.xr.test.Debug;
}

function setupWebKitWebXRTestAPI() {
Expand Down

0 comments on commit 95c9418

Please sign in to comment.