| <!doctype html> |
| <meta charset="utf-8"> |
| <title>Navigation should not occur when `src` matches the location of a anscestor browsing context</title> |
| <script> |
| // Avoid recursion in non-conforming browsers |
| if (parent !== window && parent.title == window.title) { |
| window.stop(); |
| } |
| </script> |
| <script src="/resources/testharness.js"></script> |
| <script src="/resources/testharnessreport.js"></script> |
| <body> |
| <script> |
| /** |
| * This test uses the `beforeunload` event to detect navigation. Because that |
| * event is fired synchronously in response to "process the iframe attributes", |
| * a second "control" iframe may be used to verify cases where navigation |
| * should *not* occur. `Promise.race` ensures that tests complete as soon as |
| * possible. |
| * |
| * Although the specification dictates that the `beforeunload` event must be |
| * emitted synchronously during navigation, a number of user agents do not |
| * adhere to this requirement. WPT includes a dedicated test for synchronous |
| * emission of the event [1]. This test is authored to support non-standard |
| * behavior in order to avoid spuriously passing in those UAs. |
| * |
| * [1] https://github.com/web-platform-tests/wpt/pull/12343 |
| */ |
| 'use strict'; |
| |
| function when(target, eventName) { |
| return new Promise(function(resolve, reject) { |
| target.addEventListener(eventName, function() { |
| resolve(); |
| }, { once: true }); |
| target.addEventListener('error', function() { |
| reject(new Error('Error while waiting for ' + eventName)); |
| }, { once: true }); |
| }); |
| } |
| |
| function init(doc, t) { |
| var iframes = [doc.createElement('iframe'), doc.createElement('iframe')]; |
| |
| iframes.forEach(function(iframe) { |
| iframe.src = '/common/blank.html'; |
| doc.body.appendChild(iframe); |
| |
| t.add_cleanup(function() { |
| iframe.parentNode.removeChild(iframe); |
| }); |
| }); |
| |
| return Promise.all([when(iframes[0], 'load'), when(iframes[1], 'load')]) |
| .then(function() { return iframes; }); |
| } |
| |
| // This test verifies that navigation does occur; it is intended to validate |
| // the utility functions. |
| promise_test(function(t) { |
| return init(document, t) |
| .then(function(iframes) { |
| var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); |
| var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); |
| |
| iframes[0].src = '/common/blank.html?2'; |
| iframes[1].src = '/common/blank.html?3'; |
| |
| return Promise.all([subjectNavigation, controlNavigation]); |
| }); |
| }, 'different path name'); |
| |
| promise_test(function(t) { |
| return init(document, t) |
| .then(function(iframes) { |
| var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); |
| var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); |
| |
| iframes[0].src = location.href; |
| iframes[1].src = '/common/blank.html?4'; |
| |
| return Promise.race([ |
| subjectNavigation.then(function() { |
| assert_unreached('Should not navigate'); |
| }), |
| controlNavigation |
| ]); |
| }); |
| }, 'same path name, no document fragment'); |
| |
| promise_test(function(t) { |
| return init(document, t) |
| .then(function(iframes) { |
| var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); |
| var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); |
| |
| iframes[0].src = location.href + '#something-else'; |
| iframes[1].src = '/common/blank.html?5'; |
| |
| return Promise.race([ |
| subjectNavigation.then(function() { |
| assert_unreached('Should not navigate'); |
| }), |
| controlNavigation |
| ]); |
| }); |
| }, 'same path name, different document fragment'); |
| |
| promise_test(function(t) { |
| var intermediate = document.createElement('iframe'); |
| |
| document.body.appendChild(intermediate); |
| |
| t.add_cleanup(function() { |
| intermediate.parentNode.removeChild(intermediate); |
| }); |
| intermediate.contentDocument.open(); |
| intermediate.contentDocument.write('<body></body>'); |
| intermediate.contentDocument.close(); |
| |
| return init(intermediate.contentDocument, t) |
| .then(function(iframes) { |
| var subjectNavigation = when(iframes[0].contentWindow, 'beforeunload'); |
| var controlNavigation = when(iframes[1].contentWindow, 'beforeunload'); |
| |
| iframes[0].src = location.href; |
| iframes[1].src = '/common/blank.html?6'; |
| |
| return Promise.race([ |
| subjectNavigation.then(function() { |
| assert_unreached('Should not navigate'); |
| }), |
| controlNavigation |
| ]); |
| }); |
| }, 'same path name, no document fragement (intermediary browsing context)'); |
| </script> |
| </body> |