summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/presentation-api/controlling-ua/support
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/presentation-api/controlling-ua/support')
-rw-r--r--testing/web-platform/tests/presentation-api/controlling-ua/support/iframe.html181
-rw-r--r--testing/web-platform/tests/presentation-api/controlling-ua/support/presentation.html98
-rw-r--r--testing/web-platform/tests/presentation-api/controlling-ua/support/stash.js83
-rw-r--r--testing/web-platform/tests/presentation-api/controlling-ua/support/stash.py10
4 files changed, 372 insertions, 0 deletions
diff --git a/testing/web-platform/tests/presentation-api/controlling-ua/support/iframe.html b/testing/web-platform/tests/presentation-api/controlling-ua/support/iframe.html
new file mode 100644
index 0000000000..e2171deaa8
--- /dev/null
+++ b/testing/web-platform/tests/presentation-api/controlling-ua/support/iframe.html
@@ -0,0 +1,181 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Presentation API - controlling ua - sandboxing</title>
+<link rel="author" title="Francois Daoust" href="https://www.w3.org/People/#fd">
+<link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/">
+<link rel="help" href="http://w3c.github.io/presentation-api/#dom-presentationrequest-start">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../common.js"></script>
+<script>
+ add_completion_callback((tests, status) => {
+ // remove unserializable attributes, then send the result to the parent window
+ // note: a single test result is supposed to appear here.
+ parent.window.postMessage(JSON.parse(JSON.stringify({
+ type: 'presentation-api', test: tests[0], status: status
+ })), '*');
+ });
+
+ // disable timeout for manual tests
+ setup({explicit_timeout: true});
+
+ window.onmessage = function (ev) {
+ try {
+ // Presentation URLs are relative to the "controlling-ua" folder,
+ // update relative URLs for this folder
+ var urls = presentationUrls.map(function (url) {
+ if (/:\/\//.test(url)) {
+ return url;
+ }
+ else {
+ return '../' + url;
+ }
+ });
+ var request = null;
+ if (ev.data === 'create') {
+ try {
+ request = new PresentationRequest(urls);
+ parent.window.postMessage('success', '*');
+ }
+ catch (err) {
+ parent.window.postMessage(err.name, '*');
+ }
+ }
+ else if (ev.data === 'start') {
+ request = new PresentationRequest(urls);
+ request.start()
+ .then(function () {
+ parent.window.postMessage('success', '*');
+ })
+ .catch(function (err) {
+ if ((err.name === 'NotFoundError') ||
+ (err.name === 'NotAllowedError')) {
+ // These errors either mean that the user dismissed the dialog
+ // box or that the UA could not find any available or suitable
+ // screen. This is equivalent of succeeding for the purpose of
+ // iframe tests.
+ parent.window.postMessage('success', '*');
+ }
+ else {
+ parent.window.postMessage(err.name, '*');
+ }
+ });
+ }
+ else if (ev.data === 'reconnect') {
+ request = new PresentationRequest(urls);
+ request.reconnect('someid')
+ .then(function () {
+ parent.window.postMessage('success', '*');
+ })
+ .catch(function (err) {
+ parent.window.postMessage(err.name, '*');
+ });
+ }
+ else if (ev.data.match(/^reconnect\?id=(.*)$/)) {
+ promise_test(function (t) {
+ var presentationId = RegExp.$1;
+ var phase = -1, actual = -1, connection, waitConnection;
+ var description = [
+ "Phase #1: Promise is resolved",
+ "Phase #2: 'connectionavailable' event fired",
+ "Phase #3: 'connect' event fired"
+ ].map(d => { return '(Reconnecting in a nested browsing context) ' + d; });
+
+ var count = function(evt) { actual++; return evt; };
+ var checkPhase = function(evt) {
+ phase++;
+ assert_equals(description[actual], description[phase], 'Event order is incorrect.');
+ return evt;
+ };
+
+ request = new PresentationRequest(urls);
+
+ var eventWatcher = new EventWatcher(t, request, 'connectionavailable');
+ var waitConnectionavailable = eventWatcher.wait_for('connectionavailable').then(count).then(function (evt) {
+ connection = connection || evt.connection; return evt;
+ });
+
+ return request.reconnect(presentationId).then(count).then(checkPhase).then(function (c) {
+ // Reconnecting Phase #1: Promise is resolved
+ connection = c;
+ assert_equals(connection.state, 'connecting', 'Check the initial state of the presentation connection.');
+ assert_equals(connection.id, presentationId, "The same presentation ID is set to the newly created presentation connection.");
+ assert_true(connection instanceof PresentationConnection, 'The connection is an instance of PresentationConnection.');
+
+ var eventWatcher = new EventWatcher(t, connection, 'connect');
+ waitConnect = eventWatcher.wait_for('connect').then(count);
+
+ // Reconnecting Phase #2: "connectionavailable" event is fired
+ return waitConnectionavailable;
+ }).then(checkPhase).then(function (evt) {
+ assert_true(evt instanceof PresentationConnectionAvailableEvent, 'An event using PresentationConnectionAvailableEvent is fired.');
+ assert_true(evt.isTrusted, 'The event is a trusted event.');
+ assert_false(evt.bubbles, 'The event does not bubbles.');
+ assert_false(evt.cancelable, 'The event is not cancelable.');
+ assert_equals(evt.type, 'connectionavailable', 'The event name is "connectionavailable".');
+ assert_equals(evt.target, request, 'event.target is the presentation request.');
+ assert_true(evt.connection instanceof PresentationConnection, 'event.connection is a presentation connection.');
+ assert_equals(evt.connection, connection, 'event.connection is set to the presentation which the promise is resolved with.');
+
+ // Reconnecting Phase #3: "connect" event is fired
+ return waitConnect;
+ }).then(checkPhase).then(function (evt) {
+ assert_true(evt.isTrusted && !evt.bubbles && !evt.cancelable && evt instanceof Event, 'A simple event is fired.');
+ assert_equals(evt.type, 'connect', 'The event name is "connect".');
+ assert_equals(evt.target, connection, 'event.target is the presentation connection.');
+ assert_equals(connection.state, 'connected', 'The presentation connection state is set to "connected".');
+ parent.window.postMessage({ type: 'presentation-api', test: { status: 0 } }, '*');
+ var terminateWatcher = new EventWatcher(t, connection, 'terminate');
+
+ // "terminate" event is fired
+ return terminateWatcher.wait_for('terminate');
+ }).then(function (evt) {
+ assert_true(evt.isTrusted && !evt.bubbles && !evt.cancelable && evt instanceof Event, 'A simple event is fired.');
+ assert_equals(evt.type, 'terminate', 'The event name is "terminate".');
+ assert_equals(evt.target, connection, 'event.target is the presentation connection.');
+ assert_equals(connection.state, 'terminated', 'The presentation connection state is set to "terminated".');
+ });
+ });
+ }
+ else if (ev.data.match(/^terminate\?id=(.*)$/)) {
+ var presentationId = RegExp.$1;
+ request = new PresentationRequest(urls);
+ request.reconnect(presentationId)
+ .then(function (c) {
+ parent.window.postMessage('reconnected', '*');
+ c.onterminate = function(evt) {
+ parent.window.postMessage({
+ isSimpleEvent: evt.isTrusted && !evt.bubbles && !evt.cancelable && evt instanceof Event,
+ type: evt.type,
+ checkConnection: evt.target === c,
+ state: c.state
+ }, '*');
+ };
+ })
+ .catch(function (err) {
+ parent.window.postMessage(err.name, '*');
+ });
+ }
+ else if (ev.data === 'getAvailability') {
+ request = new PresentationRequest(urls);
+ request.getAvailability()
+ .then(function () {
+ parent.window.postMessage('success', '*');
+ })
+ .catch(function (err) {
+ if (err.name === 'NotSupportedError') {
+ parent.window.postMessage('success', '*');
+ }
+ else {
+ parent.window.postMessage(err.name, '*');
+ }
+ });
+ }
+ }
+ catch (err) {
+ parent.window.postMessage('Could not create PresentationRequest', '*');
+ }
+ }
+ parent.window.postMessage('ready', '*');
+</script>
+
diff --git a/testing/web-platform/tests/presentation-api/controlling-ua/support/presentation.html b/testing/web-platform/tests/presentation-api/controlling-ua/support/presentation.html
new file mode 100644
index 0000000000..8ad838062f
--- /dev/null
+++ b/testing/web-platform/tests/presentation-api/controlling-ua/support/presentation.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+
+<meta charset="utf-8">
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="author" title="He Yue" href="mailto:yue.he@intel.com">
+<link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/">
+<link rel="help" href="http://w3c.github.io/presentation-api/#interface-presentationconnectionlist">
+<script src="../common.js"></script>
+<script src="stash.js"></script>
+<script>
+ const message1 = '1st';
+ const message2 = '2nd';
+ const message3 = new Uint8Array([51, 114, 100]); // "3rd"
+ const message4 = new Uint8Array([52, 116, 104]); // "4th"
+ const message5 = new Uint8Array([108, 97, 115, 116]); // "last"
+
+ const toUint8Array = buf => {
+ return buf instanceof ArrayBuffer ? new Uint8Array(buf) : buf;
+ }
+
+ // convert ArrayBuffer or Uint8Array into string
+ const toText = buf => {
+ const arr = toUint8Array(buf);
+ return !buf ? null : arr.reduce((result, item) => {
+ return result + String.fromCharCode(item);
+ }, '');
+ }
+
+ // compare two ArrayBuffer or Uint8Array
+ const compare = (a, b) => {
+ const p = toUint8Array(a);
+ const q = toUint8Array(b);
+ return !!p && !!q && p.every((item, index) => { return item === q[index]; });
+ };
+
+ const stash = new Stash(stashIds.toReceiver, stashIds.toController);
+
+ let connection, count = 0;
+
+ const addConnection = c => {
+ let result = [], testCase;
+ connection = c;
+ count++;
+
+ connection.onmessage = event => {
+ // PresentationConnection_send-manual.https.html
+ if (testCase === 'send') {
+ if (typeof event.data === 'string') {
+ result.push({ type: 'text', data: event.data });
+ }
+ // default value of connection.binaryType is "arraybuffer"
+ else if(event.data instanceof ArrayBuffer) {
+ result.push({ type: 'binary', data: toText(event.data) });
+ if (compare(event.data, message5)) {
+ stash.send(JSON.stringify(result));
+ }
+ }
+ else {
+ result.push({ type: 'error' });
+ }
+ }
+ };
+
+ stash.receive().then(data => {
+ testCase = data;
+
+ // PresentationConnection_send-manual.https.html
+ if (testCase === 'send') {
+ stash.send('ok');
+ }
+ // PresentationConnection_onmessage-manual.https.html
+ else if (testCase === 'onmessage') {
+ connection.send(message1); // string
+ connection.send(message2); // string
+ connection.send(new Blob([message3])); // Blob
+ connection.send(message4.buffer); // ArrayBuffer
+ connection.send(message5); // ArrayBufferView
+ stash.receive().then(data => {
+ connection.send(message5);
+ });
+ }
+ // PresentationConnection_onclose-manual.https.html
+ else if (testCase === 'close') {
+ connection.close();
+ }
+ });
+ };
+
+ navigator.presentation.receiver.connectionList
+ .then(list => {
+ list.onconnectionavailable = evt => {
+ addConnection(evt.connection);
+ };
+ list.connections.map(connection => {
+ addConnection(connection);
+ });
+ });
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.js b/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.js
new file mode 100644
index 0000000000..616907d4f2
--- /dev/null
+++ b/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.js
@@ -0,0 +1,83 @@
+var Stash = function(inbound, outbound) {
+ this.stashPath = '/presentation-api/controlling-ua/support/stash.py?id=';
+ this.inbound = inbound;
+ this.outbound = outbound;
+}
+
+// initialize a stash on wptserve
+Stash.prototype.init = function() {
+ return Promise.all([
+ fetch(this.stashPath + this.inbound).then(response => {
+ return response.text();
+ }),
+ fetch(this.stashPath + this.outbound).then(response => {
+ return response.text();
+ })
+ ]);
+}
+
+// upload a test result to a stash on wptserve
+Stash.prototype.send = function(result) {
+ return fetch(this.stashPath + this.outbound, {
+ method: 'POST',
+ body: JSON.stringify({ type: 'data', data: result })
+ }).then(response => {
+ return response.text();
+ }).then(text => {
+ return text === 'ok' ? null : Promise.reject();
+ })
+};
+
+// wait until a test result is uploaded to a stash on wptserve
+Stash.prototype.receive = function() {
+ return new Promise((resolve, reject) => {
+ let intervalId;
+ const interval = 500; // msec
+ const polling = () => {
+ return fetch(this.stashPath + this.inbound).then(response => {
+ return response.text();
+ }).then(text => {
+ if (text) {
+ try {
+ const json = JSON.parse(text);
+ if (json.type === 'data')
+ resolve(json.data);
+ else
+ reject();
+ } catch(e) {
+ resolve(text);
+ }
+ clearInterval(intervalId);
+ }
+ });
+ };
+ intervalId = setInterval(polling, interval);
+ });
+};
+
+// reset a stash on wptserve
+Stash.prototype.stop = function() {
+ return Promise.all([
+ fetch(this.stashPath + this.inbound).then(response => {
+ return response.text();
+ }),
+ fetch(this.stashPath + this.outbound).then(response => {
+ return response.text();
+ })
+ ]).then(() => {
+ return Promise.all([
+ fetch(this.stashPath + this.inbound, {
+ method: 'POST',
+ body: JSON.stringify({ type: 'stop' })
+ }).then(response => {
+ return response.text();
+ }),
+ fetch(this.stashPath + this.outbound, {
+ method: 'POST',
+ body: JSON.stringify({ type: 'stop' })
+ }).then(response => {
+ return response.text();
+ })
+ ]);
+ });
+}
diff --git a/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.py b/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.py
new file mode 100644
index 0000000000..83653d365a
--- /dev/null
+++ b/testing/web-platform/tests/presentation-api/controlling-ua/support/stash.py
@@ -0,0 +1,10 @@
+def main(request, response):
+ key = request.GET.first(b"id")
+
+ if request.method == u"POST":
+ request.server.stash.put(key, request.body)
+ return b"ok"
+ else:
+ value = request.server.stash.take(key)
+ assert request.server.stash.take(key) is None
+ return value \ No newline at end of file