blob: 8a6ebb10a694246aef2ad720ee0b1aba0d3780a4 [file] [log] [blame]
(async function(testRunner) {
var {page, session, dp} = await testRunner.startURL(
'http://first.test:8000/inspector-protocol/resources/test-page.html',
`Tests the order in which unfinished Runtime.{enable,evaluate} calls are handled around paused navigation.`);
// Unlike eval-avait-navigation-message-order.js, this test uses
// the Fetch domain to pause navigation; in this way we can send additional
// commands during the pause and observe how they're handled when navigation
// completes.
// Runtime.enable so we can capture console.log below. This command completes.
await dp.Runtime.enable();
dp.Runtime.onConsoleAPICalled(e => { testRunner.log(e.params.args[0].value); });
const callIdsToWatch = new Set();
// Creates a promise which doesn't resolve, so therefore, we won't get a
// response - only once we've navigated below, we'll get an error response
// due to command termination. Request ID will be call_id.
async function createNonResolvingPromise(call_id) {
const saveRequestId = DevToolsAPI._requestId;
DevToolsAPI._requestId = call_id - 1;
dp.Runtime.evaluate({
expression: `new Promise(() => console.log('promise created (` + call_id + `)'))`,
awaitPromise: true
});
DevToolsAPI._requestId = saveRequestId;
await dp.Runtime.onceConsoleAPICalled(); // Be sure to capture the log.
callIdsToWatch.add(call_id);
}
// Override the dispatch routine so we can intercept and log the responses in
// the order in which they arrive.
const originalDispatch = DevToolsAPI.dispatchMessage;
DevToolsAPI.dispatchMessage = function(message) {
var obj = JSON.parse(message);
if (callIdsToWatch.has(obj.id)) {
testRunner.log(obj, 'receiving result ' + obj.id + ':\n', ['sessionId']);
}
originalDispatch(message);
}
// Now create three promises with out-of-order call ids.
await createNonResolvingPromise(100021);
await createNonResolvingPromise(100013);
await createNonResolvingPromise(100017);
// This makes it so that we'll get a Fetch.requestPaused event after
// issuing page.navigate below.
await dp.Fetch.enable();
// Navigate, this causes the error notifications to arrive - in the same order
// in which the original requests were sent.
const navigatePromise = page.navigate('http://second.test:8000/inspector-protocol/resources/test-page.html');
const requestId = (await dp.Fetch.onceRequestPaused()).params.requestId;
// The DevToolsSession is now in suspended state. Messages will be queued
// but not executed until after the navigation is unpaused and completes.
// Send three Runtime.enable commands with specific command ids.
// We'll observe that these commands complete in the order in which they
// were issued, after the navigation is unpaused.
const saveRequestId = DevToolsAPI._requestId;
DevToolsAPI._requestId = 100090;
callIdsToWatch.add(100091);
dp.Runtime.enable();
DevToolsAPI._requestId = 100080;
callIdsToWatch.add(100081);
dp.Runtime.enable();
DevToolsAPI._requestId = 100085;
callIdsToWatch.add(100086);
dp.Runtime.enable();
// If we issue commands that are not idempotent, that is, commands
// that would get terminated on cross process navigation, while a navigation
// is paused, they'll get queued and issued after the navigation (just
// like Runtime.enable above).
DevToolsAPI._requestId = 100098;
callIdsToWatch.add(100099);
dp.Runtime.evaluate({
expression: `console.log('Hi from request 10099!')`, awaitPromise: true
});
DevToolsAPI._requestId = saveRequestId;
testRunner.log('Unpausing navigation ...');
await dp.Fetch.continueRequest({requestId});
await navigatePromise;
testRunner.completeTest();
})