Source code
Revision control
Copy as Markdown
Other Tools
Test Info: Warnings
- This test has a WPT meta file that expects 2 subtest issues.
- This WPT test may be referenced by the following Test IDs:
- /service-workers/service-worker/ServiceWorkerGlobalScope/extendable-message-event.https.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<title>ServiceWorkerGlobalScope: ExtendableMessageEvent</title>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<script src='../resources/test-helpers.sub.js'></script>
<script src='./resources/extendable-message-event-utils.js'></script>
<script>
promise_test(function(t) {
var script = 'resources/extendable-message-event-worker.js';
var scope = 'resources/scope/extendable-message-event-from-toplevel';
var registration;
return service_worker_unregister_and_register(t, script, scope)
.then(function(r) {
registration = r;
add_completion_callback(function() { registration.unregister(); });
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
var saw_message = new Promise(function(resolve) {
navigator.serviceWorker.onmessage =
function(event) { resolve(event.data); }
});
var channel = new MessageChannel;
registration.active.postMessage('', [channel.port1]);
return saw_message;
})
.then(function(results) {
var expected = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'WindowClient' },
frameType: 'top-level',
url: location.href,
visibilityState: 'visible',
focused: true
},
ports: [ { constructor: { name: 'MessagePort' } } ]
};
ExtendableMessageEventUtils.assert_equals(results, expected);
});
}, 'Post an extendable message from a top-level client');
promise_test(function(t) {
var script = 'resources/extendable-message-event-worker.js';
var scope = 'resources/scope/extendable-message-event-from-nested';
var frame;
return service_worker_unregister_and_register(t, script, scope)
.then(function(registration) {
add_completion_callback(function() { registration.unregister(); });
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() { return with_iframe(scope); })
.then(function(f) {
frame = f;
add_completion_callback(function() { frame.remove(); });
var saw_message = new Promise(function(resolve) {
frame.contentWindow.navigator.serviceWorker.onmessage =
function(event) { resolve(event.data); }
});
f.contentWindow.navigator.serviceWorker.controller.postMessage('');
return saw_message;
})
.then(function(results) {
var expected = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'WindowClient' },
url: frame.contentWindow.location.href,
frameType: 'nested',
visibilityState: 'visible',
focused: false
},
ports: []
};
ExtendableMessageEventUtils.assert_equals(results, expected);
});
}, 'Post an extendable message from a nested client');
promise_test(function(t) {
var script = 'resources/extendable-message-event-loopback-worker.js';
var scope = 'resources/scope/extendable-message-event-loopback';
var registration;
return service_worker_unregister_and_register(t, script, scope)
.then(function(r) {
registration = r;
add_completion_callback(function() { registration.unregister(); });
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
var results = [];
var saw_message = new Promise(function(resolve) {
navigator.serviceWorker.onmessage = function(event) {
switch (event.data.type) {
case 'record':
results.push(event.data.results);
break;
case 'finish':
resolve(results);
break;
}
};
});
registration.active.postMessage({type: 'start'});
return saw_message;
})
.then(function(results) {
assert_equals(results.length, 2);
var expected_trial_1 = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'ServiceWorker' },
scriptURL: normalizeURL(script),
state: 'activated'
},
ports: []
};
assert_equals(results[0].trial, 1);
ExtendableMessageEventUtils.assert_equals(
results[0].event, expected_trial_1
);
var expected_trial_2 = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'ServiceWorker' },
scriptURL: normalizeURL(script),
state: 'activated'
},
ports: [],
};
assert_equals(results[1].trial, 2);
ExtendableMessageEventUtils.assert_equals(
results[1].event, expected_trial_2
);
});
}, 'Post loopback extendable messages');
promise_test(function(t) {
var script1 = 'resources/extendable-message-event-ping-worker.js';
var script2 = 'resources/extendable-message-event-pong-worker.js';
var scope = 'resources/scope/extendable-message-event-pingpong';
var registration;
return service_worker_unregister_and_register(t, script1, scope)
.then(function(r) {
registration = r;
add_completion_callback(function() { registration.unregister(); });
return wait_for_state(t, registration.installing, 'activated');
})
.then(function() {
// A controlled frame is necessary for keeping a waiting worker.
return with_iframe(scope);
})
.then(function(frame) {
add_completion_callback(function() { frame.remove(); });
return navigator.serviceWorker.register(script2, {scope: scope});
})
.then(function(r) {
return wait_for_state(t, r.installing, 'installed');
})
.then(function() {
var results = [];
var saw_message = new Promise(function(resolve) {
navigator.serviceWorker.onmessage = function(event) {
switch (event.data.type) {
case 'record':
results.push(event.data.results);
break;
case 'finish':
resolve(results);
break;
}
};
});
registration.active.postMessage({type: 'start'});
return saw_message;
})
.then(function(results) {
assert_equals(results.length, 2);
var expected_ping = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'ServiceWorker' },
scriptURL: normalizeURL(script1),
state: 'activated'
},
ports: []
};
assert_equals(results[0].pingOrPong, 'ping');
ExtendableMessageEventUtils.assert_equals(
results[0].event, expected_ping
);
var expected_pong = {
constructor: { name: 'ExtendableMessageEvent' },
origin: location.origin,
lastEventId: '',
source: {
constructor: { name: 'ServiceWorker' },
scriptURL: normalizeURL(script2),
state: 'installed'
},
ports: []
};
assert_equals(results[1].pingOrPong, 'pong');
ExtendableMessageEventUtils.assert_equals(
results[1].event, expected_pong
);
});
}, 'Post extendable messages among service workers');
</script>