blob: 9b784f51c3a35e32e8ade4ae5fe49cc20c05f0fb [file]
// Copyright 2011 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const RELATIVE_PATH = 'extensions/api_test/executescript/permissions/';
let port;
function fixPort(url) {
return url.replace(/PORT/, port);
}
chrome.test.runTests([
function setup() {
chrome.test.getConfig(function(config) {
port = config.testServer.port;
chrome.test.succeed();
});
},
// Test a race that used to occur here (see bug 30937).
// Open a tab that we're not allowed to execute in (c.com), then
// navigate it to a tab we *are* allowed to execute in (a.com),
// then quickly run script in the tab before it navigates. It
// should appear to work (no error -- it could have been a developer
// mistake), but not actually do anything.
function testRace() {
const testFile = `${RELATIVE_PATH}empty.html`;
const openUrl = `${fixPort('http://c.com:PORT/')}${testFile}`;
const executeUrl = `${fixPort('http://a.com:PORT/')}${testFile}`;
const expectedError = `Cannot access contents of url "${openUrl}". ` +
'Extension manifest must request permission to access this host.';
// This promise waits for the second URL to finish loading.
const tabLoadedPromise = new Promise((resolve) => {
chrome.tabs.onUpdated.addListener(
function listener(tabId, changeInfo, tab) {
if (tab.status === 'complete' && tab.url === executeUrl) {
chrome.tabs.onUpdated.removeListener(listener);
resolve();
}
});
});
// This promise waits for both the first URL to finish loading and
// the subsequent script execution to finish.
const executePromise = new Promise((resolve, reject) => {
chrome.tabs.onUpdated.addListener(
function listener(tabId, changeInfo, tab) {
if (tab.status === 'complete') {
chrome.tabs.onUpdated.removeListener(listener);
chrome.tabs.update(tab.id, {url: executeUrl});
chrome.tabs.executeScript(
tab.id, {file: 'script.js'}, function(results) {
if (results !== undefined || !chrome.runtime.lastError) {
reject('Unexpected success in execute callback');
} else if (
chrome.runtime.lastError.message !== expectedError) {
reject(`Unexpected error: ${
chrome.runtime.lastError.message}`);
} else {
resolve();
}
});
}
});
});
chrome.tabs.create({url: openUrl});
Promise.all([tabLoadedPromise, executePromise])
.then(() => {
chrome.test.succeed();
})
.catch((message) => {
console.info(message);
chrome.test.fail();
});
},
// Inject into all frames. This should only affect frames we have
// access to. This page has three subframes, one each from a.com,
// b.com, and c.com. We have access to two of those, plus the root
// frame, so we should get three responses.
function testAllFrames() {
const testFileFrames = `${RELATIVE_PATH}frames.html`;
const tabUrl = `${fixPort('http://a.com:PORT/')}${testFileFrames}`;
// A sorted list of the expected scripts results. The script returns
// window.location.href.
const expectedResults = [
tabUrl,
`${fixPort('http://a.com:PORT/')}${RELATIVE_PATH}empty.html`,
`${fixPort('http://b.com:PORT/')}${RELATIVE_PATH}empty.html`,
].sort();
function executeScriptCallback(results) {
chrome.test.assertEq(expectedResults, results.sort());
chrome.test.succeed();
}
function updatedListener(tabId, changeInfo, tab) {
if (tab.status === 'complete') {
chrome.tabs.onUpdated.removeListener(updatedListener);
chrome.tabs.executeScript(
tab.id, {file: 'script.js', allFrames: true},
executeScriptCallback);
}
}
chrome.tabs.onUpdated.addListener(updatedListener);
chrome.tabs.create({url: tabUrl});
},
]);