diff --git a/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js b/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js new file mode 100644 index 000000000000000..320803adec29361 --- /dev/null +++ b/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js @@ -0,0 +1,19 @@ +// META: title=Testing BFCache support for page with closed WebRTC connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webrtc-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebRTC(rc1); + // The page should be eligible for BFCache because the WebRTC connection is closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +}); diff --git a/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js b/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js new file mode 100644 index 000000000000000..4a4807d5141123c --- /dev/null +++ b/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js @@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with open WebRTC connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webrtc-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebRTC(rc1); + // The page should not be eligible for BFCache because of open WebRTC connection. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['WebRTC']); +}); diff --git a/webrtc/resources/webrtc-test-helpers.sub.js b/webrtc/resources/webrtc-test-helpers.sub.js new file mode 100644 index 000000000000000..48882b30ccc263c --- /dev/null +++ b/webrtc/resources/webrtc-test-helpers.sub.js @@ -0,0 +1,79 @@ +// SDP copied from JSEP Example 7.1 +// It contains two media streams with different ufrags +// to test if candidate is added to the correct stream +const sdp = `v=0 +o=- 4962303333179871722 1 IN IP4 0.0.0.0 +s=- +t=0 0 +a=ice-options:trickle +a=group:BUNDLE a1 v1 +a=group:LS a1 v1 +m=audio 10100 UDP/TLS/RTP/SAVPF 96 0 8 97 98 +c=IN IP4 203.0.113.100 +a=mid:a1 +a=sendrecv +a=rtpmap:96 opus/48000/2 +a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=rtpmap:97 telephone-event/8000 +a=rtpmap:98 telephone-event/48000 +a=maxptime:120 +a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid +a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level +a=msid:47017fee-b6c1-4162-929c-a25110252400 f83006c5-a0ff-4e0a-9ed9-d3e6747be7d9 +a=ice-ufrag:ETEn +a=ice-pwd:OtSK0WpNtpUjkY4+86js7ZQl +a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2 +a=setup:actpass +a=dtls-id:1 +a=rtcp:10101 IN IP4 203.0.113.100 +a=rtcp-mux +a=rtcp-rsize +m=video 10102 UDP/TLS/RTP/SAVPF 100 101 +c=IN IP4 203.0.113.100 +a=mid:v1 +a=sendrecv +a=rtpmap:100 VP8/90000 +a=rtpmap:101 rtx/90000 +a=fmtp:101 apt=100 +a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid +a=rtcp-fb:100 ccm fir +a=rtcp-fb:100 nack +a=rtcp-fb:100 nack pli +a=msid:47017fee-b6c1-4162-929c-a25110252400 f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0 +a=ice-ufrag:BGKk +a=ice-pwd:mqyWsAjvtKwTGnvhPztQ9mIf +a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2 +a=setup:actpass +a=dtls-id:1 +a=rtcp:10103 IN IP4 203.0.113.100 +a=rtcp-mux +a=rtcp-rsize +`; + +const sessionDesc = { type: 'offer', sdp }; +const candidate = { + candidate: 'candidate:1 1 udp 2113929471 203.0.113.100 10100 typ host', + sdpMid: 'a1', + sdpMLineIndex: 0, + usernameFragment: 'ETEn' +}; + +// Opens a new WebRTC connection. +async function openWebRTC(remoteContextHelper) { + await remoteContextHelper.executeScript(async (sessionDesc, candidate) => { + const testRTCPeerConnection = new RTCPeerConnection(); + await testRTCPeerConnection.setRemoteDescription(sessionDesc); + await testRTCPeerConnection.addIceCandidate(candidate); + }, [sessionDesc, candidate]); +} + +// Opens a new WebRTC connection and then close it. +async function openThenCloseWebRTC(remoteContextHelper) { + await remoteContextHelper.executeScript(async (sessionDesc, candidate) => { + const testRTCPeerConnection = new RTCPeerConnection(); + await testRTCPeerConnection.setRemoteDescription(sessionDesc); + await testRTCPeerConnection.addIceCandidate(candidate); + testRTCPeerConnection.close(); + }, [sessionDesc, candidate]); +} diff --git a/websockets/back-forward-cache-with-closed-websocket-connection.window.js b/websockets/back-forward-cache-with-closed-websocket-connection.window.js new file mode 100644 index 000000000000000..30b8e63a2cd595d --- /dev/null +++ b/websockets/back-forward-cache-with-closed-websocket-connection.window.js @@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with closed WebSocket connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: script=resources/websockets-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebSocket(rc1); + // The page should be eligible for BFCache because the WebSocket connection has been closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +}); diff --git a/websockets/back-forward-cache-with-open-websocket-connection.window.js b/websockets/back-forward-cache-with-open-websocket-connection.window.js new file mode 100644 index 000000000000000..2baf38f303c3dfd --- /dev/null +++ b/websockets/back-forward-cache-with-open-websocket-connection.window.js @@ -0,0 +1,21 @@ +// META: title=Testing BFCache support for page with open WebSocket connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: script=resources/websockets-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebSocket(rc1); + // The page should not be eligible for BFCache because of open WebSocket connection. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['WebSocket']); +}); diff --git a/websockets/resources/websockets-test-helpers.sub.js b/websockets/resources/websockets-test-helpers.sub.js new file mode 100644 index 000000000000000..2680670cc691b14 --- /dev/null +++ b/websockets/resources/websockets-test-helpers.sub.js @@ -0,0 +1,25 @@ +// The file including this must also include `/websockets/constants.sub.js to +// pick up the necessary constants. + +// Opens a new WebSocket connection. +async function openWebSocket(remoteContextHelper) { + let return_value = await remoteContextHelper.executeScript((domain) => { + return new Promise((resolve) => { + var webSocketInNotRestoredReasonsTests = new WebSocket(domain + '/echo'); + webSocketInNotRestoredReasonsTests.onopen = () => { resolve(42); }; + }); + }, [SCHEME_DOMAIN_PORT]); + assert_equals(return_value, 42); +} + +// Opens a new WebSocket connection and then close it. +async function openThenCloseWebSocket(remoteContextHelper) { + let return_value = await remoteContextHelper.executeScript((domain) => { + return new Promise((resolve) => { + var testWebSocket = new WebSocket(domain + '/echo'); + testWebSocket.onopen = () => { testWebSocket.close() }; + testWebSocket.onclose = () => { resolve(42) }; + }); + }, [SCHEME_DOMAIN_PORT]); + assert_equals(return_value, 42); +} diff --git a/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js b/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js new file mode 100644 index 000000000000000..5cc7e93a2e14d54 --- /dev/null +++ b/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js @@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with closed WebTransport connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webtransport-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebTransport(rc1); + // The page should be eligible for BFCache because the WebTransport connection is closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +}); diff --git a/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js b/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js new file mode 100644 index 000000000000000..5d5143ae1a47811 --- /dev/null +++ b/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js @@ -0,0 +1,25 @@ +// META: title=Testing BFCache support for page with open WebTransport connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webtransport-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebTransport(rc1); + // The page should be eligible for BFCache and the WebTransport connection + // should be closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); + await rc1.executeScript(async () => { + assert_false(window.testWebTransport === undefined); + await window.testWebTransport.closed; + }); +}); diff --git a/webtransport/resources/webtransport-test-helpers.sub.js b/webtransport/resources/webtransport-test-helpers.sub.js index 9f9127b22f96da1..36788699e8bbbef 100644 --- a/webtransport/resources/webtransport-test-helpers.sub.js +++ b/webtransport/resources/webtransport-test-helpers.sub.js @@ -110,3 +110,24 @@ async function readInto(reader, buffer) { return buffer; } + +// Opens a new WebTransport connection. +async function openWebTransport(remoteContextHelper) { + const url = webtransport_url('custom-response.py?:status=200'); + await remoteContextHelper.executeScript((url) => { + window.testWebTransport = new WebTransport(url); + return window.testWebTransport.ready; + }, [url]); +} + +// Opens a new WebTransport connection and then close it. +async function openThenCloseWebTransport(remoteContextHelper) { + const url = webtransport_url('custom-response.py?:status=200'); + await remoteContextHelper.executeScript((url) => { + window.testWebTransport = new WebTransport(url); + return window.testWebTransport.ready.then(async () => { + window.testWebTransport.close(); + await window.testWebTransport.closed; + }); + }, [url]); +}