blob: 07df5fef733c1bf38d43f63442a724552d1aae85 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* The last file list loaded into the guest, updated via a spy on loadFiles().
* @type {?ReceivedFileList}
*/
let lastReceivedFileList = null;
/**
* Test cases registered by GUEST_TEST.
* @type {!Map<string, function(): !Promise<undefined>>}
*/
const guestTestCases = new Map();
/**
* @return {!mediaApp.AbstractFile}
*/
function firstReceivedItem() {
return assertCast(assertCast(lastReceivedFileList).item(0));
}
/**
* Acts on received TestMessageQueryData.
* @param {!TestMessageQueryData} data
* @return {!Promise<!TestMessageResponseData>}
*/
async function runTestQuery(data) {
let result = 'no result';
let extraResultData;
if (data.testQuery) {
const element = await waitForNode(data.testQuery, data.pathToRoot || []);
result = element.tagName;
if (data.property) {
result = JSON.stringify(element[data.property]);
} else if (data.requestFullscreen) {
try {
await element.requestFullscreen();
result = 'hooray';
} catch (/** @type {!TypeError} */ typeError) {
result = typeError.message;
}
}
} else if (data.navigate !== undefined) {
if (data.navigate === 'next') {
await assertCast(lastReceivedFileList).loadNext();
result = 'loadNext called';
} else if (data.navigate === 'prev') {
await assertCast(lastReceivedFileList).loadPrev();
result = 'loadPrev called';
} else {
result = 'nothing called';
}
} else if (data.overwriteLastFile) {
const testBlob = new Blob([data.overwriteLastFile]);
extraResultData = await assertCast(firstReceivedItem().overwriteOriginal)
.call(firstReceivedItem(), testBlob);
result = 'overwriteOriginal resolved';
} else if (data.deleteLastFile) {
try {
const deleteResult =
await assertCast(firstReceivedItem().deleteOriginalFile)
.call(firstReceivedItem());
if (deleteResult === DeleteResult.FILE_MOVED) {
result = 'deleteOriginalFile resolved file moved';
} else {
result = 'deleteOriginalFile resolved success';
}
} catch (/** @type{!Error} */ error) {
result = `deleteOriginalFile failed Error: ${error}`;
}
} else if (data.renameLastFile) {
try {
const renameResult =
await assertCast(firstReceivedItem().renameOriginalFile)
.call(firstReceivedItem(), data.renameLastFile);
if (renameResult === RenameResult.FILE_EXISTS) {
result = 'renameOriginalFile resolved file exists';
} else {
result = 'renameOriginalFile resolved success';
}
} catch (/** @type{!Error} */ error) {
result = `renameOriginalFile failed Error: ${error}`;
}
} else if (data.saveCopy) {
const existingFile = assertCast(lastReceivedFileList).item(0);
if (!existingFile) {
result = 'saveCopy failed, no file loaded';
} else {
DELEGATE.saveCopy(existingFile);
result = 'boo yah!';
}
} else if (data.getFileErrors) {
result =
assertCast(lastReceivedFileList).files.map(file => file.error).join();
}
return {testQueryResult: result, testQueryResultData: extraResultData};
}
/**
* Acts on TestMessageRunTestCase.
* @param {!TestMessageRunTestCase} data
* @return {!Promise<!TestMessageResponseData>}
*/
async function runTestCase(data) {
const testCase = guestTestCases.get(data.testCase);
if (!testCase) {
throw new Error(`Unknown test case: '${data.testCase}'`);
}
await testCase(); // Propate exceptions to the MessagePipe handler.
return {testQueryResult: 'success'};
}
/**
* Registers a test that runs in the guest context. To indicate failure, the
* test throws an exception (e.g. via assertEquals).
* @param {string} testName
* @param {function(): !Promise<undefined>} testCase
*/
function GUEST_TEST(testName, testCase) {
guestTestCases.set(testName, testCase);
}
/**
* Tells the test driver the guest test message handlers are installed. This
* requires the test handler that receives the signal to be set up. The order
* that this occurs can not be guaranteed. So this function retries until the
* signal is handled, which requires the 'test-handlers-ready' handler to be
* registered in driver.js.
*/
async function signalTestHandlersReady() {
const EXPECTED_ERROR =
`No handler registered for message type 'test-handlers-ready'`;
while (true) {
try {
await parentMessagePipe.sendMessage('test-handlers-ready', {});
return;
} catch (/** @type {!GenericErrorResponse} */ e) {
if (e.message !== EXPECTED_ERROR) {
console.error('Unexpected error in signalTestHandlersReady', e);
return;
}
}
}
}
/** Installs the MessagePipe handlers for receiving test queries. */
function installTestHandlers() {
parentMessagePipe.registerHandler('test', (data) => {
return runTestQuery(/** @type {!TestMessageQueryData} */ (data));
});
// Turn off error rethrowing for tests so the test runner doesn't mark
// our error handling tests as failed.
parentMessagePipe.rethrowErrors = false;
// Handler that will always error for helping to test the message pipe
// itself.
parentMessagePipe.registerHandler('bad-handler', () => {
throw Error('This is an error');
});
parentMessagePipe.registerHandler('run-test-case', (data) => {
return runTestCase(/** @type{!TestMessageRunTestCase} */ (data));
});
parentMessagePipe.registerHandler('get-last-loaded-files', () => {
// Note: the `ReceivedFileList` has methods stripped since it gets sent
// over a pipe so just send the underlying files.
return /** @type {!LastLoadedFilesResponse} */ (
{fileList: assertCast(lastReceivedFileList).files});
});
// Log errors, rather than send them to console.error. This allows the error
// handling tests to work correctly, and is also required for
// signalTestHandlersReady() to operate without failing tests.
parentMessagePipe.logClientError = error =>
console.log(JSON.stringify(error));
// Install spies.
const realLoadFiles = loadFiles;
/**
* @param {!ReceivedFileList} fileList
* @return {!Promise<undefined>}
*/
async function watchLoadFiles(fileList) {
lastReceivedFileList = fileList;
return realLoadFiles(fileList);
}
loadFiles = watchLoadFiles;
signalTestHandlersReady();
}
// Ensure content and all scripts have loaded before installing test handlers.
if (document.readyState !== 'complete') {
window.addEventListener('load', installTestHandlers);
} else {
installTestHandlers();
}
//# sourceURL=guest_query_receiver.js