tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

PresentationConnection_onterminate-manual.https.html (6766B)


      1 <!DOCTYPE html>
      2 
      3 <meta charset="utf-8">
      4 <title>Terminating a presentation in a controlling browsing context</title>
      5 <link rel="author" title="Intel" href="http://www.intel.com">
      6 <link rel="author" title="Chunyan Wang" href="mailto:chunyanx.wang@intel.com">
      7 <link rel="author" title="Tomoyuki Shimizu" href="https://github.com/tomoyukilabs/">
      8 <link rel="help" href="https://w3c.github.io/presentation-api/#terminating-a-presentation-in-a-controlling-browsing-context">
      9 <script src="/resources/testharness.js"></script>
     10 <script src="/resources/testharnessreport.js"></script>
     11 <script src="common.js"></script>
     12 <style>iframe { display: none; }</style>
     13 <p>
     14  Click the button below and select the available presentation display, to start the manual test. The test passes if a "PASS" result appears.<br>
     15  This test asks you to click the button twice, unless the test fails.<br>
     16 </p>
     17 <button id="presentBtn">Start Presentation Test</button>
     18 <iframe id="childFrame" src="support/iframe.html"></iframe>
     19 
     20 <script>
     21  setup({explicit_timeout: true});
     22  const presentBtn = document.getElementById('presentBtn');
     23  const childFrame = document.getElementById('childFrame');
     24 
     25  promise_test(t => {
     26    const clickWatcher = new EventWatcher(t, presentBtn, 'click');
     27    const messageWatcher = new EventWatcher(t, window, 'message');
     28    const request = new PresentationRequest(presentationUrls);
     29    let connection, eventWatcher, timeout;
     30 
     31    t.add_cleanup(() => {
     32      if (connection) {
     33        connection.onconnect = () => { connection.terminate(); };
     34        if (connection.state === 'closed')
     35          request.reconnect(connection.id);
     36        else
     37          connection.terminate();
     38      }
     39    });
     40 
     41    const startTimeout = () => {
     42      timeout = t.step_timeout(() => {
     43          t.force_timeout();
     44          t.done();
     45      }, 10000);
     46    };
     47 
     48    const checkTerminateEvent = evt => {
     49      assert_true(evt.isTrusted && !evt.bubbles && !evt.cancelable && evt instanceof Event, 'A simple event is fired.');
     50      assert_equals(evt.type, 'terminate', 'The event name is "terminate".');
     51      assert_equals(evt.target, connection, 'event.target is the presentation connection.');
     52      assert_equals(connection.state, 'terminated', 'State of the presentation connection is "terminated".');
     53    };
     54 
     55    const watchEvent = (obj, watcher, type) => {
     56      const watchHandler = new Promise(resolve => {
     57        obj['on' + type] = evt => { resolve(evt); };
     58      });
     59      return Promise.all([ watchHandler, watcher.wait_for(type) ]).then(results => {
     60        assert_equals(results[0], results[1], 'Both on' + type + ' and addEventListener pass the same event object.');
     61        return results[0];
     62      });
     63    };
     64 
     65    const waitForEvent = (obj, watcher, type) => {
     66      const watchHandler = new Promise(resolve => {
     67        obj['on' + type] = evt => { resolve(evt); };
     68      });
     69      return Promise.race([ watchHandler, watcher.wait_for(type) ]);
     70    };
     71 
     72    return Promise.all([
     73      clickWatcher.wait_for('click'),
     74      messageWatcher.wait_for('message')
     75    ]).then(() => {
     76      presentBtn.disabled = true;
     77 
     78      return request.start();
     79    }).then(c => {
     80      startTimeout();
     81 
     82      connection = c;
     83      eventWatcher = new EventWatcher(t, connection, 'terminate');
     84 
     85      // Step 1: terminate the presentation when the presentation connection is in "connecting" state
     86      connection.terminate();
     87      return Promise.race([
     88        new Promise((_, reject) => {
     89          t.step_timeout(() => { reject('The presentation is not terminated successfully when the presentation connection in "connecting" state.'); }, 3000);
     90        }),
     91        watchEvent(connection, eventWatcher, 'terminate')
     92      ]);
     93    }).then(evt => {
     94      checkTerminateEvent(evt);
     95 
     96      // Step 2: terminate the presentation when the presentation connection is in "closed" state (nothing should happen)
     97      presentBtn.textContent = 'Continue Presentation Test';
     98      presentBtn.disabled = false;
     99      clearTimeout(timeout);
    100      return clickWatcher.wait_for('click');
    101    }).then(() => {
    102      return request.start();
    103    }).then(c => {
    104      startTimeout();
    105      connection = c;
    106      eventWatcher = new EventWatcher(t, connection, ['connect', 'close', 'terminate']);
    107      return eventWatcher.wait_for('connect');
    108    }).then(() => {
    109      connection.close();
    110      return eventWatcher.wait_for('close');
    111    }).then(() => {
    112      const terminateWatcher = new EventWatcher(t, connection, 'terminate');
    113      connection.terminate();
    114      return Promise.race([
    115        new Promise(resolve => { t.step_timeout(resolve, 1000); }),
    116        waitForEvent(connection, terminateWatcher, 'terminate').then(() => {
    117          assert_unreached('Invoking PresentationConnection.terminate() in the "closed" state causes nothing.'); })
    118      ]);
    119    }).then(() => {
    120      // Step 3: terminate the presentation when the presentation connection is in "connected" state;
    121      // this step also checks an event fired at another presentation connection in a nested browsing context
    122      return request.reconnect(connection.id);
    123    }).then(() => {
    124      return eventWatcher.wait_for('connect');
    125    }).then(() => {
    126      childFrame.contentWindow.postMessage('terminate?id=' + connection.id, '*');
    127      return messageWatcher.wait_for('message')
    128    }).then(() => {
    129      connection.terminate();
    130      return Promise.race([
    131        new Promise((_, reject) => {
    132          t.step_timeout(() => { reject('The presentation is not terminated successfully when the presentation connection in "connected" state.'); }, 3000);
    133        }),
    134        Promise.all([
    135          watchEvent(connection, eventWatcher, 'terminate'),
    136          messageWatcher.wait_for('message')
    137        ])
    138      ]);
    139    }).then(results => {
    140      checkTerminateEvent(results[0]);
    141      const evt = results[1].data;
    142      assert_true(evt.isSimpleEvent, 'A simple event is fired in a nested browsing context.');
    143      assert_equals(evt.type, 'terminate', 'The event name is "terminate".');
    144      assert_true(evt.checkConnection, 'event.target is the presentation connection.');
    145      assert_equals(evt.state, 'terminated', 'State of the presentation connection is "terminated".');
    146 
    147      // Step 4: terminate the presentation when the presentation connection is in "terminated" state (nothing should happen)
    148      const terminateWatcher = new EventWatcher(t, connection, 'terminate');
    149      connection.terminate();
    150      return Promise.race([
    151        new Promise(resolve => { t.step_timeout(resolve, 1000); }),
    152        waitForEvent(connection, terminateWatcher, 'terminate').then(() => {
    153          assert_unreached('Invoking PresentationConnection.terminate() in the "terminated" state causes nothing.'); })
    154      ]);
    155    });
    156  });
    157 </script>