blob: 0ab404b2530fcf23f576518899c96be61d4decaf [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview using private properties isn't a Closure violation in tests.
* @suppress {accessControls}
*/
ApplicationTestRunner.dumpIndexedDBTree = function() {
TestRunner.addResult('Dumping IndexedDB tree:');
const indexedDBTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement;
if (!indexedDBTreeElement.childCount()) {
TestRunner.addResult(' (empty)');
return;
}
for (let i = 0; i < indexedDBTreeElement.childCount(); ++i) {
const databaseTreeElement = indexedDBTreeElement.childAt(i);
TestRunner.addResult(' database: ' + databaseTreeElement.title);
if (!databaseTreeElement.childCount()) {
TestRunner.addResult(' (no object stores)');
continue;
}
for (let j = 0; j < databaseTreeElement.childCount(); ++j) {
const objectStoreTreeElement = databaseTreeElement.childAt(j);
TestRunner.addResult(' Object store: ' + objectStoreTreeElement.title);
if (!objectStoreTreeElement.childCount()) {
TestRunner.addResult(' (no indexes)');
continue;
}
for (let k = 0; k < objectStoreTreeElement.childCount(); ++k) {
const indexTreeElement = objectStoreTreeElement.childAt(k);
TestRunner.addResult(' Index: ' + indexTreeElement.title);
}
}
}
};
ApplicationTestRunner.dumpObjectStores = function() {
TestRunner.addResult('Dumping ObjectStore data:');
const idbDatabaseTreeElement = UI.panels.resources._sidebar.indexedDBListTreeElement._idbDatabaseTreeElements[0];
for (let i = 0; i < idbDatabaseTreeElement.childCount(); ++i) {
const objectStoreTreeElement = idbDatabaseTreeElement.childAt(i);
objectStoreTreeElement.onselect(false);
TestRunner.addResult(' Object store: ' + objectStoreTreeElement.title);
const entries = objectStoreTreeElement._view._entries;
TestRunner.addResult(' Number of entries: ' + entries.length);
for (let j = 0; j < entries.length; ++j)
TestRunner.addResult(' Key = ' + entries[j].key._value + ', value = ' + entries[j].value);
for (let k = 0; k < objectStoreTreeElement.childCount(); ++k) {
const indexTreeElement = objectStoreTreeElement.childAt(k);
TestRunner.addResult(' Index: ' + indexTreeElement.title);
indexTreeElement.onselect(false);
const entries = indexTreeElement._view._entries;
TestRunner.addResult(' Number of entries: ' + entries.length);
for (let j = 0; j < entries.length; ++j)
TestRunner.addResult(' Key = ' + entries[j].primaryKey._value + ', value = ' + entries[j].value);
}
}
};
let lastCallbackId = 0;
const callbacks = {};
const callbackIdPrefix = 'InspectorTest.IndexedDB_callback';
ApplicationTestRunner.evaluateWithCallback = function(frameId, methodName, parameters, callback) {
ApplicationTestRunner._installIndexedDBSniffer();
const callbackId = ++lastCallbackId;
callbacks[callbackId] = callback;
let parametersString = 'dispatchCallback.bind(this, "' + callbackIdPrefix + callbackId + '")';
for (let i = 0; i < parameters.length; ++i)
parametersString += ', ' + JSON.stringify(parameters[i]);
const requestString = methodName + '(' + parametersString + ')';
TestRunner.evaluateInPageAnonymously(requestString);
};
ApplicationTestRunner._installIndexedDBSniffer = function() {
ConsoleTestRunner.addConsoleSniffer(consoleMessageOverride, false);
function consoleMessageOverride(msg) {
const text = msg.messageText;
if (!text.startsWith(callbackIdPrefix)) {
ConsoleTestRunner.addConsoleSniffer(consoleMessageOverride, false);
return;
}
const callbackId = text.substring(callbackIdPrefix.length);
callbacks[callbackId].call();
delete callbacks[callbackId];
}
};
ApplicationTestRunner.createDatabase = function(frameId, databaseName, callback) {
ApplicationTestRunner.evaluateWithCallback(frameId, 'createDatabase', [databaseName], callback);
};
ApplicationTestRunner.deleteDatabase = function(frameId, databaseName, callback) {
ApplicationTestRunner.evaluateWithCallback(frameId, 'deleteDatabase', [databaseName], callback);
};
ApplicationTestRunner.createObjectStore = function(
frameId, databaseName, objectStoreName, keyPath, autoIncrement, callback) {
ApplicationTestRunner.evaluateWithCallback(
frameId, 'createObjectStore', [databaseName, objectStoreName, keyPath, autoIncrement], callback);
};
ApplicationTestRunner.deleteObjectStore = function(frameId, databaseName, objectStoreName, callback) {
ApplicationTestRunner.evaluateWithCallback(frameId, 'deleteObjectStore', [databaseName, objectStoreName], callback);
};
ApplicationTestRunner.createObjectStoreIndex = function(
frameId, databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry, callback) {
ApplicationTestRunner.evaluateWithCallback(
frameId, 'createObjectStoreIndex',
[databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry], callback);
};
ApplicationTestRunner.deleteObjectStoreIndex = function(
frameId, databaseName, objectStoreName, objectStoreIndexName, callback) {
ApplicationTestRunner.evaluateWithCallback(
frameId, 'deleteObjectStoreIndex', [databaseName, objectStoreName, objectStoreIndexName], callback);
};
ApplicationTestRunner.addIDBValue = function(frameId, databaseName, objectStoreName, value, key, callback) {
ApplicationTestRunner.evaluateWithCallback(
frameId, 'addIDBValue', [databaseName, objectStoreName, value, key], callback);
};
ApplicationTestRunner.createIndexedDBModel = function() {
const indexedDBModel = new Resources.IndexedDBModel(SDK.targetManager.mainTarget(), TestRunner.securityOriginManager);
indexedDBModel.enable();
return indexedDBModel;
};
ApplicationTestRunner.createDatabaseAsync = function(databaseName) {
return TestRunner.evaluateInPageAsync('createDatabaseAsync(\'' + databaseName + '\')');
};
ApplicationTestRunner.deleteDatabaseAsync = function(databaseName) {
return TestRunner.evaluateInPageAsync('deleteDatabaseAsync(\'' + databaseName + '\')');
};
ApplicationTestRunner.createObjectStoreAsync = function(databaseName, objectStoreName, indexName) {
return TestRunner.evaluateInPageAsync(
'createObjectStoreAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
};
ApplicationTestRunner.deleteObjectStoreAsync = function(databaseName, objectStoreName) {
return TestRunner.evaluateInPageAsync(
'deleteObjectStoreAsync(\'' + databaseName + '\', \'' + objectStoreName + '\')');
};
ApplicationTestRunner.createObjectStoreIndexAsync = function(databaseName, objectStoreName, indexName) {
return TestRunner.evaluateInPageAsync(
'createObjectStoreIndexAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
};
ApplicationTestRunner.deleteObjectStoreIndexAsync = function(databaseName, objectStoreName, indexName) {
return TestRunner.evaluateInPageAsync(
'deleteObjectStoreIndexAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + indexName + '\')');
};
ApplicationTestRunner.addIDBValueAsync = function(databaseName, objectStoreName, key, value) {
return TestRunner.evaluateInPageAsync(
'addIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\', \'' + value + '\')');
};
ApplicationTestRunner.deleteIDBValueAsync = function(databaseName, objectStoreName, key) {
return TestRunner.evaluateInPageAsync(
'deleteIDBValueAsync(\'' + databaseName + '\', \'' + objectStoreName + '\', \'' + key + '\')');
};
const __indexedDBHelpers = `
function dispatchCallback(callbackId) {
console.log(callbackId);
}
function onIndexedDBError(e) {
console.error('IndexedDB error: ' + e);
}
function onIndexedDBBlocked(e) {
console.error('IndexedDB blocked: ' + e);
}
function doWithDatabase(databaseName, callback) {
function innerCallback() {
let db = request.result;
callback(db);
}
let request = indexedDB.open(databaseName);
request.onblocked = onIndexedDBBlocked;
request.onerror = onIndexedDBError;
request.onsuccess = innerCallback;
}
function doWithVersionTransaction(databaseName, callback, commitCallback) {
doWithDatabase(databaseName, step2);
function step2(db) {
let version = db.version;
db.close();
request = indexedDB.open(databaseName, version + 1);
request.onerror = onIndexedDBError;
request.onupgradeneeded = onUpgradeNeeded;
request.onsuccess = onOpened;
function onUpgradeNeeded(e) {
let db = e.target.result;
let trans = e.target.transaction;
callback(db, trans);
}
function onOpened(e) {
let db = e.target.result;
db.close();
commitCallback();
}
}
}
function doWithReadWriteTransaction(databaseName, objectStoreName, callback, commitCallback) {
doWithDatabase(databaseName, step2);
function step2(db) {
let transaction = db.transaction([objectStoreName], 'readwrite');
let objectStore = transaction.objectStore(objectStoreName);
callback(objectStore, innerCommitCallback);
function innerCommitCallback() {
db.close();
commitCallback();
}
}
}
function createDatabase(callback, databaseName) {
let request = indexedDB.open(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = closeDatabase;
function closeDatabase() {
request.result.close();
callback();
}
}
function deleteDatabase(callback, databaseName) {
let request = indexedDB.deleteDatabase(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = callback;
}
function createObjectStore(callback, databaseName, objectStoreName, keyPath, autoIncrement) {
doWithVersionTransaction(databaseName, withTransactionCallback, callback);
function withTransactionCallback(db, transaction) {
let store = db.createObjectStore(objectStoreName, {
keyPath: keyPath,
autoIncrement: autoIncrement
});
}
}
function deleteObjectStore(callback, databaseName, objectStoreName) {
doWithVersionTransaction(databaseName, withTransactionCallback, callback);
function withTransactionCallback(db, transaction) {
let store = db.deleteObjectStore(objectStoreName);
}
}
function createObjectStoreIndex(callback, databaseName, objectStoreName, objectStoreIndexName, keyPath, unique, multiEntry) {
doWithVersionTransaction(databaseName, withTransactionCallback, callback);
function withTransactionCallback(db, transaction) {
let objectStore = transaction.objectStore(objectStoreName);
objectStore.createIndex(objectStoreIndexName, keyPath, {
unique: unique,
multiEntry: multiEntry
});
}
}
function deleteObjectStoreIndex(callback, databaseName, objectStoreName, objectStoreIndexName) {
doWithVersionTransaction(databaseName, withTransactionCallback, callback);
function withTransactionCallback(db, transaction) {
let objectStore = transaction.objectStore(objectStoreName);
objectStore.deleteIndex(objectStoreIndexName);
}
}
function addIDBValue(callback, databaseName, objectStoreName, value, key) {
doWithReadWriteTransaction(databaseName, objectStoreName, withTransactionCallback, callback);
function withTransactionCallback(objectStore, commitCallback) {
let request;
if (key)
request = objectStore.add(value, key);
else
request = objectStore.add(value);
request.onerror = onIndexedDBError;
request.onsuccess = commitCallback;
}
}
function createDatabaseAsync(databaseName) {
return new Promise((resolve) => {
createDatabase(resolve, databaseName);
});
}
function upgradeRequestAsync(databaseName, onUpgradeNeeded, callback) {
let request = indexedDB.open(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = function(event) {
let db = request.result;
let version = db.version;
db.close();
let upgradeRequest = indexedDB.open(databaseName, version + 1);
upgradeRequest.onerror = onIndexedDBError;
upgradeRequest.onupgradeneeded = function(e) {
onUpgradeNeeded(e.target.result, e.target.transaction, callback);
}
upgradeRequest.onsuccess = function(e) {
let upgradeDb = e.target.result;
upgradeDb.close();
callback();
}
}
}
function deleteDatabaseAsync(databaseName) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let request = indexedDB.deleteDatabase(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = callback;
return promise;
}
function createObjectStoreAsync(databaseName, objectStoreName, indexName) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
let store = upgradeDb.createObjectStore(objectStoreName, { keyPath: "test", autoIncrement: false });
store.createIndex(indexName, "test", { unique: false, multiEntry: false });
callback();
}
upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
return promise;
}
function deleteObjectStoreAsync(databaseName, objectStoreName) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
upgradeDb.deleteObjectStore(objectStoreName);
callback();
}
upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
return promise;
}
function createObjectStoreIndexAsync(databaseName, objectStoreName, indexName) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
let store = transaction.objectStore(objectStoreName);
store.createIndex(indexName, "test", { unique: false, multiEntry: false });
callback();
}
upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
return promise;
}
function deleteObjectStoreIndexAsync(databaseName, objectStoreName, indexName) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let onUpgradeNeeded = function(upgradeDb, transaction, callback) {
let store = transaction.objectStore(objectStoreName);
store.deleteIndex(indexName);
callback();
}
upgradeRequestAsync(databaseName, onUpgradeNeeded, callback)
return promise;
}
function addIDBValueAsync(databaseName, objectStoreName, key, value) {
let callback;
let promise = new Promise(fulfill => callback = fulfill);
let request = indexedDB.open(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = function(event) {
let db = request.result;
let transaction = db.transaction(objectStoreName, 'readwrite');
let store = transaction.objectStore(objectStoreName);
store.put({
test: key,
testValue: value
});
transaction.onerror = onIndexedDBError;
transaction.oncomplete = function() {
db.close();
callback();
};
};
return promise;
}
function deleteIDBValueAsync(databaseName, objectStoreName, key) {
let callback;
let promise = new Promise((fulfill) => callback = fulfill);
let request = indexedDB.open(databaseName);
request.onerror = onIndexedDBError;
request.onsuccess = function(event) {
let db = request.result;
let transaction = db.transaction(objectStoreName, "readwrite");
let store = transaction.objectStore(objectStoreName);
store.delete(key);
transaction.onerror = onIndexedDBError;
transaction.oncomplete = function() {
db.close();
callback();
};
}
return promise;
}
`;
ApplicationTestRunner.setupIndexedDBHelpers = function() {
return TestRunner.evaluateInPagePromise(__indexedDBHelpers);
};
TestRunner.deprecatedInitAsync(__indexedDBHelpers);