gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 01/02: idb: more tests and fixes


From: gnunet
Subject: [taler-wallet-core] 01/02: idb: more tests and fixes
Date: Tue, 23 Feb 2021 19:28:54 +0100

This is an automated email from the git hooks/post-receive script.

dold pushed a commit to branch master
in repository wallet-core.

commit 648b0be7dd0e65f9001c1f869e710337ecd7c4e2
Author: Florian Dold <florian@dold.me>
AuthorDate: Tue Feb 23 19:28:37 2021 +0100

    idb: more tests and fixes
---
 packages/idb-bridge/src/bridge-idb.ts              |  80 +++-
 packages/idb-bridge/src/idb-wpt-ported/README      | 266 +++++++++++-
 .../abort-in-initial-upgradeneeded.test.ts         |   4 +-
 .../src/idb-wpt-ported/cursor-overloads.test.ts    |   2 +-
 .../idb-wpt-ported/idbcursor-advance-index.test.ts |   6 +-
 .../idbcursor-continue-index.test.ts               |  14 +-
 .../idbcursor-continue-objectstore.test.ts         | 240 +++++++++++
 .../idbcursor-delete-exception-order.test.ts       |  85 ++++
 .../idb-wpt-ported/idbcursor-delete-index.test.ts  | 204 ++++++++++
 .../idbcursor-delete-objectstore.test.ts           | 194 +++++++++
 .../src/idb-wpt-ported/idbcursor-reused.test.ts    |   2 +-
 .../idb-wpt-ported/idbcursor-update-index.test.ts  | 388 ++++++++++++++++++
 .../src/idb-wpt-ported/idbfactory-open.test.ts     |  10 +-
 .../src/idb-wpt-ported/idbindex-get.test.ts        |   6 +-
 .../src/idb-wpt-ported/idbindex-openCursor.test.ts |  80 ++++
 .../src/idb-wpt-ported/idbobjectstore-add.test.ts  |  16 +-
 .../src/idb-wpt-ported/idbobjectstore-get.test.ts  | 159 ++++++++
 .../src/idb-wpt-ported/idbobjectstore-put.test.ts  | 449 +++++++++++++++++++++
 .../idbtransaction-oncomplete.test.ts              |   2 +-
 .../idb-bridge/src/idb-wpt-ported/keypath.test.ts  |   4 +-
 .../request-bubble-and-capture.test.ts             |   2 +-
 .../transaction-requestqueue.test.ts               |   2 +-
 .../idb-bridge/src/idb-wpt-ported/wptsupport.ts    |  33 +-
 23 files changed, 2192 insertions(+), 56 deletions(-)

diff --git a/packages/idb-bridge/src/bridge-idb.ts 
b/packages/idb-bridge/src/bridge-idb.ts
index 836f2efa..744ad1ae 100644
--- a/packages/idb-bridge/src/bridge-idb.ts
+++ b/packages/idb-bridge/src/bridge-idb.ts
@@ -635,7 +635,9 @@ export class BridgeIDBDatabase extends FakeEventTarget 
implements IDBDatabase {
 
     this._schema = this._backend.getCurrentTransactionSchema(backendTx);
 
-    return transaction.objectStore(name);
+    const newObjectStore = transaction.objectStore(name);
+    newObjectStore._justCreated = true;
+    return newObjectStore;
   }
 
   public deleteObjectStore(name: string): void {
@@ -965,7 +967,6 @@ export class BridgeIDBFactory {
           });
           event2.eventPath = [];
           request.dispatchEvent(event2);
-
         } else {
           if (BridgeIDBFactory.enableTracing) {
             console.log("dispatching 'success' event for opening db");
@@ -1046,6 +1047,11 @@ export class BridgeIDBIndex implements IDBIndex {
 
   public _deleted: boolean = false;
 
+  /**
+   * Was this index newly created in the current transaction?
+   */
+  _justCreated: boolean = false;
+
   constructor(objectStore: BridgeIDBObjectStore, name: string) {
     this._name = name;
     this._objectStore = objectStore;
@@ -1078,8 +1084,16 @@ export class BridgeIDBIndex implements IDBIndex {
 
     this._backend.renameIndex(btx, this._objectStore.name, oldName, newName);
 
+    this._objectStore._transaction._db._schema = 
this._backend.getCurrentTransactionSchema(
+      btx,
+    );
+
+    this._objectStore._indexesCache.delete(oldName);
+    this._objectStore._indexesCache.set(newName, this);
+    this._name = newName;
+
     if (this._objectStore._indexNames.indexOf(name) >= 0) {
-      throw new ConstraintError();
+      throw new Error("internal invariant violated");
     }
   }
 
@@ -1089,6 +1103,14 @@ export class BridgeIDBIndex implements IDBIndex {
     range?: BridgeIDBKeyRange | IDBValidKey | null | undefined,
     direction: IDBCursorDirection = "next",
   ) {
+    if (this._deleted) {
+      throw new InvalidStateError(
+        "tried to call 'openCursor' on a deleted index",
+      );
+    }
+
+    console.log("opening cursor on", this);
+
     this._confirmActiveTransaction();
 
     if (range === null) {
@@ -1418,6 +1440,8 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
    */
   _debugName: string | undefined = undefined;
 
+  _justCreated: boolean = false;
+
   get transaction(): IDBTransaction {
     return this._transaction;
   }
@@ -1642,8 +1666,8 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
       try {
         keyRange = BridgeIDBKeyRange.only(valueToKey(key));
       } catch (e) {
-        throw Error(
-          `invalid key (type ${typeof key}) for object store ${this._name}`,
+        throw new DataError(
+          `invalid key (type ${typeof key}) for object store '${this._name}'`,
         );
       }
     }
@@ -1677,6 +1701,9 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
       if (!values) {
         throw Error("invariant violated");
       }
+      if (values.length !== 1) {
+        throw Error("invariant violated");
+      }
       return structuredRevive(values[0]);
     };
 
@@ -1790,7 +1817,6 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     });
   }
 
-  // tslint:disable-next-line max-line-length
   // 
http://www.w3.org/TR/2015/REC-IndexedDB-20150108/#widl-IDBObjectStore-createIndex-IDBIndex-DOMString-name-DOMString-sequence-DOMString--keyPath-IDBIndexParameters-optionalParameters
   public createIndex(
     indexName: string,
@@ -1839,7 +1865,9 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
       unique,
     );
 
-    return new BridgeIDBIndex(this, indexName);
+    const idx = this.index(indexName);
+    idx._justCreated = true;
+    return idx;
   }
 
   // https://w3c.github.io/IndexedDB/#dom-idbobjectstore-index
@@ -1856,8 +1884,10 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     if (index !== undefined) {
       return index;
     }
-
-    return new BridgeIDBIndex(this, name);
+    const newIndex = new BridgeIDBIndex(this, name);
+    this._indexesCache.set(name, newIndex);
+    this._transaction._usedIndexes.push(newIndex);
+    return newIndex;
   }
 
   public deleteIndex(indexName: string) {
@@ -1878,6 +1908,7 @@ export class BridgeIDBObjectStore implements 
IDBObjectStore {
     const index = this._indexesCache.get(indexName);
     if (index !== undefined) {
       index._deleted = true;
+      this._indexesCache.delete(indexName);
     }
 
     this._backend.deleteIndex(btx, this._name, indexName);
@@ -2053,6 +2084,16 @@ export class BridgeIDBTransaction
   _aborted: boolean = false;
   _objectStoresCache: Map<string, BridgeIDBObjectStore> = new Map();
 
+  /**
+   * Object stores used during the transaction.
+   */
+  _usedObjectStores: BridgeIDBObjectStore[] = [];
+
+  /**
+   * Object stores used during the transaction.
+   */
+  _usedIndexes: BridgeIDBIndex[] = [];
+
   /**
    * Name that can be set to identify the transaction in logs.
    */
@@ -2181,11 +2222,31 @@ export class BridgeIDBTransaction
       }
     }
 
+    // "Any object stores and indexes which were created during the
+    // transaction are now considered deleted for the purposes of other
+    // algorithms."
+    if (this._db._upgradeTransaction) {
+      for (const os of this._usedObjectStores) {
+        if (os._justCreated) {
+          os._deleted = true
+        }
+      }
+      for (const ind of this._usedIndexes) {
+        if (ind._justCreated) {
+          ind._deleted = true
+        }
+      }
+    }
+
     // ("abort a transaction", step 5.1)
     if (this._openRequest) {
       this._db._upgradeTransaction = null;
     }
 
+    // All steps before happend synchronously.  Now
+    // we asynchronously roll back the backend transaction,
+    // if necessary/possible.
+
     const maybeBtx = this._backendTransaction;
     if (maybeBtx) {
       this._db._schema = this._backend.getInitialTransactionSchema(maybeBtx);
@@ -2242,6 +2303,7 @@ export class BridgeIDBTransaction
 
     const newObjectStore = new BridgeIDBObjectStore(this, name);
     this._objectStoresCache.set(name, newObjectStore);
+    this._usedObjectStores.push(newObjectStore);
     return newObjectStore;
   }
 
diff --git a/packages/idb-bridge/src/idb-wpt-ported/README 
b/packages/idb-bridge/src/idb-wpt-ported/README
index 801450bb..1947074d 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/README
+++ b/packages/idb-bridge/src/idb-wpt-ported/README
@@ -7,4 +7,268 @@ The following tests are intentionally not included:
 * file_support.sub.html (assumes we have a DOM)
 * fire-error-event-exception.html (ava can't test unhandled rejections)
 * fire-success-event-exception.html (ava can't test unhandled rejections)
-* fire-upgradeneeded-event-exception.html (ava can't test unhandled rejections)
\ No newline at end of file
+* fire-upgradeneeded-event-exception.html (ava can't test unhandled rejections)
+
+Test todo:
+
+bigint_value.htm
+bindings-inject-keys-bypass-setters.html
+bindings-inject-values-bypass-chain.html
+bindings-inject-values-bypass-setters.html
+blob-contenttype.any.js
+blob-delete-objectstore-db.any.js
+blob-valid-after-deletion.any.js
+blob-valid-before-commit.any.js
+clone-before-keypath-eval.html
+delete-request-queue.html
+get-databases.any.js
+globalscope-indexedDB-SameObject.html
+historical.html
+idb_binary_key_conversion.htm
+idb-binary-key-detached.htm
+idb-binary-key-roundtrip.htm
+idbcursor-advance-continue-async.htm
+idbcursor-advance-exception-order.html
+idbcursor_advance_index.htm
+idbcursor-advance-invalid.htm
+idbcursor_advance_objectstore2.htm
+idbcursor_advance_objectstore3.htm
+idbcursor_advance_objectstore4.htm
+idbcursor_advance_objectstore5.htm
+idbcursor_advance_objectstore.htm
+idbcursor_continue_delete_objectstore.htm
+idbcursor-continue-exception-order.htm
+idbcursor_continue_invalid.htm
+idbcursor-continuePrimaryKey-exception-order.htm
+idbcursor-continuePrimaryKey-exceptions.htm
+idbcursor-continuePrimaryKey.htm
+idbcursor-direction.htm
+idbcursor-direction-index.htm
+idbcursor-direction-index-keyrange.htm
+idbcursor-direction-objectstore.htm
+idbcursor-direction-objectstore-keyrange.htm
+idbcursor_iterating.htm
+idbcursor_iterating_index2.htm
+idbcursor_iterating_index.htm
+idbcursor_iterating_objectstore2.htm
+idbcursor_iterating_objectstore.htm
+idbcursor-iterating-update.htm
+idbcursor-key.htm
+idbcursor-primarykey.htm
+idbcursor-request.any.js
+idbcursor-request-source.html
+idbcursor-reused.htm
+idbcursor-source.htm
+idbcursor-update-exception-order.htm
+idbcursor_update_objectstore2.htm
+idbcursor_update_objectstore3.htm
+idbcursor_update_objectstore4.htm
+idbcursor_update_objectstore5.htm
+idbcursor_update_objectstore6.htm
+idbcursor_update_objectstore7.htm
+idbcursor_update_objectstore8.htm
+idbcursor_update_objectstore9.htm
+idbcursor_update_objectstore.htm
+idbdatabase_close2.htm
+idbdatabase_close.htm
+idbdatabase_createObjectStore10-1000ends.htm
+idbdatabase_createObjectStore10-emptyname.htm
+idbdatabase_createObjectStore11.htm
+idbdatabase_createObjectStore2.htm
+idbdatabase_createObjectStore3.htm
+idbdatabase_createObjectStore4.htm
+idbdatabase_createObjectStore5.htm
+idbdatabase_createObjectStore6.htm
+idbdatabase_createObjectStore7.htm
+idbdatabase_createObjectStore8-parameters.htm
+idbdatabase_createObjectStore9-invalidparameters.htm
+idbdatabase_createObjectStore-createIndex-emptyname.htm
+idbdatabase-createObjectStore-exception-order.htm
+idbdatabase_createObjectStore.htm
+idbdatabase_deleteObjectStore2.htm
+idbdatabase_deleteObjectStore3.htm
+idbdatabase_deleteObjectStore4-not_reused.htm
+idbdatabase-deleteObjectStore-exception-order.htm
+idbdatabase_deleteObjectStore.htm
+idbdatabase_transaction2.htm
+idbdatabase_transaction3.htm
+idbdatabase_transaction4.htm
+idbdatabase_transaction5.htm
+idbdatabase-transaction-exception-order.html
+idbdatabase_transaction.htm
+idb-explicit-commit.any.js
+idb-explicit-commit-throw.any.js
+idbfactory-databases-opaque-origin.html
+idbfactory_deleteDatabase2.htm
+idbfactory_deleteDatabase3.htm
+idbfactory_deleteDatabase4.htm
+idbfactory_deleteDatabase.htm
+idbfactory-deleteDatabase-opaque-origin.html
+idbfactory-deleteDatabase-request-success.html
+idbfactory-open-error-properties.html
+idbfactory-open-opaque-origin.html
+idbfactory-open-request-error.html
+idbfactory-open-request-success.html
+idbfactory-origin-isolation.html
+idbindex_count2.htm
+idbindex_count3.htm
+idbindex_count4.htm
+idbindex_count.htm
+idbindex-getAll-enforcerange.html
+idbindex_getAll.html
+idbindex-getAllKeys-enforcerange.html
+idbindex_getAllKeys.html
+idbindex_get.htm
+idbindex_getKey2.htm
+idbindex_getKey3.htm
+idbindex_getKey4.htm
+idbindex_getKey5.htm
+idbindex_getKey6.htm
+idbindex_getKey7.htm
+idbindex_getKey8.htm
+idbindex_getKey.htm
+idbindex_indexNames.htm
+idbindex_keyPath.any.js
+idbindex-multientry-arraykeypath.htm
+idbindex-multientry-big.htm
+idbindex-multientry.htm
+idbindex-objectStore-SameObject.html
+idbindex_openKeyCursor2.htm
+idbindex_openKeyCursor3.htm
+idbindex_openKeyCursor4.htm
+idbindex_openKeyCursor.htm
+idbindex-query-exception-order.html
+idbindex-rename-abort.html
+idbindex-rename-errors.html
+idbindex-rename.html
+idbindex-request-source.html
+idbindex_reverse_cursor.any.js
+idbindex_tombstones.any.js
+idbkeyrange.htm
+idbkeyrange-includes.htm
+idbkeyrange_incorrect.htm
+idbobjectstore_clear2.htm
+idbobjectstore_clear3.htm
+idbobjectstore_clear4.htm
+idbobjectstore-clear-exception-order.html
+idbobjectstore_clear.htm
+idbobjectstore_count2.htm
+idbobjectstore_count3.htm
+idbobjectstore_count4.htm
+idbobjectstore_count.htm
+idbobjectstore_createIndex10.htm
+idbobjectstore_createIndex11.htm
+idbobjectstore_createIndex12.htm
+idbobjectstore_createIndex13.htm
+idbobjectstore_createIndex14-exception_order.htm
+idbobjectstore_createIndex15-autoincrement.htm
+idbobjectstore_createIndex2.htm
+idbobjectstore_createIndex3-usable-right-away.htm
+idbobjectstore_createIndex4-deleteIndex-event_order.htm
+idbobjectstore_createIndex5-emptykeypath.htm
+idbobjectstore_createIndex6-event_order.htm
+idbobjectstore_createIndex7-event_order.htm
+idbobjectstore_createIndex8-valid_keys.htm
+idbobjectstore_createIndex9-emptyname.htm
+idbobjectstore_createIndex.htm
+idbobjectstore_delete2.htm
+idbobjectstore_delete3.htm
+idbobjectstore_delete4.htm
+idbobjectstore_delete5.htm
+idbobjectstore_delete6.htm
+idbobjectstore_delete7.htm
+idbobjectstore_deleted.htm
+idbobjectstore-delete-exception-order.html
+idbobjectstore_delete.htm
+idbobjectstore-deleteIndex-exception-order.html
+idbobjectstore_deleteIndex.htm
+idbobjectstore-getAll-enforcerange.html
+idbobjectstore_getAll.html
+idbobjectstore-getAllKeys-enforcerange.html
+idbobjectstore_getAllKeys.html
+idbobjectstore_getKey.html
+idbobjectstore-index-finished.html
+idbobjectstore_index.htm
+idbobjectstore_keyPath.any.js
+idbobjectstore_openCursor.htm
+idbobjectstore_openCursor_invalid.htm
+idbobjectstore_openKeyCursor.htm
+idbobjectstore_putall.tentative.any.js
+idbobjectstore-query-exception-order.html
+idbobjectstore-rename-abort.html
+idbobjectstore-rename-errors.html
+idbobjectstore-request-source.html
+idbobjectstore-transaction-SameObject.html
+idbrequest_error.html
+idbrequest-onupgradeneeded.htm
+idbrequest_result.html
+idbtransaction_abort.htm
+idbtransaction-db-SameObject.html
+idbtransaction.htm
+idbtransaction-objectStore-exception-order.html
+idbtransaction-objectStore-finished.html
+idbtransaction_objectStoreNames.html
+idbversionchangeevent.htm
+idb_webworkers.htm
+idbworker.js
+idlharness.any.js
+index_sort_order.htm
+interleaved-cursors-common.js
+interleaved-cursors-large.html
+interleaved-cursors-small.html
+key-conversion-exceptions.htm
+keygenerator-constrainterror.htm
+keygenerator-explicit.html
+keygenerator.htm
+keygenerator-inject.html
+keygenerator-overflow.htm
+key-generators
+key_invalid.htm
+keyorder.htm
+keypath-exceptions.htm
+keypath_invalid.htm
+keypath_maxsize.htm
+keypath-special-identifiers.htm
+key_valid.html
+large-requests-abort.html
+list_ordering.htm
+META.yml
+name-scopes.html
+nested-cloning-common.js
+nested-cloning-large.html
+nested-cloning-large-multiple.html
+nested-cloning-small.html
+objectstore_keyorder.htm
+open-request-queue.html
+parallel-cursors-upgrade.html
+request-abort-ordering.html
+request-event-ordering.html
+resources
+string-list-ordering.htm
+structured-clone.any.js
+structured-clone-transaction-state.any.js
+transaction-abort-generator-revert.html
+transaction-abort-index-metadata-revert.html
+transaction-abort-multiple-metadata-revert.html
+transaction-abort-object-store-metadata-revert.html
+transaction-abort-request-error.html
+transaction_bubble-and-capture.htm
+transaction-create_in_versionchange.htm
+transaction-deactivation-timing.html
+transaction-lifetime-blocked.htm
+transaction-lifetime-empty.html
+transaction-lifetime.htm
+transaction-relaxed-durability.tentative.any.js
+transaction-scheduling-across-connections.any.js
+transaction-scheduling-across-databases.any.js
+transaction-scheduling-mixed-scopes.any.js
+transaction-scheduling-ordering.any.js
+transaction-scheduling-ro-waits-for-rw.any.js
+transaction-scheduling-rw-scopes.any.js
+transaction-scheduling-within-database.any.js
+upgrade-transaction-deactivation-timing.html
+upgrade-transaction-lifecycle-backend-aborted.html
+upgrade-transaction-lifecycle-committed.html
+upgrade-transaction-lifecycle-user-aborted.html
+value_recursive.htm
+writer-starvation.htm
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/abort-in-initial-upgradeneeded.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/abort-in-initial-upgradeneeded.test.ts
index 70f2f2b8..3b65a903 100644
--- 
a/packages/idb-bridge/src/idb-wpt-ported/abort-in-initial-upgradeneeded.test.ts
+++ 
b/packages/idb-bridge/src/idb-wpt-ported/abort-in-initial-upgradeneeded.test.ts
@@ -6,7 +6,7 @@ test("WPT test abort-in-initial-upgradeneeded.htm", async (t) 
=> {
     var db: any;
     var open_rq = createdb(t, undefined, 2);
 
-    open_rq.onupgradeneeded = function (e) {
+    open_rq.onupgradeneeded = function (e: any) {
       const tgt = e.target as any;
       db = tgt.result;
       t.deepEqual(db.version, 2);
@@ -20,7 +20,7 @@ test("WPT test abort-in-initial-upgradeneeded.htm", async (t) 
=> {
       transaction.abort();
     };
 
-    open_rq.onerror = function (e) {
+    open_rq.onerror = function (e: any) {
       const tgt = e.target as any;
       t.deepEqual(open_rq, e.target);
       t.deepEqual(tgt.result, undefined);
diff --git a/packages/idb-bridge/src/idb-wpt-ported/cursor-overloads.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/cursor-overloads.test.ts
index 7da0ea8f..0f0713d1 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/cursor-overloads.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/cursor-overloads.test.ts
@@ -12,7 +12,7 @@ test.cb("WPT test cursor-overloads.htm", (t) => {
   var db: any, store: any, index: any;
 
   var request = createdb(t);
-  request.onupgradeneeded = function (e) {
+  request.onupgradeneeded = function (e: any) {
     db = request.result;
     store = db.createObjectStore("store");
     index = store.createIndex("index", "value");
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts
index 2d449a9a..fac04799 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-advance-index.test.ts
@@ -26,7 +26,7 @@ test("WPT test idbcursor_advance_index.htm", async (t) => {
       }
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var cursor_rq = db
         .transaction("test")
         .objectStore("test")
@@ -79,7 +79,7 @@ test("WPT test idbcursor_advance_index2.htm", async (t) => {
       for (var i = 0; i < records.length; i++) objStore.add(records[i]);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var cursor_rq = db
         .transaction("test")
         .objectStore("test")
@@ -123,7 +123,7 @@ test("WPT test idbcursor_advance_index3.htm", async (t) => {
       for (var i = 0; i < records.length; i++) objStore.add(records[i]);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var cursor_rq = db
         .transaction("test")
         .objectStore("test")
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-index.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-index.test.ts
index 02f2e5c9..9b96a2e9 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-index.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-index.test.ts
@@ -22,7 +22,7 @@ test.cb("WPT test idbcursor_continue_index.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var cursor_rq = db
       .transaction("test")
       .objectStore("test")
@@ -65,7 +65,7 @@ test.cb("WPT idbcursor-continue-index2.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var cursor_rq = db
       .transaction("test")
       .objectStore("test")
@@ -108,7 +108,7 @@ test.cb("WPT idbcursor-continue-index3.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var count = 0;
     var cursor_rq = db
       .transaction("test")
@@ -159,7 +159,7 @@ test.cb("WPT idbcursor-continue-index4.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var count = 0,
       cursor_rq = db
         .transaction("test")
@@ -224,7 +224,7 @@ test.cb("WPT idbcursor-continue-index5.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var count = 0,
       cursor_rq = db
         .transaction("test")
@@ -281,7 +281,7 @@ test.cb("WPT idbcursor-continue-index6.htm", (t) => {
     for (var i = 0; i < records.length; i++) objStore.add(records[i]);
   };
 
-  open_rq.onsuccess = function (e) {
+  open_rq.onsuccess = function (e: any) {
     var count = 0,
       cursor_rq = db
         .transaction("test")
@@ -316,7 +316,7 @@ test.cb("WPT idbcursor-continue-index6.htm", (t) => {
 
 // IDBCursor.continue() - index - throw TransactionInactiveError
 test.cb("WPT idbcursor-continue-index7.htm", (t) => {
-  var db,
+  var db: any,
     records = [
       { pKey: "primaryKey_0", iKey: "indexKey_0" },
       { pKey: "primaryKey_1", iKey: "indexKey_1" },
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-objectstore.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-objectstore.test.ts
new file mode 100644
index 00000000..ecfac82f
--- /dev/null
+++ 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-continue-objectstore.test.ts
@@ -0,0 +1,240 @@
+import test from "ava";
+import { BridgeIDBCursor } from "..";
+import { BridgeIDBCursorWithValue } from "../bridge-idb";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBCursor.continue() - object store - iterate to the next record
+test.cb("WPT test idbcursor_continue_objectstore.htm", (t) => {
+  var db: any;
+  let count = 0;
+  const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", {
+      autoIncrement: true,
+      keyPath: "pKey",
+    });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var store = db.transaction("test").objectStore("test");
+
+    var cursor_rq = store.openCursor();
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      if (!cursor) {
+        t.deepEqual(count, records.length, "cursor run count");
+        t.end();
+      }
+
+      var record = cursor.value;
+      t.deepEqual(record.pKey, records[count].pKey, "primary key");
+
+      cursor.continue();
+      count++;
+    };
+  };
+});
+
+// IDBCursor.continue() - index - attempt to pass a
+// key parameter that is not a valid key
+test.cb("WPT test idbcursor_continue_objectstore2.htm", (t) => {
+  var db: any;
+  const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exists");
+      t.throws(
+        () => {
+          cursor.continue({ foo: "42" });
+        },
+        { name: "DataError" },
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.continue() - object store - attempt to iterate to the
+// previous record when the direction is set for the next record
+test.cb("WPT test idbcursor_continue_objectstore3.htm", (t) => {
+  var db: IDBDatabase;
+  const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("test")
+      .objectStore("test")
+      .openCursor(undefined, "next");
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+      t.throws(
+        () => {
+          cursor.continue(records[0].pKey);
+        },
+        {
+          name: "DataError",
+        },
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.continue() - object store - attempt to iterate to the next record 
when the direction is set for the previous record
+test.cb("WPT test idbcursor_continue_objectstore4.htm", (t) => {
+  var db: any;
+  const records = [
+    { pKey: "primaryKey_0" },
+    { pKey: "primaryKey_1" },
+    { pKey: "primaryKey_2" },
+  ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var count = 0,
+      cursor_rq = db
+        .transaction("test")
+        .objectStore("test")
+        .openCursor(null, "prev");
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor != null, "cursor exist");
+
+      switch (count) {
+        case 0:
+          t.deepEqual(cursor.value.pKey, records[2].pKey, "first cursor pkey");
+          cursor.continue(records[1].pKey);
+          break;
+
+        case 1:
+          t.deepEqual(cursor.value.pKey, records[1].pKey, "second cursor 
pkey");
+          t.throws(
+            () => {
+              cursor.continue(records[2].pKey);
+            },
+            {
+              name: "DataError",
+            },
+          );
+          t.end();
+          break;
+
+        default:
+          t.fail("Unexpected count value: " + count);
+      }
+
+      count++;
+    };
+  };
+});
+
+// IDBCursor.continue() - object store - throw TransactionInactiveError
+test.cb("WPT test idbcursor_continue_objectstore5.htm", (t) => {
+  var db: any;
+  const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exists");
+
+      e.target.transaction.abort();
+      t.throws(
+        () => {
+          cursor.continue();
+        },
+        {
+          name: "TransactionInactiveError",
+        },
+        "Calling continue() should throw an exception TransactionInactiveError 
when the transaction is not active.",
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.continue() - object store - throw InvalidStateError caused by 
object store been deleted
+test.cb("WPT test idbcursor_continue_objectstore6.htm", (t) => {
+  var db: any;
+  const records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+
+    var cursor_rq = objStore.openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exists");
+
+      db.deleteObjectStore("test");
+      t.throws(
+        () => {
+          cursor.continue();
+        },
+        {
+          name: "InvalidStateError",
+        },
+        "If the cursor's source or effective object store has been deleted, 
the implementation MUST throw a DOMException of type InvalidStateError",
+      );
+
+      t.end();
+    };
+  };
+});
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-exception-order.test.ts
 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-exception-order.test.ts
new file mode 100644
index 00000000..c80e276e
--- /dev/null
+++ 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-exception-order.test.ts
@@ -0,0 +1,85 @@
+import test from "ava";
+import { createdb, indexeddb_test } from "./wptsupport";
+
+test("WPT idbcursor-delete-exception-order.htm", async (t) => {
+  // 'IDBCursor.delete exception order: TransactionInactiveError vs. 
ReadOnlyError'
+  await indexeddb_test(
+    t,
+    (done, db) => {
+      const s = db.createObjectStore("s");
+      s.put("value", "key");
+    },
+    (done, db) => {
+      const s = db.transaction("s", "readonly").objectStore("s");
+      const r = s.openCursor();
+      r.onsuccess = () => {
+        r.onsuccess = null;
+        setTimeout(() => {
+          const cursor = r.result;
+          t.assert(!!cursor);
+          t.throws(
+            () => {},
+            { name: "TransactionInactiveError" },
+
+            '"Transaction inactive" check (TransactionInactivError) ' +
+              'should precede "read only" check (ReadOnlyError)',
+          );
+          done();
+        }, 0);
+      };
+    },
+  );
+
+  indexeddb_test(
+    t,
+    (done, db) => {
+      const s = db.createObjectStore("s");
+      s.put("value", "key");
+    },
+    (done, db) => {
+      const s = db.transaction("s", "readonly").objectStore("s");
+      const r = s.openCursor();
+      r.onsuccess = () => {
+        r.onsuccess = null;
+        const cursor = r.result!;
+        t.assert(cursor);
+        cursor.continue();
+        t.throws(
+          () => {
+            cursor.delete();
+          },
+          { name: "ReadOnlyError" },
+          '"Read only" check (ReadOnlyError) should precede ' +
+            '"got value flag" (InvalidStateError) check',
+        );
+
+        done();
+      };
+    },
+    "IDBCursor.delete exception order: ReadOnlyError vs. InvalidStateError #1",
+  );
+
+  indexeddb_test(
+    t,
+    (done, db) => {
+      const s = db.createObjectStore("s");
+      s.put("value", "key");
+    },
+    (done, db) => {
+      const s = db.transaction("s", "readonly").objectStore("s");
+      const r = s.openKeyCursor();
+      r.onsuccess = () => {
+        r.onsuccess = null;
+        const cursor = r.result;
+        t.throws(
+          () => {},
+          { name: "ReadOnlyError" },
+          '"Read only" check (ReadOnlyError) should precede ' +
+            '"key only flag" (InvalidStateError) check',
+        );
+        done();
+      };
+    },
+    "IDBCursor.delete exception order: ReadOnlyError vs. InvalidStateError #2",
+  );
+});
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-index.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-index.test.ts
new file mode 100644
index 00000000..0b28a4d4
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-index.test.ts
@@ -0,0 +1,204 @@
+import test from "ava";
+import { BridgeIDBCursor } from "..";
+import { IDBCursor } from "../idbtypes";
+import { createdb, indexeddb_test } from "./wptsupport";
+
+// IDBCursor.delete() - index - remove a record from the object store
+test.cb("WPT idbcursor-delete-index.htm", (t) => {
+  var db: any;
+  let count = 0,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = CursorDeleteRecord;
+
+  function CursorDeleteRecord(e: any) {
+    var txn = db.transaction("test", "readwrite"),
+      cursor_rq = txn.objectStore("test").index("index").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+      cursor.delete();
+    };
+
+    txn.oncomplete = VerifyRecordWasDeleted;
+  }
+
+  function VerifyRecordWasDeleted(e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      if (!cursor) {
+        t.deepEqual(count, 1, "count");
+        t.end();
+        return;
+      }
+
+      t.deepEqual(cursor.value.pKey, records[1].pKey);
+      t.deepEqual(cursor.value.iKey, records[1].iKey);
+      cursor.continue();
+      count++;
+    };
+  }
+});
+
+// IDBCursor.delete() - object store - attempt to remove a record in a 
read-only transaction
+test.cb("WPT idbcursor-delete-index2.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor != null, "cursor exist");
+      t.throws(
+        () => {
+          cursor.delete();
+        },
+        {
+          name: "ReadOnlyError",
+        },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - index - attempt to remove a record in an inactive 
transaction
+test.cb("WPT idbcursor-delete-index3.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    var index = objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+
+    var cursor_rq = index.openCursor();
+
+    let myCursor: IDBCursor | undefined;
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+      myCursor = cursor;
+    };
+
+    e.target.transaction.oncomplete = function (e: any) {
+      t.throws(
+        () => {
+          myCursor!.delete();
+        },
+        { name: "TransactionInactiveError" },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - index - throw InvalidStateError caused by object store 
been deleted
+test.cb("WPT idbcursor-delete-index4.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+    for (var i = 0; i < records.length; i++) {
+      objStore.add(records[i]);
+    }
+    var rq = objStore.index("index").openCursor();
+    rq.onsuccess = function (event: any) {
+      var cursor = event.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+
+      db.deleteObjectStore("store");
+      t.throws(
+        function () {
+          cursor.delete();
+        },
+        { name: "InvalidStateError" },
+        "If the cursor's source or effective object store has been deleted, 
the implementation MUST throw a DOMException of type InvalidStateError",
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - index - throw InvalidStateError when the cursor is 
being iterated
+test.cb("WPT idbcursor-delete-index5.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+    for (var i = 0; i < records.length; i++) {
+      objStore.add(records[i]);
+    }
+
+    var rq = objStore.index("index").openCursor();
+    rq.onsuccess = function (event: any) {
+      var cursor = event.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+
+      cursor.continue();
+      t.throws(
+        function () {
+          cursor.delete();
+        },
+        { name: "InvalidStateError" },
+      );
+
+      t.end();
+    };
+  };
+});
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-objectstore.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-objectstore.test.ts
new file mode 100644
index 00000000..7afe1e48
--- /dev/null
+++ 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-delete-objectstore.test.ts
@@ -0,0 +1,194 @@
+import test from "ava";
+import { BridgeIDBCursor } from "..";
+import { IDBCursor } from "../idbtypes";
+import { createdb, indexeddb_test } from "./wptsupport";
+
+// IDBCursor.delete() - object store - remove a record from the object store
+test.cb("WPT idbcursor-delete-objectstore.htm", (t) => {
+  var db: any,
+    count = 0,
+    records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = CursorDeleteRecord;
+
+  function CursorDeleteRecord(e: any) {
+    var txn = db.transaction("test", "readwrite"),
+      cursor_rq = txn.objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor != null, "cursor exist");
+      cursor.delete();
+    };
+
+    txn.oncomplete = VerifyRecordWasDeleted;
+  }
+
+  function VerifyRecordWasDeleted(e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      if (!cursor) {
+        t.deepEqual(count, 1, "count");
+        t.end();
+      }
+
+      t.deepEqual(cursor.value.pKey, records[1].pKey);
+      count++;
+      cursor.continue();
+    };
+  }
+});
+
+// IDBCursor.delete() - object store - attempt to remove a record in a 
read-only transaction
+test.cb("WPT idbcursor-delete-objectstore2.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.true(cursor != null, "cursor exist");
+      t.throws(
+        function () {
+          cursor.delete();
+        },
+        { name: "ReadOnlyError" },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - index - attempt to remove a record in an inactive 
transaction
+test.cb("WPT idbcursor-delete-objectstore3.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+
+    var cursor_rq = objStore.openCursor();
+
+    const window: any = {};
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+      window.cursor = cursor;
+    };
+
+    e.target.transaction.oncomplete = function (e: any) {
+      t.throws(
+        function () {
+          window.cursor.delete();
+        },
+        {
+          name: "TransactionInactiveError",
+        },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - object store - throw InvalidStateError caused by 
object store been deleted
+test.cb("WPT idbcursor-delete-objectstore4.htm", (t) => {
+  var db: any,
+    records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    for (var i = 0; i < records.length; i++) {
+      objStore.add(records[i]);
+    }
+    var rq = objStore.openCursor();
+    rq.onsuccess = function (event: any) {
+      var cursor = event.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+
+      db.deleteObjectStore("store");
+      t.throws(
+        function () {
+          cursor.delete();
+        },
+        { name: "InvalidStateError" },
+        "If the cursor's source or effective object store has been deleted, 
the implementation MUST throw a DOMException of type InvalidStateError",
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.delete() - object store - throw InvalidStateError when the cursor 
is being iterated
+test.cb("WPT idbcursor-delete-objectstore5.htm", (t) => {
+  var db: any,
+    records = [{ pKey: "primaryKey_0" }, { pKey: "primaryKey_1" }];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    for (var i = 0; i < records.length; i++) {
+      objStore.add(records[i]);
+    }
+  };
+
+  open_rq.onsuccess = function (event: any) {
+    var txn = db.transaction("store", "readwrite");
+    var rq = txn.objectStore("store").openCursor();
+    rq.onsuccess = function (event: any) {
+      var cursor = event.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+
+      cursor.continue();
+      t.throws(
+        function () {
+          cursor.delete();
+        },
+        {
+          name: "InvalidStateError",
+        },
+      );
+
+      t.end();
+    };
+  };
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-reused.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-reused.test.ts
index 44a647dc..3c2ee875 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-reused.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-reused.test.ts
@@ -14,7 +14,7 @@ test("WPT idbcursor-reused.htm", async (t) => {
       os.add("data2", "k2");
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var cursor: any;
       var count = 0;
       var rq = db.transaction("test").objectStore("test").openCursor();
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbcursor-update-index.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-update-index.test.ts
new file mode 100644
index 00000000..950a31e3
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbcursor-update-index.test.ts
@@ -0,0 +1,388 @@
+import test from "ava";
+import { BridgeIDBCursor, BridgeIDBKeyRange } from "..";
+import { BridgeIDBCursorWithValue } from "../bridge-idb";
+import { IDBDatabase } from "../idbtypes";
+import {
+  createDatabase,
+  createdb,
+  promiseForRequest,
+  promiseForTransaction,
+} from "./wptsupport";
+
+// IDBCursor.update() - index - modify a record in the object store
+test.cb("WPT test idbcursor_update_index.htm", (t) => {
+  var db: any,
+    count = 0,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+
+    // XXX: Gecko doesn't like this
+    //e.target.transaction.oncomplete = t.step_func(CursorUpdateRecord);
+  };
+
+  open_rq.onsuccess = CursorUpdateRecord;
+
+  function CursorUpdateRecord(e: any) {
+    var txn = db.transaction("test", "readwrite"),
+      cursor_rq = txn.objectStore("test").index("index").openCursor();
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      cursor.value.iKey += "_updated";
+      cursor.update(cursor.value);
+    };
+
+    txn.oncomplete = VerifyRecordWasUpdated;
+  }
+
+  function VerifyRecordWasUpdated(e: any) {
+    var cursor_rq = db.transaction("test").objectStore("test").openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      t.deepEqual(cursor.value.iKey, records[0].iKey + "_updated");
+      t.end();
+    };
+  }
+});
+
+// IDBCursor.update() - index - attempt to modify a record in a read-only 
transaction
+test.cb("WPT test idbcursor_update_index2.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("test")
+      .objectStore("test")
+      .index("index")
+      .openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.throws(
+        function () {
+          cursor.update(cursor.value);
+        },
+        { name: "ReadOnlyError" },
+      );
+      t.end();
+    };
+  };
+});
+
+//IDBCursor.update() - index - attempt to modify a record in an inactive 
transaction
+test.cb("WPT test idbcursor_update_index3.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    var index = objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+
+    var cursor_rq = index.openCursor();
+
+    const window: any = {};
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exist");
+      window.cursor = cursor;
+      window.record = cursor.value;
+    };
+
+    e.target.transaction.oncomplete = function (e: any) {
+      t.throws(
+        function () {
+          window.cursor.update(window.record);
+        },
+        { name: "TransactionInactiveError" },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.update() - index - attempt to modify a record when object store 
been deleted
+test.cb("WPT test idbcursor_update_index4.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+    for (var i = 0; i < records.length; i++) {
+      objStore.add(records[i]);
+    }
+    var rq = objStore.index("index").openCursor();
+    rq.onsuccess = function (event: any) {
+      var cursor = event.target.result;
+      t.true(cursor instanceof BridgeIDBCursor);
+
+      db.deleteObjectStore("store");
+      cursor.value.iKey += "_updated";
+      t.throws(
+        function () {
+          cursor.update(cursor.value);
+        },
+        { name: "InvalidStateError" },
+        "If the cursor's source or effective object store has been deleted, 
the implementation MUST throw a DOMException of type InvalidStateError",
+      );
+
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.update() - index - throw DataCloneError
+test.cb("WPT test idbcursor_update_index5.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("test", "readwrite")
+      .objectStore("test")
+      .index("index")
+      .openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor);
+
+      var record = cursor.value;
+      // Original test uses different uncloneable value
+      record.data = { foo: "42" };
+      record.data.me = record.data;
+      t.throws(
+        function () {
+          cursor.update(record);
+        },
+        { name: "DataCloneError" },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.update() - index - no argument
+test.cb("WPT test idbcursor_update_index6.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("test")
+      .objectStore("test")
+      .index("index")
+      .openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor);
+
+      t.throws(
+        function () {
+          cursor.update();
+        },
+        {
+          instanceOf: TypeError,
+        },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.update() - index - throw DataError
+test.cb("WPT test idbcursor_update_index7.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("test", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("test", "readwrite")
+      .objectStore("test")
+      .index("index")
+      .openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor);
+
+      t.throws(
+        function () {
+          cursor.update(null);
+        },
+        { name: "DataError" },
+      );
+      t.end();
+    };
+  };
+});
+
+// IDBCursor.update() - index - throw InvalidStateError when the cursor is 
being iterated
+test.cb("WPT test idbcursor_update_index8.htm", (t) => {
+  var db: any,
+    records = [
+      { pKey: "primaryKey_0", iKey: "indexKey_0" },
+      { pKey: "primaryKey_1", iKey: "indexKey_1" },
+    ];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var objStore = db.createObjectStore("store", { keyPath: "pKey" });
+    objStore.createIndex("index", "iKey");
+
+    for (var i = 0; i < records.length; i++) objStore.add(records[i]);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var cursor_rq = db
+      .transaction("store", "readwrite")
+      .objectStore("store")
+      .index("index")
+      .openCursor();
+
+    cursor_rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+      t.true(cursor instanceof BridgeIDBCursor, "cursor exists");
+
+      cursor.continue();
+      t.throws(
+        function () {
+          cursor.update({ pKey: "primaryKey_0", iKey: "indexKey_0_updated" });
+        },
+        {
+          name: "InvalidStateError",
+        },
+      );
+
+      t.end();
+    };
+  };
+});
+
+// Index cursor - indexed values updated during iteration
+test("WPT test idbcursor_update_index9.any.js", async (t) => {
+  const db = await createDatabase(t, (db) => {
+    const store = db.createObjectStore("store");
+    store.createIndex("index", "value");
+    store.put({ value: 1 }, 1);
+    store.put({ value: 2 }, 2);
+    store.put({ value: 3 }, 3);
+  });
+
+  {
+    // Iterate over all index entries until an upper bound is reached.
+    // On each record found, increment the value used as the index
+    // key, which will make it show again up later in the iteration.
+    const tx = db.transaction("store", "readwrite");
+    const range = BridgeIDBKeyRange.upperBound(9);
+    const index = tx.objectStore("store").index("index");
+    const request = index.openCursor(range);
+    request.onsuccess = (e: any) => {
+      const cursor = e.target.result;
+      if (!cursor) return;
+
+      const record = cursor.value;
+      record.value += 1;
+      cursor.update(record);
+
+      cursor.continue();
+    };
+
+    await promiseForTransaction(t, tx);
+  }
+
+  {
+    const tx = db.transaction("store", "readonly");
+    const results = await promiseForRequest(
+      t,
+      tx.objectStore("store").getAll(),
+    );
+    t.deepEqual(
+      results.map((record) => record.value),
+      [10, 10, 10],
+      "Values should all be incremented until bound reached",
+    );
+  }
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts
index 0d1f24c4..bba9c6e5 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbfactory-open.test.ts
@@ -8,7 +8,7 @@ test("WPT idbfactory-open.htm", async (t) => {
   await new Promise<void>((resolve, reject) => {
     var open_rq = createdb(t, undefined, 9);
 
-    open_rq.onupgradeneeded = function (e) {};
+    open_rq.onupgradeneeded = function (e: any) {};
     open_rq.onsuccess = function (e: any) {
       t.deepEqual(e.target.source, null, "source");
       resolve();
@@ -23,7 +23,7 @@ test("WPT idbfactory-open2.htm", async (t) => {
     var database_name = t.title + "-database_name";
     var open_rq = createdb(t, database_name, 13);
 
-    open_rq.onupgradeneeded = function (e) {};
+    open_rq.onupgradeneeded = function (e: any) {};
     open_rq.onsuccess = function (e: any) {
       var db = e.target.result;
       t.deepEqual(db.name, database_name, "db.name");
@@ -302,7 +302,7 @@ test("WPT idbfactory-open10.htm", async (t) => {
       st.add({ i: "Joshua" }, 1);
       st.add({ i: "Jonas" }, 2);
     };
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       db.close();
       var open_rq2 = indexedDB.open(db.name, 10);
       open_rq2.onupgradeneeded = function (e: any) {
@@ -434,7 +434,7 @@ test("WPT idbfactory-open11.htm", async (t) => {
 
       store.add("data2", 2);
     };
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var store = db.transaction("store").objectStore("store");
       t.deepEqual(store.name, "store", "store.name");
       store.count().onsuccess = function (e: any) {
@@ -491,7 +491,7 @@ test("WPT idbfactory-open12.htm", async (t) => {
 
       t.deepEqual(db.version, 9, "db.version");
     };
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       t.true(e instanceof FakeEvent, "e instanceof Event");
       t.false(
         e instanceof BridgeIDBVersionChangeEvent,
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbindex-get.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbindex-get.test.ts
index 7601faad..751b4f98 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbindex-get.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbindex-get.test.ts
@@ -18,7 +18,7 @@ test("WPT idbindex_get.htm", async (t) => {
       objStore.add(record);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var rq = db
         .transaction("store")
         .objectStore("store")
@@ -53,7 +53,7 @@ test("WPT idbindex_get2.htm", async (t) => {
       for (var i = 0; i < records.length; i++) objStore.add(records[i]);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var rq = db
         .transaction("test")
         .objectStore("test")
@@ -107,7 +107,7 @@ test("WPT idbindex_get4.htm", async (t) => {
       }
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var rq = db
         .transaction("store")
         .objectStore("store")
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbindex-openCursor.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbindex-openCursor.test.ts
new file mode 100644
index 00000000..2dcab603
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbindex-openCursor.test.ts
@@ -0,0 +1,80 @@
+import test from "ava";
+import { BridgeIDBCursor } from "..";
+import { BridgeIDBCursorWithValue } from "../bridge-idb";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBIndex.openCursor() - throw InvalidStateError when the index is deleted
+test.cb("WPT test idbindex-openCursor.htm", (t) => {
+  var db;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var store = db.createObjectStore("store", { keyPath: "key" });
+    var index = store.createIndex("index", "indexedProperty");
+
+    store.add({ key: 1, indexedProperty: "data" });
+    store.deleteIndex("index");
+
+    t.throws(
+      () => {
+        index.openCursor();
+      },
+      { name: "InvalidStateError" },
+    );
+
+    t.end();
+  };
+});
+
+// IDBIndex.openCursor() - throw TransactionInactiveError on aborted 
transaction
+test.cb("WPT test idbindex-openCursor2.htm", (t) => {
+  var db;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var store = db.createObjectStore("store", { keyPath: "key" });
+    var index = store.createIndex("index", "indexedProperty");
+    store.add({ key: 1, indexedProperty: "data" });
+  };
+  open_rq.onsuccess = function (e: any) {
+    db = e.target.result;
+    var tx = db.transaction("store");
+    var index = tx.objectStore("store").index("index");
+    tx.abort();
+
+    t.throws(
+      () => {
+        index.openCursor();
+      },
+      { name: "TransactionInactiveError" },
+    );
+
+    t.end();
+  };
+});
+
+
+// IDBIndex.openCursor() - throw InvalidStateError on index deleted by aborted 
upgrade
+test.cb("WPT test idbindex-openCursor3.htm", (t) => {
+  var db;
+
+var open_rq = createdb(t);
+open_rq.onupgradeneeded = function(e: any) {
+  db = e.target.result;
+  var store = db.createObjectStore("store", { keyPath: "key" });
+  var index = store.createIndex("index", "indexedProperty");
+  store.add({ key: 1, indexedProperty: "data" });
+
+  e.target.transaction.abort();
+
+  t.throws(() => {
+    console.log("index before openCursor", index);
+    index.openCursor();
+  }, { name: "InvalidStateError"});
+
+  t.end();
+}
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add.test.ts
index b8fdb5ac..02f05f46 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-add.test.ts
@@ -17,7 +17,7 @@ test("WPT idbobjectstore_add.htm", async (t) => {
       objStore.add(record);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var rq = db!.transaction("store").objectStore("store").get(record.key);
 
       rq.onsuccess = function (e: any) {
@@ -45,7 +45,7 @@ test("WPT idbobjectstore_add2.htm", async (t) => {
       objStore.add(record, key);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var rq = db.transaction("store").objectStore("store").get(key);
 
       rq.onsuccess = function (e: any) {
@@ -82,7 +82,7 @@ test("WPT idbobjectstore_add3.htm", async (t) => {
     };
 
     // Defer done, giving rq.onsuccess a chance to run
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       resolve();
     };
   });
@@ -115,7 +115,7 @@ test("WPT idbobjectstore_add4.htm", async (t) => {
     };
 
     // Defer done, giving a spurious rq.onsuccess a chance to run
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       resolve();
     };
   });
@@ -171,7 +171,7 @@ test("WPT idbobjectstore_add6.htm", async (t) => {
       objStore.add(record);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var actual_keys: any[] = [],
         rq = db.transaction("store").objectStore("store").openCursor();
 
@@ -209,7 +209,7 @@ test("WPT idbobjectstore_add7.htm", async (t) => {
       objStore.add(record);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var actual_keys: any[] = [],
         rq = db.transaction("store").objectStore("store").openCursor();
 
@@ -251,7 +251,7 @@ test("WPT idbobjectstore_add8.htm", async (t) => {
       objStore.add(record);
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var actual_keys: any[] = [],
         rq = db.transaction("store").objectStore("store").openCursor();
 
@@ -445,7 +445,7 @@ test("WPT idbobjectstore_add15.htm", async (t) => {
       db.createObjectStore("store", { keyPath: "pKey" });
     };
 
-    open_rq.onsuccess = function (event) {
+    open_rq.onsuccess = function (event: any) {
       var txn = db.transaction("store");
       var ostore = txn.objectStore("store");
       t.throws(
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-get.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-get.test.ts
new file mode 100644
index 00000000..0c9d30b7
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-get.test.ts
@@ -0,0 +1,159 @@
+import test from "ava";
+import { BridgeIDBKeyRange, BridgeIDBRequest } from "..";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBObjectStore.get() - key is a number
+test.cb("WPT idbobjectstore_get.htm", (t) => {
+  var db: any,
+    record = { key: 3.14159265, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    db.createObjectStore("store", { keyPath: "key" }).add(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db.transaction("store").objectStore("store").get(record.key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.key, record.key);
+      t.deepEqual(e.target.result.property, record.property);
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.get() - key is a string
+test.cb("WPT idbobjectstore_get2.htm", (t) => {
+  var db: any,
+    record = { key: "this is a key that's a string", property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    db.createObjectStore("store", { keyPath: "key" }).add(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db.transaction("store").objectStore("store").get(record.key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.key, record.key);
+      t.deepEqual(e.target.result.property, record.property);
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.get() - key is a date
+test.cb("WPT idbobjectstore_get3.htm", (t) => {
+  var db: any;
+  const record = { key: new Date(), property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    db.createObjectStore("store", { keyPath: "key" }).add(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db.transaction("store").objectStore("store").get(record.key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.key.valueOf(), record.key.valueOf());
+      t.deepEqual(e.target.result.property, record.property);
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.get() - attempt to retrieve a record that doesn't exist
+test.cb("WPT idbobjectstore_get4.htm", (t) => {
+  var db: any;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var rq = db.createObjectStore("store", { keyPath: "key" }).get(1);
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.results, undefined);
+      setTimeout(function () {
+        t.end();
+      }, 10);
+    };
+  };
+
+  open_rq.onsuccess = function () {};
+});
+
+// IDBObjectStore.get() - returns the record with the first key in the range
+test.cb("WPT idbobjectstore_get5.htm", (t) => {
+  var db: any;
+  var open_rq = createdb(t);
+
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var os = db.createObjectStore("store");
+
+    for (var i = 0; i < 10; i++) os.add("data" + i, i);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    db
+      .transaction("store")
+      .objectStore("store")
+      .get(BridgeIDBKeyRange.bound(3, 6)).onsuccess = function (e: any) {
+      t.deepEqual(e.target.result, "data3", "get(3-6)");
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.get() - throw TransactionInactiveError on aborted transaction
+test.cb("WPT idbobjectstore_get6.htm", (t) => {
+  var db: any;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    db.createObjectStore("store", { keyPath: "key" });
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var store = db.transaction("store").objectStore("store");
+    store.transaction.abort();
+    t.throws(
+      function () {
+        store.get(1);
+      },
+      { name: "TransactionInactiveError" },
+      "throw TransactionInactiveError on aborted transaction.",
+    );
+    t.end();
+  };
+});
+
+// IDBObjectStore.get() - throw DataError when using invalid key
+test.cb("WPT idbobjectstore_get7.htm", (t) => {
+  var db: any;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    db.createObjectStore("store", { keyPath: "key" });
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var store = db.transaction("store").objectStore("store");
+    t.throws(
+      function () {
+        store.get(null);
+      },
+      { name: "DataError" },
+      "throw DataError when using invalid key.",
+    );
+    t.end();
+  };
+});
diff --git a/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-put.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-put.test.ts
new file mode 100644
index 00000000..3ca1b8ec
--- /dev/null
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbobjectstore-put.test.ts
@@ -0,0 +1,449 @@
+import test from "ava";
+import { BridgeIDBKeyRange, BridgeIDBRequest } from "..";
+import { IDBDatabase } from "../idbtypes";
+import { createdb } from "./wptsupport";
+
+// IDBObjectStore.put() - put with an inline key
+test.cb("WPT idbobjectstore_put.htm", (t) => {
+  var db: any,
+    record = { key: 1, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    objStore.put(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db.transaction("store").objectStore("store").get(record.key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.property, record.property);
+      t.deepEqual(e.target.result.key, record.key);
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.put() - put with an out-of-line key
+test.cb("WPT idbobjectstore_put2.htm", (t) => {
+  var db: any,
+    key = 1,
+    record = { property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store");
+
+    objStore.put(record, key);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db.transaction("store").objectStore("store").get(key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.property, record.property);
+
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.put() - put with an out-of-line key
+test.cb("WPT idbobjectstore_put3.htm", (t) => {
+  var db: any,
+    success_event: any,
+    record = { key: 1, property: "data" },
+    record_put = { key: 1, property: "changed", more: ["stuff", 2] };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "key" });
+    objStore.put(record);
+
+    var rq = objStore.put(record_put);
+    rq.onerror = () => t.fail("error on put");
+
+    rq.onsuccess = function (e: any) {
+      success_event = true;
+    };
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    t.true(success_event);
+
+    var rq = db.transaction("store").objectStore("store").get(1);
+
+    rq.onsuccess = function (e: any) {
+      var rec = e.target.result;
+
+      t.deepEqual(rec.key, record_put.key);
+      t.deepEqual(rec.property, record_put.property);
+      t.deepEqual(rec.more, record_put.more);
+
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.put() - put where an index has unique:true specified
+test.cb("WPT idbobjectstore_put4.htm", (t) => {
+  var db: any,
+    record = { key: 1, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", { autoIncrement: true });
+    objStore.createIndex("i1", "property", { unique: true });
+    objStore.put(record);
+
+    var rq = objStore.put(record);
+    rq.onsuccess = () => t.fail("success on putting duplicate indexed record");
+
+    rq.onerror = function (e: any) {
+      t.deepEqual(rq.error.name, "ConstraintError");
+      t.deepEqual(e.target.error.name, "ConstraintError");
+
+      t.deepEqual(e.type, "error");
+
+      e.preventDefault();
+      e.stopPropagation();
+    };
+  };
+
+  // Defer done, giving a spurious rq.onsuccess a chance to run
+  open_rq.onsuccess = function (e: any) {
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - object store's key path is an object attribute
+test.cb("WPT idbobjectstore_put5.htm", (t) => {
+  var db: any,
+    record = { test: { obj: { key: 1 } }, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", { keyPath: "test.obj.key" });
+    objStore.put(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var rq = db
+      .transaction("store")
+      .objectStore("store")
+      .get(record.test.obj.key);
+
+    rq.onsuccess = function (e: any) {
+      t.deepEqual(e.target.result.property, record.property);
+
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.put() - autoIncrement and inline keys
+test.cb("WPT idbobjectstore_put6.htm", (t) => {
+  var db: any,
+    record = { property: "data" },
+    expected_keys = [1, 2, 3, 4];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", {
+      keyPath: "key",
+      autoIncrement: true,
+    });
+
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var actual_keys: any[] = [],
+      rq = db.transaction("store").objectStore("store").openCursor();
+
+    rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      if (cursor) {
+        actual_keys.push(cursor.value.key);
+        cursor.continue();
+      } else {
+        t.deepEqual(actual_keys, expected_keys);
+        t.end();
+      }
+    };
+  };
+});
+
+// IDBObjectStore.put() - autoIncrement and out-of-line keys
+test.cb("WPT idbobjectstore_put7.htm", (t) => {
+  var db: any,
+    record = { property: "data" },
+    expected_keys = [1, 2, 3, 4];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", { autoIncrement: true });
+
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+  };
+
+  open_rq.onsuccess = function (e) {
+    var actual_keys: any[] = [],
+      rq = db.transaction("store").objectStore("store").openCursor();
+
+    rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      if (cursor) {
+        actual_keys.push(cursor.key);
+        cursor.continue();
+      } else {
+        t.deepEqual(actual_keys, expected_keys);
+        t.end();
+      }
+    };
+  };
+});
+
+// IDBObjectStore.put() - object store has autoIncrement:true and the key path 
is an object attribute
+test.cb("WPT idbobjectstore_put8.htm", (t) => {
+  var db: any,
+    record = { property: "data" },
+    expected_keys = [1, 2, 3, 4];
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+    var objStore = db.createObjectStore("store", {
+      keyPath: "test.obj.key",
+      autoIncrement: true,
+    });
+
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+    objStore.put(record);
+  };
+
+  open_rq.onsuccess = function (e: any) {
+    var actual_keys: any[] = [],
+      rq = db.transaction("store").objectStore("store").openCursor();
+
+    rq.onsuccess = function (e: any) {
+      var cursor = e.target.result;
+
+      if (cursor) {
+        actual_keys.push(cursor.value.test.obj.key);
+        cursor.continue();
+      } else {
+        t.deepEqual(actual_keys, expected_keys);
+        t.end();
+      }
+    };
+  };
+});
+
+//IDBObjectStore.put() - Attempt to put a record that does not meet the 
constraints of an object store's inline key requirements
+test.cb("WPT idbobjectstore_put9.htm", (t) => {
+  var record = { key: 1, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    var rq,
+      db = e.target.result,
+      objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    t.throws(
+      function () {
+        rq = objStore.put(record, 1);
+      },
+      { name: "DataError" },
+    );
+
+    t.deepEqual(rq, undefined);
+    t.end();
+  };
+});
+
+//IDBObjectStore.put() - Attempt to call 'put' without an key parameter when 
the object store uses out-of-line keys
+test.cb("WPT idbobjectstore_put10.htm", (t) => {
+  var db: any,
+    record = { property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var rq,
+      objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    t.throws(
+      function () {
+        rq = objStore.put(record);
+      },
+      { name: "DataError" },
+    );
+
+    t.deepEqual(rq, undefined);
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - Attempt to put a record where the record's key does 
not meet the constraints of a valid key
+test.cb("WPT idbobjectstore_put11.htm", (t) => {
+  var db: any,
+    record = { key: { value: 1 }, property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var rq,
+      objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    t.throws(
+      function () {
+        rq = objStore.put(record);
+      },
+      { name: "DataError" },
+    );
+
+    t.deepEqual(rq, undefined);
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - Attempt to put a record where the record's in-line 
key is not defined
+test.cb("WPT idbobjectstore_put12.htm", (t) => {
+  var db: any,
+    record = { property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var rq,
+      objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    t.throws(
+      function () {
+        rq = objStore.put(record);
+      },
+      { name: "DataError" },
+    );
+
+    t.deepEqual(rq, undefined);
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - Attempt to put a record where the out of line key 
provided does not meet the constraints of a valid key
+test.cb("WPT idbobjectstore_put13.htm", (t) => {
+  var db: any,
+    record = { property: "data" };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var rq,
+      objStore = db.createObjectStore("store");
+
+    t.throws(
+      function () {
+        rq = objStore.put(record, { value: 1 });
+      },
+      {
+        name: "DataError",
+      },
+    );
+
+    t.deepEqual(rq, undefined);
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - Put a record where a value being indexed does not 
meet the constraints of a valid key
+test.cb("WPT idbobjectstore_put14.htm", (t) => {
+  var db: any,
+    record = { key: 1, indexedProperty: { property: "data" } };
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (e: any) {
+    db = e.target.result;
+
+    var rq,
+      objStore = db.createObjectStore("store", { keyPath: "key" });
+
+    objStore.createIndex("index", "indexedProperty");
+
+    rq = objStore.put(record);
+
+    t.true(rq instanceof BridgeIDBRequest);
+    rq.onsuccess = function () {
+      t.end();
+    };
+  };
+});
+
+// IDBObjectStore.put() - If the transaction this IDBObjectStore belongs to 
has its mode set to readonly, throw ReadOnlyError
+test.cb("WPT idbobjectstore_put15.htm", (t) => {
+  var db: any;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    db.createObjectStore("store", { keyPath: "pKey" });
+  };
+
+  open_rq.onsuccess = function (event: any) {
+    var txn = db.transaction("store");
+    var ostore = txn.objectStore("store");
+    t.throws(
+      function () {
+        ostore.put({ pKey: "primaryKey_0" });
+      },
+      {
+        name: "ReadOnlyError",
+      },
+    );
+    t.end();
+  };
+});
+
+// IDBObjectStore.put() - If the object store has been deleted, the 
implementation must throw a DOMException of type InvalidStateError
+test.cb("WPT idbobjectstore_put16.htm", (t) => {
+  var db: any, ostore: any;
+
+  var open_rq = createdb(t);
+  open_rq.onupgradeneeded = function (event: any) {
+    db = event.target.result;
+    ostore = db.createObjectStore("store", { keyPath: "pKey" });
+    db.deleteObjectStore("store");
+    t.throws(
+      function () {
+        ostore.put({ pKey: "primaryKey_0" });
+      },
+      {
+        name: "InvalidStateError",
+      },
+    );
+    t.end();
+  };
+});
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts
index 8e0b4387..8f54fb7c 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/idbtransaction-oncomplete.test.ts
@@ -20,7 +20,7 @@ test("WPT idbtransaction-oncomplete.htm", async (t) => {
       };
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       stages.push("success");
 
       // Making a totally new transaction to check
diff --git a/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts
index 61e416a5..20ec6f3f 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/keypath.test.ts
@@ -15,14 +15,14 @@ test("WPT test keypath.htm", async (t) => {
       const store_name = "store-" + Date.now() + Math.random();
 
       var open_rq = createdb(t);
-      open_rq.onupgradeneeded = function (e) {
+      open_rq.onupgradeneeded = function (e: any) {
         db = (e.target as any).result;
         var objStore = db.createObjectStore(store_name, { keyPath: keypath });
 
         for (var i = 0; i < objects.length; i++) objStore.add(objects[i]);
       };
 
-      open_rq.onsuccess = function (e) {
+      open_rq.onsuccess = function (e: any) {
         var actual_keys: any[] = [],
           rq = db.transaction(store_name).objectStore(store_name).openCursor();
 
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/request-bubble-and-capture.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/request-bubble-and-capture.test.ts
index c59a63bc..a7541a68 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/request-bubble-and-capture.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/request-bubble-and-capture.test.ts
@@ -32,7 +32,7 @@ test("WPT request_bubble-and-capture.htm", async (t) => {
       );
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       log("open_rq.success")(e);
       t.deepEqual(
         events,
diff --git 
a/packages/idb-bridge/src/idb-wpt-ported/transaction-requestqueue.test.ts 
b/packages/idb-bridge/src/idb-wpt-ported/transaction-requestqueue.test.ts
index edf98eb5..707bb525 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/transaction-requestqueue.test.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/transaction-requestqueue.test.ts
@@ -23,7 +23,7 @@ test("transaction-requestqueue.htm", async (t) => {
       }
     };
 
-    open_rq.onsuccess = function (e) {
+    open_rq.onsuccess = function (e: any) {
       var txn = db.transaction(["os2", "os1", "os3", "os5"]);
       txn.objectStore("os1").openCursor().onsuccess = reg("txn");
       txn.objectStore("os3").openCursor().onsuccess = reg("txn");
diff --git a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts 
b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
index 5f6b0a04..d6c0b011 100644
--- a/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
+++ b/packages/idb-bridge/src/idb-wpt-ported/wptsupport.ts
@@ -12,9 +12,9 @@ import {
 import { MemoryBackend } from "../MemoryBackend";
 import { compareKeys } from "../util/cmp";
 
-BridgeIDBFactory.enableTracing = false;
+BridgeIDBFactory.enableTracing = true;
 const backend = new MemoryBackend();
-backend.enableTracing = false;
+backend.enableTracing = true;
 export const idbFactory = new BridgeIDBFactory(backend);
 
 const self = {
@@ -43,12 +43,6 @@ export function assert_key_equals(
   }
 }
 
-export function assert_equals(actual: any, expected: any) {
-  if (actual !== expected) {
-    throw Error("assert_equals failed");
-  }
-}
-
 function makeDatabaseName(testCase: string): string {
   return "db-" + testCase;
 }
@@ -59,7 +53,7 @@ function makeDatabaseName(testCase: string): string {
 // other event causes the promise to reject with an error. This is correct in
 // most cases, but insufficient for indexedDB.open(), which issues
 // "upgradeneded" events under normal operation.
-function promiseForRequest<T = any>(
+export function promiseForRequest<T = any>(
   t: ExecutionContext,
   request: IDBRequest<T>,
 ): Promise<T> {
@@ -75,6 +69,23 @@ function promiseForRequest<T = any>(
   });
 }
 
+// Promise that resolves when an IDBTransaction completes.
+//
+// The promise resolves with undefined if IDBTransaction receives the 
"complete"
+// event, and rejects with an error for any other event.
+export function promiseForTransaction(
+  t: ExecutionContext,
+  request: IDBTransaction,
+) {
+  return new Promise<any>((resolve, reject) => {
+    request.addEventListener("complete", (evt: any) => {
+      resolve(evt.target.result);
+    });
+    request.addEventListener("abort", (evt: any) => reject(evt.target.error));
+    request.addEventListener("error", (evt: any) => reject(evt.target.error));
+  });
+}
+
 type MigrationCallback = (
   db: IDBDatabase,
   tx: IDBTransaction,
@@ -430,7 +441,7 @@ export function format_value(val: any, seen?: any): string {
 //     },
 //     (test_object, db_connection, open_request) => {
 //        // Test logic.
-//        test_object.done();
+//        test_object.end();
 //     },
 //     'Test case description');
 export function indexeddb_test(
@@ -460,7 +471,7 @@ export function indexeddb_test(
       var db = open.result;
       t.teardown(function () {
         // If open didn't succeed already, ignore the error.
-        open.onerror = function (e) {
+        open.onerror = function (e: any) {
           e.preventDefault();
         };
         db.close();

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]