<!DOCTYPE html>
<title>IndexedDB: Dispatching events from script</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script>
function idb_test(func, name) {
async_test(t => {
const dbname = location.pathname + ' - ' + t.name;
const open_request = indexedDB.open(dbname);
t.add_cleanup(() => { indexedDB.deleteDatabase(dbname); });
func(t, open_request);
}, name);
}
//
// IDBOpenDBRequest
//
// A regression test for http://crbug.com/1032890
idb_test((t, open_request) => {
open_request.onerror = t.unreached_func();
open_request.onsuccess = t.step_func_done();
open_request.dispatchEvent(new ErrorEvent({}));
}, 'Dispatching a generic event at an IDBOpenDBRequest should not crash');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onblocked = t.step_func(e => {
++events_seen;
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 1, 'Should have seen event');
});
open_request.dispatchEvent(new Event('blocked'));
}, 'Dispatching a synthetic blocked event at an IDBOpenDBRequest');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.step_func(e => {
++events_seen;
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 1, 'Should have seen event');
});
open_request.dispatchEvent(new Event('error'));
}, 'Dispatching a synthetic error event at an IDBOpenDBRequest');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
++events_seen;
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 2, 'Should have seen both events');
});
open_request.dispatchEvent(new Event('upgradeneeded'));
}, 'Dispatching a synthetic upgradeneeded event at an IDBOpenDBRequest');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onsuccess = t.step_func(e => {
++events_seen;
if (e.isTrusted) {
assert_equals(events_seen, 2, 'Should have seen both events');
t.done();
}
});
open_request.dispatchEvent(new Event('success'));
}, 'Dispatching a synthetic success event at an IDBOpenDBRequest');
//
// IDBTransaction
//
idb_test((t, open_request) => {
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const tx = open_request.transaction;
tx.dispatchEvent(new Event('generic'));
});
open_request.onsuccess = t.step_func_done();
}, 'Dispatching a generic event at an IDBTransaction should not crash');
[
// Events that would be propagated from an IDBRequest:
'success', 'error',
// Events that would be fired at an IDBTransaction:
'abort'
].forEach(type => {
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const tx = open_request.transaction;
tx.addEventListener(type, t.step_func(e => {
assert_false(e.isTrusted, 'Event should not be trusted');
++events_seen;
}));
tx.dispatchEvent(new Event(type));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 1, 'Should have seen event');
});
}, `Dispatching a synthetic ${type} event at an IDBTransaction`);
});
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const tx = open_request.transaction;
tx.oncomplete = t.step_func(e => {
++events_seen;
});
tx.dispatchEvent(new Event('complete'));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 2, 'Should have seen both events');
});
}, 'Dispatching a synthetic complete event at an IDBTransaction');
idb_test((t, open_request) => {
const targets = []
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
const tx = open_request.transaction;
[db, tx].forEach(target => target.addEventListener(
'generic',
t.step_func(e => { targets.push(e.currentTarget.constructor.name); })
));
tx.dispatchEvent(new Event('generic', {bubbles: true}));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(targets.length, 2, 'Event should propagate');
assert_equals(targets[0], 'IDBTransaction',
'First target should be transaction');
assert_equals(targets[1], 'IDBDatabase',
'Second target should be database');
});
}, 'Dispatching a generic event at an IDBTransaction propagates correctly');
//
// IDBRequest
//
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
const store = db.createObjectStore('store');
const request = store.get(0);
request.dispatchEvent(new Event('generic'));
});
open_request.onsuccess = t.step_func_done();
}, 'Dispatching a generic event at an IDBRequest should not crash');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
const store = db.createObjectStore('store');
const request = store.get(0);
request.onerror = t.step_func(e => {
++events_seen;
});
request.dispatchEvent(new Event('error'));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 1, 'Should have seen the event');
});
}, 'Dispatching a synthetic error event at an IDBRequest');
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
const store = db.createObjectStore('store');
const request = store.get(0);
request.onsuccess = t.step_func(e => {
++events_seen;
});
request.dispatchEvent(new Event('success'));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 2, 'Should have seen both events');
});
}, 'Dispatching a synthetic success event at an IDBRequest');
idb_test((t, open_request) => {
const targets = []
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
const tx = open_request.transaction;
const store = db.createObjectStore('store');
const request = store.get(0);
[db, tx, request].forEach(target => target.addEventListener(
'generic',
t.step_func(e => { targets.push(e.currentTarget.constructor.name); })
));
request.dispatchEvent(new Event('generic', {bubbles: true}));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(targets.length, 3, 'Event should propagate');
assert_equals(targets[0], 'IDBRequest',
'First target should be request');
assert_equals(targets[1], 'IDBTransaction',
'Second target should be transaction');
assert_equals(targets[2], 'IDBDatabase',
'Third target should be database');
});
}, 'Dispatching a generic event at an IDBRequest propagates correctly');
//
// IDBDatabase
//
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
db.dispatchEvent(new Event('generic'));
});
open_request.onsuccess = t.step_func_done();
}, 'Dispatching a generic event at an IDBDatabase');
[
// Events that would be propagated from an IDBRequest:
'success', 'error',
// Events that would be propagated from an IDBTransaction:
'complete', 'abort',
// Events that would be fired at an IDBDatabase:
'versionchange', 'close'
].forEach(type => {
idb_test((t, open_request) => {
let events_seen = 0;
open_request.onerror = t.unreached_func();
open_request.onupgradeneeded = t.step_func(e => {
const db = open_request.result;
db.addEventListener(type, t.step_func(e => {
assert_false(e.isTrusted, 'Event should not be trusted');
++events_seen;
}));
db.dispatchEvent(new Event(type));
});
open_request.onsuccess = t.step_func_done(e => {
assert_equals(events_seen, 1, 'Should have seen the event');
});
}, `Dispatching a synthetic ${type} event at an IDBDatabase`);
});
</script>