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