1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
<!DOCTYPE html>
<meta charset="utf-8">
<title>Reconnect to presentation success manual test</title>
<link rel="author" title="Marius Wessel" href="http://www.fokus.fraunhofer.de">
<link rel="author" title="Louay Bassbouss" href="http://www.fokus.fraunhofer.de">
<link rel="help" href="http://w3c.github.io/presentation-api/#dom-presentationrequest-reconnect">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="common.js"></script>
<style>iframe { display: none; }</style>
<p>Click the button below to start the manual test. Select a presentation device after the selection dialog is prompted.
The test assumes that at least one presentation device is available. The test passes if a "PASS" result appears.</p>
<button id="startBtn">Start Test</button>
<iframe id="childFrame" src="support/iframe.html"></iframe>
<script>
let receiverStack;
add_completion_callback(() => {
// overwrite a stack written in the test result
if (receiverStack) {
document.querySelector('#log pre').textContent = receiverStack;
}
});
// disable timeout for manual tests
setup({explicit_timeout: true});
const startBtn = document.getElementById('startBtn');
const childFrame = document.getElementById('childFrame');
promise_test(t => {
const startWatcher = new EventWatcher(t, startBtn, 'click');
const messageWatcher = new EventWatcher(t, window, 'message');
const request = new PresentationRequest(presentationUrls);
let connection, eventWatcher;
t.add_cleanup(() => {
if (connection) {
connection.onconnect = () => { connection.terminate(); }
if (connection.state === 'closed')
request.reconnect(connection.id);
else
connection.terminate();
}
});
const waitForMessage = () => {
return messageWatcher.wait_for('message').then(evt => {
return evt.data.type === 'presentation-api' ? evt : waitForMessage();
});
};
// handle a test result received from a nested browsing context
const parseValue = value => {
let r;
// String
if (r = value.match(/^(\(string\)\s+)?"(.*)"$/))
return r[2];
// Object
else if (r = value.match(/^(\(object\)\s+)?object\s+"\[object\s+(.*)\]"$/))
return window[r[2]].prototype;
// undefined
else if (value === "undefined")
return undefined;
// Number, boolean, null
else {
if (r = value.match(/^(\(\S+\)\s+)?(\S+)$/)) {
try {
return JSON.parse(r[2]);
} catch(e) {
return value;
}
}
else
return value;
}
};
const parseResult = t.step_func(evt => {
const result = evt.data;
if (result.test.status === 0)
return evt;
receiverStack = result.test.stack;
const message = result.test.message;
let r = message.match(/^(assert_.*):\s+(.*)$/);
if (r) {
const assertion = r[1];
const body = r[2];
let args;
if (assertion === 'assert_equals') {
if (r = body.match(/^((.*)\s+)?expected\s+((\(\S*\)\s+)?(\S+|(\S+\s+)?\".*\"))\s+but\s+got\s+((\(\S*\)\s+)?(\S+|(\S+\s+)?\".*\"))$/))
args = [parseValue(r[7]), parseValue(r[3]), r[2]];
}
else if (assertion === 'assert_true') {
if (r = body.match(/^((.*)\s+)?expected\s+(true|false)\s+got\s+(\S+|(\S+\s+)?\".*\")$/)) {
args = [parseValue(r[4]), r[2]];
}
}
else if (assertion === 'assert_unreached') {
if (r = body.match(/^((.*)\s+)?Reached\s+unreachable\s+code$/))
args = [r[2]];
}
if (args) {
window[assertion](args[0], args[1], args[2]);
return;
}
}
// default
assert_unreached('Test result received from a receiving user agent: ' + message + ': ');
});
return Promise.all([
startWatcher.wait_for('click'),
messageWatcher.wait_for('message')
]).then(() => {
startBtn.disabled = true;
let presentationId = null;
return request.start();
}).then(c => {
connection = c;
presentationId = connection.id;
// No more user input needed, re-enable test timeout
t.step_timeout(() => {
t.force_timeout();
t.done();
}, 5000);
eventWatcher = new EventWatcher(t, connection, ['connect', 'close', 'terminate']);
return Promise.all([
// Wait for "connect" event
eventWatcher.wait_for('connect'),
// Try to reconnect when the connection state is "connecting"
request.reconnect(presentationId).then(c => {
assert_equals(c, connection, 'The promise is resolved with the existing presentation connection.');
assert_equals(c.state, "connecting", "The connection state remains 'connecting'.");
assert_equals(c.id, presentationId, "The presentation ID is not changed.");
})
]);
}).then(() => {
// Try to reconnect when the connection state is "connected"
return request.reconnect(presentationId);
}).then(c => {
assert_equals(c, connection, 'The promise is resolved with the existing presentation connection.');
assert_equals(c.state, "connected", "The connection state remains 'connected'.");
assert_equals(c.id, presentationId, "The presentation ID is not changed.");
// Close connection and wait for "close" event
connection.close();
return eventWatcher.wait_for('close');
}).then(() => {
// Connection now closed, let's reconnect to it
return request.reconnect(presentationId);
}).then(c => {
// Check the presentation connection in "connecting" state
assert_equals(c, connection, 'The promise is resolved with the existing presentation connection.');
connection = c;
assert_equals(connection.state, "connecting", "The connection state is set to 'connecting'.");
assert_equals(connection.id, presentationId, "Ids of old and new connections must be equal.");
return eventWatcher.wait_for('connect');
}).then(evt => {
// Check the established presentation connection and its associated "connect" event
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".');
// Request an iframe to reconnect the presentation with the current presentation ID
childFrame.contentWindow.postMessage('reconnect?id=' + presentationId, '*');
return waitForMessage().then(parseResult);
}).then(() => {
// Wait until state of each presentation connection is set to "terminated"
connection.terminate();
return Promise.all([ eventWatcher.wait_for('terminate'), waitForMessage().then(parseResult) ]);
}).then(() => {
// Try to reconnect to the presentation, while all presentation connection have already been terminated
return promise_rejects_dom(t, 'NotFoundError', request.reconnect(presentationId),
'Reconnecting to a terminated presentation rejects a promise with a "NotFoundError" exception.');
});
});
</script>
|