filer
filer copied to clipboard
Does not skip browser tests when IndexedDB is not supported
While attempting to verify #433, I ran into an interesting issue when running the in-browser tests using Firefox 63.0b2 (64-bit).
Skipping provider tests for `WebSQL'--not supported in current environment. providers.base.js:13:4
TypeError: this.db is null, can't access property "transaction" of it indexeddb.js:22:6
IndexedDB is not always supported in every browser context. Notably, Incognito in Chrome supports IndexedDB, but Private Browsing Mode in Firefox does not.
In the above error message, the tests are not run for the WebSQL provider as intended in Private Browsing Mode, but it does not skip the tests for IndexedDB as it should.
If the issue relates to Private Browsing and Firefox, the problem is that the browser reports that indexDB
is available, but throws when you try to access it. We've filed this with Mozilla, and it's in their queue, but hasn't been addressed yet. Chrome allows the tests to work in a private tab, but then deletes the DB. I'm not sure we can fix this on our end.
For IndexedDB.isSupported()
, it simply checks if the indexedDB
reference grabbed from global
exists.
We could enhance this feature detection to actually attempt an operation on IndexedDB, such as opening a connection, test if it succeeds or fails, and then cache the result for future calls to isSupported()
. I found an (MIT-licensed) example in Modernizr on how we could go about doing this.
@0xazure unfortunately, it's not that simple. I've discussed this with the IndexedDB
devs at Mozilla in the past. Firefox will throw
a security exception, which is un-catchable if you touch it. There is a way to do this, but it's a bit hacky:
- create an
iframe
-
postMessage
to theiframe
and ask it to test for you - in the
iframe
, setup atimeout
to respond back to theparent
window indicating failure - try to touch open a db connection and then
postMessage
back to theparent
that it worked, removing your failuretimeout
.
In this way you can safely fail to access the db, and send back info on whether or not it exists and can be used.
Firefox will
throw
a security exception, which is un-catchable if you touch it.
Interesting! On Firefox 61.0.2 (64-bit)
and 63.0b8 (64-bit)
I'm not able to reproduce this behaviuor with the following snippet:
var DBOpenRequest = window.indexedDB.open(`test-${Math.random()}`);
DBOpenRequest.onsuccess = function(e) {
console.log('have IndexedDB instance');
}
DBOpenRequest.onerror = function(e) {
console.log('open request failed');
}
Running the snippet from Scratchpad, in a normal window I get the have IndexedDB instance
message and in a Private Browsing Mode window I get open request failed
as expected. I don't get any throw
n errors, un-catchable or otherwise.
Perhaps the behaviour changed in newer versions of Firefox? I don't have access to any pre-Quantum versions right now, so it would take some investigation to determine if this is the case.
Sounds like things have changed, which would be great.
@humphd where would we like to go with this? I can have a look at implementing some better IndexedDB detection, but I'm not sure how we want to go about verifying behaviour on older versions of the supported browsers so we don't trigger unrecoverable security exceptions.