servo icon indicating copy to clipboard operation
servo copied to clipboard

indexeddb: move database open and upgrade transaction to in parallel.

Open gterzian opened this issue 1 month ago • 27 comments

The spec concept of opening a database, and the conditional upgrade of a database, should be run in-parallel, meaning on the backend indexeddb thread, and not on the script-thread.

This implements the move, but retains a blocking wait on the upgrade transaction finish. It is the first step towards a larger refactoring(see https://github.com/servo/servo/issues/40983), which will see concepts like transaction lifecyle and connection queues be implemented on the indexeddb thread, and which will make any waiting non-blocking as well.

Other smaller changes to support the above are:

  • returning whether a physical db was created when instantiating the db engine.
  • using a global counter to produce transaction ids.

Testing: New failures on WPT tests: to be fixed as part of several follow-ups. Fixes: The parts of https://github.com/servo/servo/issues/38942#issuecomment-3270223903 that were not addressed when the issue was closed.

gterzian avatar Nov 28 '25 13:11 gterzian

@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.

gterzian avatar Dec 02 '25 13:12 gterzian

@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.

Yes, the database opening, and in fact all IDB factory operations, need to run primarily in the backend, so this refactoring makes complete sense to me.

janvarga avatar Dec 02 '25 14:12 janvarga

@Taym95 @janvarga @jdm @arihant2math This completes the initial refactoring; I will try to run the tests tomorrow and fix any issues that come-up. Welcome to take a look already.

I will take look tonight!

Taym95 avatar Dec 02 '25 14:12 Taym95

One thing is that since this now blocks the idb thread(instead of script), it might create other issues, even deadlocks if script does a blocking call within the upgrade event handler. But I'll look into those things when I run tests tomorrow.

Trying to keep it simple for now since a non-blocking workflow would take a lot more changes because it requires implementing the entire transaction lifecycle as a backend state machine as well as making all other operations async.

gterzian avatar Dec 02 '25 14:12 gterzian

Yeah an operation like CreateObjectStore will deadlock if indexeddb is blocking, so I think I'll have to add a simple beginning of an async transaction system tomorrow. (there is one such system in place already, but it's sort of driven by script now, and like the rest it needs to be switched to parallel steps)

gterzian avatar Dec 02 '25 15:12 gterzian

Will take a look later today.

arihant2math avatar Dec 02 '25 22:12 arihant2math

So I introduced an async worfklow for the open request: it is a first step and it should be merged into something general dealing with transaction lifecyle. But this fixes the deadlock which was introduced by moving the blocking wait from script to indexeddb.

gterzian avatar Dec 03 '25 13:12 gterzian

🔨 Triggering try run (#19896250328) for Linux (WPT)

github-actions[bot] avatar Dec 03 '25 13:12 github-actions[bot]

Test results for linux-wpt from try job (#19896250328):

Flaky unexpected result (36)
  • OK /FileAPI/url/url-with-fetch.any.html (#21517)
    • FAIL [expected PASS] subtest: Revoke blob URL after calling fetch, fetch should succeed
      promise_test: Unhandled rejection with value: object "TypeError: Network error occurred"
      

  • PASS [expected FAIL] /_mozilla/css/linear_gradients_reverse_a.html
  • OK /_mozilla/css/offset_properties_inline.html (#40543)
    • FAIL [expected PASS] subtest: offsetTop
      assert_equals: offsetTop of #inline-1 should be 0. expected 0 but got -1
      

    • FAIL [expected PASS] subtest: offsetLeft
      assert_equals: offsetLeft of #inline-2 should be 40. expected 40 but got 25
      

  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session
      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • OK /_mozilla/webxr/obtain_frame.https.html
    • FAIL [expected PASS] subtest: obtain_frame
      promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
      

  • CRASH [expected OK] /_webgl/conformance2/wasm/readpixels-2gb-in-4gb-wasm-memory.html
  • OK /content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html (#36468)
    • FAIL [expected PASS] subtest: A 'frame-ancestors' CSP directive with a URL that includes a path should be ignored.
      assert_unreached: The IFrame should have been blocked (or cross-origin). It wasn't. Reached unreachable code
      

  • OK /css/CSS2/linebox/vertical-align-top-bottom-001.html (#41015)
    • FAIL [expected PASS] subtest: text-top+
      assert_approx_equals: expected "44" +/- 0 but got 41
      

    • FAIL [expected PASS] subtest: text-top+top
      assert_approx_equals: expected "5" +/- 0 but got 3
      

    • FAIL [expected PASS] subtest: text-top+text-top
      assert_approx_equals: expected "5" +/- 0 but got 3
      

    • FAIL [expected PASS] subtest: text-top+text-bottom
      assert_approx_equals: expected "40" +/- 0 but got 37
      

    • FAIL [expected PASS] subtest: text-bottom+
      assert_approx_equals: expected "44" +/- 0 but got 45
      

    • FAIL [expected PASS] subtest: text-bottom+top
      assert_approx_equals: expected "5" +/- 0 but got 7
      

    • FAIL [expected PASS] subtest: text-bottom+text-top
      assert_approx_equals: expected "5" +/- 0 but got 7
      

    • FAIL [expected PASS] subtest: bottom+
      assert_approx_equals: expected "49" +/- 0 but got 48
      

    • FAIL [expected PASS] subtest: bottom+text-top
      assert_approx_equals: expected "45" +/- 0 but got 43
      

    • FAIL [expected PASS] subtest: bottom+text-bottom
      assert_approx_equals: expected "45" +/- 0 but got 44
      

  • FAIL [expected PASS] /css/css-backgrounds/background-size-042.html
  • OK /css/css-cascade/layer-font-face-override.html (#35935)
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 1
    • PASS [expected FAIL] subtest: @font-face override update with appended sheet 2
  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: setFormValue with an empty FormData should submit nothing
  • OK /html/browsers/browsing-the-web/navigating-across-documents/008.html (#24456)
    • PASS [expected FAIL] subtest: Link with onclick form submit to javascript url and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-cross-origin.sub.window.html (#29056)
    • PASS [expected FAIL] subtest: Cross-origin navigation started from unload handler must be ignored
  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
    • PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
  • CRASH [expected OK] /html/browsers/browsing-the-web/navigating-across-documents/plugin-document.historical.html
  • CRASH [expected OK] /html/browsers/sandboxing/sandbox-initial-empty-document-toward-same-origin.html (#35948)
  • CRASH [expected OK] /html/browsers/windows/browsing-context-window.html
  • CRASH [expected OK] /html/canvas/element/canvas-host/2d.canvas.host.size.attributes.setAttribute.whitespace.html
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/document-with-fragment-empty.html (#28259)
    • TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with empty fragments should work.
      Test timed out
      

  • OK [expected TIMEOUT] /html/semantics/embedded-content/media-elements/src_object_blob.html (#40340)
    • PASS [expected TIMEOUT] subtest: HTMLMediaElement.srcObject blob
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-replace-set-src.html (#32697)
    • PASS [expected FAIL] subtest: Navigating iframe loading='lazy' and then setting src: location.replace
  • OK /html/semantics/forms/form-submission-0/jsurl-form-submit.tentative.html (#36489)
    • PASS [expected FAIL] subtest: Verifies that form submissions scheduled inside javascript: urls take precedence over the javascript: url's return value.
  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • FAIL [expected PASS] subtest: multipart/form-data: Basic test (formdata event)
      assert_equals: expected "\r\nContent-Disposition: form-data; name=\"basic\"\r\n\r\ntest\r\n--\r\n" but got ""
      

  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • PASS [expected FAIL] subtest: text/plain: 0x00 in filename (formdata event)
  • TIMEOUT [expected ERROR] /html/semantics/links/links-created-by-a-and-area-elements/target_blank_implicit_noopener_base.html (#40347)
  • OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
    • FAIL [expected PASS] subtest: adding several types of scripts through the DOM and removing some of them confuses scheduler
      assert_array_equals: expected property 1 to be "Script #1 ran" but got "Script #3 ran" (expected array ["Script #2 ran", "Script #1 ran", "Script #3 ran", "Script #4 ran"] got ["Script #2 ran", "Script #3 ran", "Script #4 ran", "Script #1 ran"])
      

  • CRASH [expected OK] /pointerevents/compat/pointerevent_touch-action_two-finger_interaction.html (#40418)
  • OK /preload/preload-invalid-resources.html (#39091)
    • PASS [expected FAIL] subtest: Preloading an invalid image (invalid data) should preload and not re-fetch
  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.
      assert_equals: resources/dummy.xml?token=2027a395-13f7-43bc-8a37-dccc644269d2 expected 1 but got 0
      

  • OK /service-workers/service-worker/fetch-event.https.html (#36234)
    • PASS [expected FAIL] subtest: Service Worker falls back to network in fetch event with POST form
  • CRASH [expected OK] /trusted-types/set-event-handlers-content-attributes.tentative.html
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.
      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.
      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • CRASH [expected OK] /trusted-types/trusted-types-reporting-for-Document-execCommand.html
  • CRASH [expected ERROR] /wasm/webapi/invalid-code.any.sharedworker.html
  • OK /webdriver/tests/classic/execute_script/objects.py
    • FAIL [expected PASS] subtest: test_object
      AssertionError: no such window (404): No such window
      

  • CRASH [expected OK] /websockets/Close-1005-verify-code.any.worker.html?wss
Stable unexpected results that are known to be intermittent (37)
  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor
      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor
      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_delete.any.worker.html (#39069)
    • PASS [expected FAIL] subtest: delete() key doesn't match any records
  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • FAIL [expected PASS] subtest: Single item get
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: getAll on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all values
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Test maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range with maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get upper excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get lower excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Non existent key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: zero maxCount
      The object is in an invalid state.
      

    • And 3 more unexpected results...
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • FAIL [expected PASS] subtest: Single item get
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: getAll on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all values
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Test maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range with maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get upper excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get lower excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Non existent key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: zero maxCount
      The object is in an invalid state.
      

    • And 3 more unexpected results...
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)
    • FAIL [expected PASS] subtest: indexedDB.delete called from upgradeneeded handler
      assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
      

    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)
    • FAIL [expected PASS] subtest: indexedDB.delete called from upgradeneeded handler
      assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
      

    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • PASS [expected FAIL] subtest: IndexedDB: Exceptions thrown during key conversion
    • PASS [expected FAIL] subtest: IDBIndex get() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getKey() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex count() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex openCursor() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex openKeyCursor() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAll() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAllKeys() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAllRecords() method with throwing/invalid keys
  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • PASS [expected FAIL] subtest: IndexedDB: Exceptions thrown during key conversion
    • PASS [expected FAIL] subtest: IDBIndex get() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getKey() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex count() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex openCursor() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex openKeyCursor() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAll() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAllKeys() method with throwing/invalid keys
    • PASS [expected FAIL] subtest: IDBIndex getAllRecords() method with throwing/invalid keys
  • OK /IndexedDB/transaction-deactivation-timing.any.html (#38772)
    • FAIL [expected PASS] subtest: New transactions are not deactivated until after the microtask checkpoint
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: New transactions from microtask are still active through the microtask checkpoint
      The object is in an invalid state.
      

  • OK /IndexedDB/transaction-deactivation-timing.any.worker.html (#38808)
    • FAIL [expected PASS] subtest: New transactions are not deactivated until after the microtask checkpoint
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: New transactions from microtask are still active through the microtask checkpoint
      The object is in an invalid state.
      

  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo
      Test timed out
      

  • OK /css/css-cascade/layer-cssom-order-reverse.html (#36094)
    • PASS [expected FAIL] subtest: Delete layer invalidates @font-face
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(fangsong)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(kai)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(nastaliq)
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted generic(nastaliq) (drawing text in a canvas)
  • FAIL [expected PASS] /css/css-grid/grid-lanes/tentative/alignment/row-grid-lanes-align-self-003.html (#40833)
  • FAIL [expected PASS] /css/css-grid/grid-lanes/tentative/grid-placement/row-explicit-placement-004.html (#40834)
  • FAIL [expected PASS] /css/css-grid/masonry/tentative/subgrid/column/masonry-subgrid-002f.html (#40830)
  • TIMEOUT [expected OK] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • TIMEOUT [expected PASS] subtest: [keepalive][iframe][load] mixed content redirect; setting up
      Test timed out
      

  • OK /fetch/fetch-later/permissions-policy/deferred-fetch-allowed-by-permissions-policy.https.window.html (#40478)
    • PASS [expected FAIL] subtest: Permissions policy header: "deferred-fetch=*" allows fetchLater() in the top-level document.
  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Cross-site
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-origin destination
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Cross-site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -> Same Origin, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - no attributes
    • FAIL [expected PASS] subtest: sec-fetch-mode - attributes: crossorigin
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-mode - attributes: crossorigin=anonymous
    • FAIL [expected PASS] subtest: sec-fetch-mode - attributes: crossorigin=use-credentials
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-dest - no attributes
  • OK /fetch/metadata/generated/element-img-environment-change.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-user - Not sent to non-trustworthy cross-site destination, no attributes
  • OK [expected CRASH] /fetch/metadata/window-open.https.sub.html (#40339)
    • PASS [expected TIMEOUT] subtest: Same-origin window, user-activated
    • PASS [expected TIMEOUT] subtest: Same-site window, user-activated
    • PASS [expected TIMEOUT] subtest: Cross-site window, user-activated
    • FAIL [expected PASS] subtest: Same-site window, user-activated: sec-fetch-site
      assert_equals: expected "same-site" but got "same-origin"
      

    • FAIL [expected PASS] subtest: Cross-site window, user-activated: sec-fetch-site
      assert_equals: expected "cross-site" but got "same-origin"
      

  • TIMEOUT [expected CRASH] /html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK [expected ERROR] /html/infrastructure/common-dom-interfaces/collections/domstringlist.html (#40665)
  • OK [expected TIMEOUT] /html/interaction/focus/the-autofocus-attribute/autofocus-dialog.html (#29087)
    • FAIL [expected TIMEOUT] subtest: <dialog>-contained autofocus element gets focused when the dialog is shown
      assert_equals: expected "DIV" but got "BODY"
      

  • TIMEOUT /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • FAIL [expected TIMEOUT] subtest: Element with tabindex should support autofocus
      assert_equals: expected "SPAN" but got "BODY"
      

    • TIMEOUT [expected NOTRUN] subtest: Non-HTMLElement should not support autofocus
      Test timed out
      

  • OK /html/semantics/embedded-content/media-elements/preserves-pitch.html (#40352)
    • FAIL [expected PASS] subtest: The default playbackRate should not affect pitch, even with preservesPitch=false
      assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
      

    • FAIL [expected PASS] subtest: Speed-ups should not change the pitch when preservesPitch=true
      assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
      

    • FAIL [expected PASS] subtest: Slow-downs should not change the pitch when preservesPitch=true
      assert_approx_equals: The actual pitch should be close to the expected pitch. expected 440 +/- 66 but got 0
      

  • OK [expected CRASH] /html/semantics/forms/the-fieldset-element/disabled-003.html (#31730, #39631)
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete > Original domComplete
    • FAIL [expected PASS] subtest: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd
      assert_true: Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd expected true got false
      

    • PASS [expected FAIL] subtest: Reload loadEventEnd > Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart > Original loadEventStart
  • OK /preload/preload-error.sub.html (#37177)
    • FAIL [expected PASS] subtest: success (fetch): main
      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?label=fetch should be loaded expected a number greater than 0 but got 0
      

    • FAIL [expected PASS] subtest: 404 (fetch): main
      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?pipe=status%28404%29&label=fetch should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: CORS (fetch): main
  • OK [expected ERROR] /resource-timing/cors-preflight.any.html (#28694)
  • TIMEOUT [expected OK] /trusted-types/trusted-types-navigation.html?26-30 (#38807)
    • TIMEOUT [expected FAIL] subtest: Navigate a window via form-submission with javascript:-urls in report-only mode.
      Test timed out
      

    • NOTRUN [expected PASS] subtest: Navigate a window via form-submission with javascript:-urls w/ default policy in report-only mode.
    • NOTRUN [expected FAIL] subtest: Navigate a frame via form-submission with javascript:-urls in enforcing mode.
    • NOTRUN [expected PASS] subtest: Navigate a frame via form-submission with javascript:-urls w/ default policy in enforcing mode.
Stable unexpected results (94)
  • TIMEOUT [expected OK] /IndexedDB/back-forward-cache-open-transaction.window.html
    • TIMEOUT [expected PASS] subtest: BFCache support test for page with open IndexedDB transaction
      Test timed out
      

  • OK /IndexedDB/blob-composite-blob-reads.any.html
    • FAIL [expected PASS] subtest: Composite Blob Handling: Many blobs: fetch-blob-url
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Composite Blob Handling: Many blobs: direct
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/blob-composite-blob-reads.any.worker.html
    • FAIL [expected PASS] subtest: Composite Blob Handling: Many blobs: fetch-blob-url
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Composite Blob Handling: Many blobs: direct
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/blob-contenttype.any.html
    • FAIL [expected PASS] subtest: Ensure that content type round trips when reading blob data
      The object is in an invalid state.
      

  • OK /IndexedDB/blob-contenttype.any.worker.html
    • FAIL [expected PASS] subtest: Ensure that content type round trips when reading blob data
      The object is in an invalid state.
      

  • OK [expected TIMEOUT] /IndexedDB/blob-valid-after-abort.any.html
    • FAIL [expected TIMEOUT] subtest: A blob can be read back after the transaction that added it was aborted.
      The object is in an invalid state.
      

  • OK [expected TIMEOUT] /IndexedDB/blob-valid-after-abort.any.worker.html
    • FAIL [expected TIMEOUT] subtest: A blob can be read back after the transaction that added it was aborted.
      The object is in an invalid state.
      

  • OK /IndexedDB/blob-valid-after-deletion.any.html
    • FAIL [expected PASS] subtest: Blobs stay alive after their records are deleted.
      The object is in an invalid state.
      

  • OK /IndexedDB/blob-valid-after-deletion.any.worker.html
    • FAIL [expected PASS] subtest: Blobs stay alive after their records are deleted.
      The object is in an invalid state.
      

  • OK /IndexedDB/blob-valid-before-commit.any.html
    • FAIL [expected PASS] subtest: Blobs can be read back before their records are committed.
      The object is in an invalid state.
      

  • OK /IndexedDB/blob-valid-before-commit.any.worker.html
    • FAIL [expected PASS] subtest: Blobs can be read back before their records are committed.
      The object is in an invalid state.
      

  • TIMEOUT [expected OK] /IndexedDB/crashtests/create-index.any.html
    • TIMEOUT [expected FAIL] subtest: Assure no crash when populating index
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/crashtests/create-index.any.worker.html
    • TIMEOUT [expected FAIL] subtest: Assure no crash when populating index
      Test timed out
      

  • OK [expected TIMEOUT] /IndexedDB/database-names-by-origin.html
    • FAIL [expected TIMEOUT] subtest: open database names don't leak to cross-origin iframe
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected NOTRUN] subtest: open database names don't leak to cross-origin window
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected NOTRUN] subtest: closed database names don't leak to cross-origin iframe
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected NOTRUN] subtest: closed database names don't leak to cross-origin window
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/event-dispatch-active-flag.any.html
    • FAIL [expected PASS] subtest: Active during success handlers
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during success listeners
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during error handlers
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during error listeners
      The object is in an invalid state.
      

  • OK /IndexedDB/event-dispatch-active-flag.any.worker.html
    • FAIL [expected PASS] subtest: Active during success handlers
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during success listeners
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during error handlers
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Active during error listeners
      The object is in an invalid state.
      

  • OK /IndexedDB/idb-explicit-commit.any.html
    • FAIL [expected PASS] subtest: commit() on a version change transaction does not cause errors.
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/idb-explicit-commit.any.worker.html
    • FAIL [expected PASS] subtest: commit() on a version change transaction does not cause errors.
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK [expected CRASH] /IndexedDB/idb-partitioned-coverage.sub.html
    • FAIL [expected PASS] subtest: Deletes are processed in order
      saw is not a function
      

  • OK /IndexedDB/idb-partitioned-persistence.sub.html
    • FAIL [expected PASS] subtest: Persistence test for partitioned IndexedDB
      assert_true: The same database should exist in both frames expected true got false
      

  • ERROR [expected OK] /IndexedDB/idb_webworkers.htm
    • TIMEOUT [expected PASS] subtest: IndexedDB inside of a WebWorker
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbcursor-advance-exception-order.any.html
    • FAIL [expected PASS] subtest: IDBCursor.advance exception order: TypeError vs. TransactionInactiveError
      The object is in an invalid state.
      

    • TIMEOUT [expected FAIL] subtest: IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbcursor-advance-exception-order.any.worker.html
    • FAIL [expected PASS] subtest: IDBCursor.advance exception order: TypeError vs. TransactionInactiveError
      The object is in an invalid state.
      

    • TIMEOUT [expected FAIL] subtest: IDBCursor.advance exception order: TransactionInactiveError vs. InvalidStateError #1
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbcursor-continuePrimaryKey-exception-order.any.html
    • TIMEOUT [expected FAIL] subtest: TransactionInactiveError v.s. InvalidStateError(deleted index)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect source)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect direction)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration complete)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration ongoing)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration ongoing)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration complete)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(iteration ongoing) v.s. DataError(unset key)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(iteration complete) v.s. DataError(unset key)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: DataError(unset key)
      Test timed out
      

    • And 3 more unexpected results...
  • TIMEOUT [expected OK] /IndexedDB/idbcursor-continuePrimaryKey-exception-order.any.worker.html
    • TIMEOUT [expected FAIL] subtest: TransactionInactiveError v.s. InvalidStateError(deleted index)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect source)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(deleted source) v.s. InvalidAccessError(incorrect direction)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration complete)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect direction) v.s. InvalidStateError(iteration ongoing)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration ongoing)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidAccessError(incorrect source) v.s. InvalidStateError(iteration complete)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(iteration ongoing) v.s. DataError(unset key)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: InvalidStateError(iteration complete) v.s. DataError(unset key)
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: DataError(unset key)
      Test timed out
      

    • And 3 more unexpected results...
  • TIMEOUT [expected OK] /IndexedDB/idbdatabase-createObjectStore-exception-order.any.html
    • TIMEOUT [expected PASS] subtest: IDBDatabase.createObjectStore exception order: SyntaxError vs. ConstraintError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBDatabase.createObjectStore exception order: ConstraintError vs. InvalidAccessError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbdatabase-createObjectStore-exception-order.any.worker.html
    • TIMEOUT [expected PASS] subtest: IDBDatabase.createObjectStore exception order: SyntaxError vs. ConstraintError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBDatabase.createObjectStore exception order: ConstraintError vs. InvalidAccessError
      Test timed out
      

  • OK /IndexedDB/idbdatabase_createObjectStore.any.html
    • PASS [expected FAIL] subtest: Attempt to create an object store outside of a version change transaction
    • FAIL [expected PASS] subtest: Object store's name appears in database's list
      assert_true: objectStoreNames.contains (in success) expected true got false
      

  • OK /IndexedDB/idbdatabase_createObjectStore.any.worker.html
    • PASS [expected FAIL] subtest: Attempt to create an object store outside of a version change transaction
    • FAIL [expected PASS] subtest: Object store's name appears in database's list
      assert_true: objectStoreNames.contains (in success) expected true got false
      

  • TIMEOUT [expected OK] /IndexedDB/idbfactory-open-error-properties.any.html
    • TIMEOUT [expected FAIL] subtest: Properties of error event from failed open()
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbfactory-open-error-properties.any.worker.html
    • TIMEOUT [expected FAIL] subtest: Properties of error event from failed open()
      Test timed out
      

  • OK /IndexedDB/idbfactory-open-request-success.any.html
    • FAIL [expected PASS] subtest: Properties of IDBOpenDBRequest during successful IDBFactory open()
      assert_true: complete event should fire before success expected true got false
      

  • OK /IndexedDB/idbfactory-open-request-success.any.worker.html
    • FAIL [expected PASS] subtest: Properties of IDBOpenDBRequest during successful IDBFactory open()
      assert_true: complete event should fire before success expected true got false
      

  • TIMEOUT [expected OK] /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: IDBFactory.open() - database 'name' and 'version' are correctly set
      assert_equals: db.version expected 13 but got 1
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - no version opens current database
      assert_unreached: Unexpected upgradeneeded Reached unreachable code
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - open database with a lower version than current
      assert_unreached: Unexpected success Reached unreachable code
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - open database with a higher version than current
      assert_true: did upgrade expected true got false
      

    • FAIL [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.
      assert_unreached: open should fail Reached unreachable code
      

    • TIMEOUT [expected FAIL] subtest: Calling open() with version argument undefined should not throw.
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbfactory_open.any.worker.html
    • FAIL [expected PASS] subtest: IDBFactory.open() - database 'name' and 'version' are correctly set
      assert_equals: db.version expected 13 but got 1
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - no version opens current database
      assert_unreached: Unexpected upgradeneeded Reached unreachable code
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - open database with a lower version than current
      assert_unreached: Unexpected success Reached unreachable code
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - open database with a higher version than current
      assert_true: did upgrade expected true got false
      

    • TIMEOUT [expected FAIL] subtest: Calling open() with version argument undefined should not throw.
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbindex-query-exception-order.any.html
    • TIMEOUT [expected FAIL] subtest: IDBIndex.get exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.getAll exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.count exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.openCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbindex-query-exception-order.any.worker.html
    • TIMEOUT [expected FAIL] subtest: IDBIndex.get exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.getAll exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.count exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.openCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBIndex.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-add-put-exception-order.any.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.put exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.put exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                    store[method]({}, 'value');
                  }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.add exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.add exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                    store[method]({}, 'value');
                  }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-add-put-exception-order.any.worker.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.put exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.put exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                    store[method]({}, 'value');
                  }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.add exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.add exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                    store[method]({}, 'value');
                  }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-clear-exception-order.any.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.clear exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-clear-exception-order.any.worker.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.clear exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-delete-exception-order.any.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.delete exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.delete exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                  store.delete({});
                }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-delete-exception-order.any.worker.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.delete exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBObjectStore.delete exception order: ReadOnlyError vs. DataError
      assert_throws_dom: "read only" check (ReadOnlyError) should precede key/data check (DataError) function "() => {
                  store.delete({});
                }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException ReadOnlyError: property "code" is equal to 11, expected 0
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-deleteIndex-exception-order.any.html
    • TIMEOUT [expected FAIL] subtest: IDBObjectStore.deleteIndex exception order: InvalidStateError #2 vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBObjectStore.deleteIndex exception order: TransactionInactiveError vs. NotFoundError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-deleteIndex-exception-order.any.worker.html
    • TIMEOUT [expected FAIL] subtest: IDBObjectStore.deleteIndex exception order: InvalidStateError #2 vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: IDBObjectStore.deleteIndex exception order: TransactionInactiveError vs. NotFoundError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-query-exception-order.any.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.get exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.getAll exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.count exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • TIMEOUT [expected OK] /IndexedDB/idbobjectstore-query-exception-order.any.worker.html
    • TIMEOUT [expected PASS] subtest: IDBObjectStore.get exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.getAll exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.getAllKeys exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.count exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.openCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

    • TIMEOUT [expected PASS] subtest: IDBObjectStore.openKeyCursor exception order: InvalidStateError vs. TransactionInactiveError
      Test timed out
      

  • OK /IndexedDB/idbobjectstore-request-source.any.html
    • FAIL [expected PASS] subtest: The source of the request from store => store.put(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.add(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.delete(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.clear() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.get(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getKey(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getAll() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getAllKeys() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.count() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.openCursor() is the object store itself
      The object is in an invalid state.
      

    • And 1 more unexpected results...
  • OK /IndexedDB/idbobjectstore-request-source.any.worker.html
    • FAIL [expected PASS] subtest: The source of the request from store => store.put(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.add(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.delete(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.clear() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.get(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getKey(0) is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getAll() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.getAllKeys() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.count() is the object store itself
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: The source of the request from store => store.openCursor() is the object store itself
      The object is in an invalid state.
      

    • And 1 more unexpected results...
  • TIMEOUT /IndexedDB/idbobjectstore_createIndex.any.html
    • TIMEOUT [expected FAIL] subtest: TransactionInactiveError vs. ConstraintError. Transaction-state check should precede index name check.
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: ConstraintError vs. SyntaxError. Index name check should precede syntax check of the key path
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: SyntaxError vs. InvalidAccessError. Syntax check should precede multiEntry check of the key path.
      Test timed out
      

  • TIMEOUT [expected ERROR] /IndexedDB/idbobjectstore_createIndex.any.worker.html
    • TIMEOUT [expected FAIL] subtest: TransactionInactiveError vs. ConstraintError. Transaction-state check should precede index name check.
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: ConstraintError vs. SyntaxError. Index name check should precede syntax check of the key path
      Test timed out
      

    • TIMEOUT [expected FAIL] subtest: SyntaxError vs. InvalidAccessError. Syntax check should precede multiEntry check of the key path.
      Test timed out
      

  • OK /IndexedDB/idbobjectstore_delete.any.html
    • PASS [expected FAIL] subtest: delete() key doesn't match any records
  • OK /IndexedDB/idbobjectstore_get.any.worker.html
    • PASS [expected FAIL] subtest: Attempts to retrieve a record that doesn't exist
  • OK /IndexedDB/idbobjectstore_getAll-options.any.html
    • FAIL [expected PASS] subtest: Get all values with invalid query keys
      assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
              queryTarget[getAllFunctionName](argument);
            }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
      

  • OK /IndexedDB/idbobjectstore_getAll-options.any.worker.html
    • FAIL [expected PASS] subtest: Get all values with invalid query keys
      assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
              queryTarget[getAllFunctionName](argument);
            }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
      

  • OK /IndexedDB/idbobjectstore_getAllKeys-options.any.html
    • FAIL [expected PASS] subtest: getAllKeys on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys with invalid query keys
      assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
              queryTarget[getAllFunctionName](argument);
            }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
      

  • OK /IndexedDB/idbobjectstore_getAllKeys-options.any.worker.html
    • FAIL [expected PASS] subtest: getAllKeys on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys with invalid query keys
      assert_throws_dom: An invalid Date(NaN) key must throw an exception. function "() => {
              queryTarget[getAllFunctionName](argument);
            }" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataError: property "code" is equal to 11, expected 0
      

  • OK /IndexedDB/idbobjectstore_getAllKeys.any.html
    • FAIL [expected PASS] subtest: Single item get
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Single item get (generated key)
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: getAllKeys on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Test maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range with maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get upper excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get lower excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range (generated) with maxCount
      The object is in an invalid state.
      

    • And 5 more unexpected results...
  • OK /IndexedDB/idbobjectstore_getAllKeys.any.worker.html
    • FAIL [expected PASS] subtest: Single item get
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Single item get (generated key)
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: getAllKeys on empty object store
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get all keys
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Test maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range with maxCount
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get upper excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get lower excluded
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Get bound range (generated) with maxCount
      The object is in an invalid state.
      

    • And 5 more unexpected results...
  • OK /IndexedDB/idbobjectstore_getKey.any.html
    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - key - no match
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - key - no match
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator and key path - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator and key path - range
      The object is in an invalid state.
      

  • OK /IndexedDB/idbobjectstore_getKey.any.worker.html
    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - basic - key - no match
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key path - key - no match
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator - range
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator and key path - key
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: IDBObjectStore.getKey() - key generator and key path - range
      The object is in an invalid state.
      

  • OK [expected CRASH] /IndexedDB/idbobjectstore_openKeyCursor.any.html
  • OK [expected CRASH] /IndexedDB/idbobjectstore_openKeyCursor.any.worker.html
  • OK /IndexedDB/idbtransaction-oncomplete.any.html
    • PASS [expected FAIL] subtest: IDBTransaction - complete event
  • OK /IndexedDB/idbtransaction-oncomplete.any.worker.html
    • PASS [expected FAIL] subtest: IDBTransaction - complete event
  • OK /IndexedDB/idbtransaction_abort.any.html
    • FAIL [expected PASS] subtest: Abort during auto-committing should throw InvalidStateError.
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Abort on completed transaction should throw InvalidStateError.
      The object is in an invalid state.
      

  • OK /IndexedDB/idbtransaction_abort.any.worker.html
    • FAIL [expected PASS] subtest: Abort during auto-committing should throw InvalidStateError.
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Abort on completed transaction should throw InvalidStateError.
      The object is in an invalid state.
      

  • OK /IndexedDB/idbtransaction_objectStoreNames.any.html
    • PASS [expected FAIL] subtest: IDBTransaction.objectStoreNames - during upgrade transaction
    • FAIL [expected PASS] subtest: IDBTransaction.objectStoreNames - value after commit
      The object is in an invalid state.
      

  • OK /IndexedDB/idbtransaction_objectStoreNames.any.worker.html
    • PASS [expected FAIL] subtest: IDBTransaction.objectStoreNames - during upgrade transaction
    • FAIL [expected PASS] subtest: IDBTransaction.objectStoreNames - value after commit
      The object is in an invalid state.
      

  • OK /IndexedDB/keypath-exceptions.any.html
    • PASS [expected FAIL] subtest: Key path evaluation: Exceptions from non-enumerable getters
  • OK /IndexedDB/keypath-exceptions.any.worker.html
    • PASS [expected FAIL] subtest: Key path evaluation: Exceptions from non-enumerable getters
  • OK /IndexedDB/keypath-special-identifiers.any.html
    • FAIL [expected PASS] subtest: Type: String, identifier: length
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Array, identifier: length
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Blob, identifier: size
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Blob, identifier: type
      The object is in an invalid state.
      

  • OK /IndexedDB/keypath-special-identifiers.any.worker.html
    • FAIL [expected PASS] subtest: Type: String, identifier: length
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Array, identifier: length
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Blob, identifier: size
      The object is in an invalid state.
      

    • FAIL [expected PASS] subtest: Type: Blob, identifier: type
      The object is in an invalid state.
      

  • OK /IndexedDB/nested-cloning-basic.any.html
    • FAIL [expected PASS] subtest: small typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: blob
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/nested-cloning-basic.any.worker.html
    • FAIL [expected PASS] subtest: small typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: blob
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/nested-cloning-large.any.html
    • FAIL [expected PASS] subtest: blob with large typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: array of blobs and large typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: object with blobs and large typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/nested-cloning-large.any.worker.html
    • FAIL [expected PASS] subtest: blob with large typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: array of blobs and large typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: object with blobs and large typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/nested-cloning-small.any.html
    • FAIL [expected PASS] subtest: blob with small typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: blob array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: array of blobs and small typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/nested-cloning-small.any.worker.html
    • FAIL [expected PASS] subtest: blob with small typed array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: blob array
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: array of blobs and small typed arrays
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • TIMEOUT [expected CRASH] /IndexedDB/open-request-queue.any.html
    • TIMEOUT [expected PASS] subtest: IndexedDB: open and delete requests are processed as a FIFO queue
      Test timed out
      

  • TIMEOUT [expected CRASH] /IndexedDB/open-request-queue.any.worker.html
    • TIMEOUT [expected PASS] subtest: IndexedDB: open and delete requests are processed as a FIFO queue
      Test timed out
      

  • OK /IndexedDB/structured-clone.any.html?101-last
    • FAIL [expected PASS] subtest: Not serializable: function: function() {}
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: symbol: Symbol(desc)
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: Window: [object Window]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: Event: [object Event]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: MessageChannel: [object MessageChannel]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /IndexedDB/structured-clone.any.worker.html?101-last
    • FAIL [expected PASS] subtest: Not serializable: function: function() {}
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: symbol: Symbol(desc)
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: DedicatedWorkerGlobalScope: [object DedicatedWorkerGlobalScope]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: Event: [object Event]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

    • FAIL [expected PASS] subtest: Not serializable: MessageChannel: [object MessageChannel]
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK [expected TIMEOUT] /IndexedDB/transaction-lifetime-empty.any.html
    • FAIL [expected TIMEOUT] subtest: Transactions without requests complete in the expected order
      The object is in an invalid state.
      

    • FAIL [expected TIMEOUT] subtest: Multiple transactions without requests complete in the expected order
      The object is in an invalid state.
      

  • OK [expected TIMEOUT] /IndexedDB/transaction-lifetime-empty.any.worker.html
    • FAIL [expected TIMEOUT] subtest: Transactions without requests complete in the expected order
      The object is in an invalid state.
      

    • FAIL [expected TIMEOUT] subtest: Multiple transactions without requests complete in the expected order
      The object is in an invalid state.
      

  • OK [expected TIMEOUT] /IndexedDB/transaction-lifetime.any.html
    • FAIL [expected TIMEOUT] subtest: No Blocked event
      assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
      

    • FAIL [expected NOTRUN] subtest: Blocked event
      assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
      

  • OK [expected TIMEOUT] /IndexedDB/transaction-lifetime.any.worker.html
    • FAIL [expected TIMEOUT] subtest: No Blocked event
      assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
      

    • FAIL [expected NOTRUN] subtest: Blocked event
      assert_equals: Expected upgradeneeded event, but got success event instead expected "upgradeneeded" but got "success"
      

  • OK /IndexedDB/transaction-scheduling-within-database.any.html
    • FAIL [expected PASS] subtest: Check that read-only transactions within a database can run in parallel.
      The object is in an invalid state.
      

  • OK /IndexedDB/transaction-scheduling-within-database.any.worker.html
    • FAIL [expected PASS] subtest: Check that read-only transactions within a database can run in parallel.
      The object is in an invalid state.
      

  • OK /IndexedDB/upgrade-transaction-deactivation-timing.any.html
    • PASS [expected FAIL] subtest: Upgrade transactions are active in upgradeneeded callback
    • PASS [expected FAIL] subtest: Upgrade transactions are active in upgradeneeded callback and microtasks
    • PASS [expected FAIL] subtest: Upgrade transactions are deactivated before next task
  • OK /IndexedDB/upgrade-transaction-deactivation-timing.any.worker.html
    • PASS [expected FAIL] subtest: Upgrade transactions are active in upgradeneeded callback
    • PASS [expected FAIL] subtest: Upgrade transactions are active in upgradeneeded callback and microtasks
    • PASS [expected FAIL] subtest: Upgrade transactions are deactivated before next task
  • OK /IndexedDB/worker-termination-aborts-upgrade.window.html
    • FAIL [expected PASS] subtest: Worker Termination Aborts a Pending Upgrade
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

  • OK /wasm/webapi/historical.any.html
    • FAIL [expected PASS] subtest: historical
      assert_throws_dom: function "() => store.put(mod, module_key)" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataCloneError: property "code" is equal to 11, expected 25
      

  • OK /wasm/webapi/historical.any.worker.html
    • FAIL [expected PASS] subtest: historical
      assert_throws_dom: function "() => store.put(mod, module_key)" threw object "InvalidStateError: The object is in an invalid state." that is not a DOMException DataCloneError: property "code" is equal to 11, expected 25
      

github-actions[bot] avatar Dec 03 '25 14:12 github-actions[bot]

⚠️ Try run (#19896250328) failed.

github-actions[bot] avatar Dec 03 '25 14:12 github-actions[bot]

Ok so the problem is that the new async worflow creates two database, one during upgrade, one when it finishes, and so any object stores created during upgrade are not found on the second one. Previously this wasn't an issue because the entire worflow was one atomic step(blocking script), so only one db was created.

Solution: store the DB that is created in the first async step and use it later. Highlights the need to have a script-side persistent and stateful IPC message handler(now the OpenRequestListener, but could just be one struct per global keeping track of everything). Useful besides just saving on IPC routes.

EDIT: actually it's not the IPC handler that should be stateful, since it cannot manipulate script objects: what is needed is state per global; I'm guessing the IDBFactory will do.

gterzian avatar Dec 04 '25 11:12 gterzian

Solution: store the DB that is created in the first async step and use it later. Highlights the need to have a script-side persistent and stateful IPC message handler(now the OpenRequestListener, but could just be one struct per global keeping track of everything). Useful besides just saving on IPC routes.

Is that something like a persistent back channel from the backend to the script/global (and the script would add a route for it)? That would actually align with my plans. :) The only difference is that I’d like to maintain state across multiple structs and also support more message types.

janvarga avatar Dec 04 '25 11:12 janvarga

Is that something like

Yes something like that, as in we don't need one callback per operation, like is now done at

https://github.com/servo/servo/blob/1aab8186b7c984a80f23e65dd31bb70b4f632cc0/components/script/dom/indexeddb/idbrequest.rs#L412

The only difference is that I’d like to maintain state across multiple structs and also support more message types.

You can use whatever data structure you need, but the "root" of it needs to be stored somewhere accessible from code on the script-thread; for example the idb factory is available via global.IndexedDB().

Note that there is a difference between "one IPC route/callback for all indexeddb stuff per global", and "stateful data used in script", because the route/callback handler is a struct on the IPC router thread, and all it can do is queue a task back on the script-thread to run some logic. And running that logic, if stateful, requires some other data(usually dom objects).

So in this PR, what I will do is the following:

  • Use OpenRequestListener as a callback for all the stuff related to opening/upgrading a db. That means I use it as a kind of persistent callback, in the sense that in the case of an upgrade it will handle first the upgrade message, and later the final upgraded connection.
  • I will then store some state on IDBFactory, because I need it in the case of an upgrade to since that is now an async workflow involving multiple messages. The state is the Db that is being upgraded, so I'll just add a map of IDBDatabase on the factory.

But this can be applied to all async operations using a single IPC channel/route. Those can still contain nested data and messages. So you can have multiple types of structs and messages, but if you want to use only a single IPC route you need to nest those within one global data and one global message structure.

gterzian avatar Dec 04 '25 12:12 gterzian

Thanks for detailed explanation!

janvarga avatar Dec 04 '25 13:12 janvarga

I've applied the transformation mentioned above, and it fixes at least one test(which I think is representative) from the list of failures in the last run, so let's see what it does now.

gterzian avatar Dec 05 '25 13:12 gterzian

🔨 Triggering try run (#19964127059) for Linux (WPT)

github-actions[bot] avatar Dec 05 '25 13:12 github-actions[bot]

⚠️ Try run (#19964127059) failed.

github-actions[bot] avatar Dec 05 '25 13:12 github-actions[bot]

🔨 Triggering try run (#19970159612) for Linux (WPT)

github-actions[bot] avatar Dec 05 '25 17:12 github-actions[bot]

Test results for linux-wpt from try job (#19970159612):

Flaky unexpected result (36)
  • OK /IndexedDB/idbobjectstore_count.any.html
    • PASS [expected FAIL] subtest: Returns the number of records that have keys with the key
  • OK /IndexedDB/transaction-deactivation-timing.any.worker.html (#38808)
    • PASS [expected FAIL] subtest: New transactions are deactivated before next task
  • PASS [expected FAIL] /_mozilla/css/linear_gradients_reverse_a.html
  • CRASH [expected PASS] /_mozilla/shadow-dom/move-element-with-ua-shadow-tree-crash.html (#39473)
  • OK /_mozilla/webxr/create_session.https.html
    • FAIL [expected PASS] subtest: create_session
      can't access property "simulateDeviceConnection", navigator.xr.test is undefined
      

  • OK /_mozilla/webxr/obtain_frame.https.html
    • FAIL [expected PASS] subtest: obtain_frame
      promise_test: Unhandled rejection with value: object "TypeError: can't access property "simulateDeviceConnection", navigator.xr.test is undefined"
      

  • ERROR [expected TIMEOUT] /_mozilla/webxr/sessionavailable.https.html
  • CRASH [expected OK] /_webgl/conformance/context/context-hidden-alpha.html
  • CRASH [expected OK] /_webgl/conformance2/canvas/to-data-url-with-pack-params.html
  • OK /css/css-animations/event-order.tentative.html (#39000)
    • PASS [expected FAIL] subtest: Same events on pseudo-elements follow the prescribed order
  • OK /css/css-fonts/generic-family-keywords-002.html (#40929)
    • PASS [expected FAIL] subtest: font-family: -webkit-serif treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-sans-serif treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-cursive treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-fantasy treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-monospace treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-system-ui treated as <font-family>, not <generic-name>
    • PASS [expected FAIL] subtest: font-family: -webkit-math treated as <font-family>, not <generic-name>
    • FAIL [expected PASS] subtest: font-family: -webkit-generic(fangsong) treated as <font-family>, not <generic-name>
      assert_equals: expected 50 but got 30
      

    • FAIL [expected PASS] subtest: font-family: -webkit-generic(kai) treated as <font-family>, not <generic-name>
      assert_equals: expected 50 but got 30
      

    • FAIL [expected PASS] subtest: font-family: -webkit-generic(khmer-mul) treated as <font-family>, not <generic-name>
      assert_equals: expected 50 but got 30
      

    • And 12 more unexpected results...
  • OK /css/css-fonts/generic-family-keywords-003.html (#38994)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-serif (drawing text in a canvas)
    • PASS [expected FAIL] subtest: @font-face matching for quoted and unquoted ui-rounded (drawing text in a canvas)
  • OK /css/css-fonts/variations/font-weight-matching.html (#38577)
    • FAIL [expected PASS] subtest: Test @font-face matching for weight 400
      assert_approx_equals: @font-face should be mapped to CSSTest Weights 700. expected 90 +/- 2 but got 180
      

    • FAIL [expected PASS] subtest: Test @font-face matching for weight 420
      assert_approx_equals: @font-face should be mapped to CSSTest Weights 600. expected 90 +/- 2 but got 180
      

  • OK /custom-elements/form-associated/ElementInternals-setFormValue.html (#29174)
    • PASS [expected FAIL] subtest: Null value should submit nothing
    • PASS [expected FAIL] subtest: setFormValue with an empty FormData should submit nothing
  • OK [expected TIMEOUT] /fetch/api/redirect/redirect-keepalive.https.any.html (#32153)
    • PASS [expected TIMEOUT] subtest: [keepalive][iframe][load] mixed content redirect; setting up
  • TIMEOUT /fetch/metadata/generated/css-images.sub.tentative.html (#29047)
    • TIMEOUT [expected PASS] subtest: background-image sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
      Test timed out
      

  • ERROR [expected OK] /focus/focus-event-after-switching-iframes.sub.html (#40368)
  • OK /html/browsers/browsing-the-web/navigating-across-documents/005.html (#27062)
    • PASS [expected FAIL] subtest: Link with onclick navigation and href navigation
  • OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html (#28681)
    • FAIL [expected PASS] subtest: load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank'
      assert_unreached: load should not be fired Reached unreachable code
      

  • OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html (#20768)
    • PASS [expected FAIL] subtest: Tests that a fragment navigation in the unload handler will not block the initial navigation
  • OK /html/browsers/history/the-history-interface/traverse_the_history_5.html (#21383)
    • FAIL [expected PASS] subtest: Multiple history traversals, last would be aborted
      assert_array_equals: Pages opened during history navigation expected property 1 to be 5 but got 3 (expected array [6, 5] got [6, 3])
      

  • OK /html/browsers/windows/browsing-context-names/duplicate-name-order.html (#34623)
    • PASS [expected FAIL] subtest: Duplicate name lookup order
  • CRASH [expected OK] /html/canvas/element/drawing-images-to-the-canvas/2d.drawImage.transform.html
  • OK /html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/allow-scripts-flag-changing-1.html (#39694)
    • PASS [expected FAIL] subtest: Meta refresh is blocked by the allow-scripts sandbox flag at its creation time, not when refresh comes due
  • CRASH [expected OK] /html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.cross.html
  • OK /html/semantics/embedded-content/the-iframe-element/iframe-loading-lazy-nav-location-assign.html (#32863)
    • FAIL [expected PASS] subtest: Navigating iframe loading='lazy' before it is loaded: location.assign
      uncaught exception: Error: assert_equals: expected "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?nav" but got "http://web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/support/blank.htm?src"
      

  • OK /html/semantics/forms/form-submission-0/multipart-formdata.window.html (#28725)
    • FAIL [expected PASS] subtest: multipart/form-data: Basic test (formdata event)
      assert_equals: expected "\r\nContent-Disposition: form-data; name=\"basic\"\r\n\r\ntest\r\n--\r\n" but got ""
      

    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in name (formdata event)
    • PASS [expected FAIL] subtest: multipart/form-data: 0x00 in value (normal form)
    • PASS [expected FAIL] subtest: multipart/form-data: \n in value (normal form)
  • OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
    • FAIL [expected PASS] subtest: text/plain: Basic test (formdata event)
      assert_equals: expected "basic=test\r\n" but got ""
      

    • FAIL [expected PASS] subtest: text/plain: Basic File test (normal form)
      assert_equals: expected "basic=file-test.txt\r\n" but got ""
      

    • PASS [expected FAIL] subtest: text/plain: backslash in filename (formdata event)
  • OK /preload/preload-xhr.html (#39092)
    • FAIL [expected PASS] subtest: Make an XHR request immediately after creating link rel=preload.
      assert_equals: resources/dummy.xml?token=36e7d92d-ce25-44e2-bff1-8d4076a11950 expected 1 but got 0
      

  • CRASH [expected OK] /preload/subresource-integrity-partial-image.html
  • CRASH [expected OK] /trusted-types/Element-setAttribute-setAttributeNS-sinks.tentative.html
  • CRASH [expected ERROR] /trusted-types/SharedWorker-importScripts.html
  • OK [expected TIMEOUT] /trusted-types/trusted-types-navigation.html?06-10 (#37920)
    • PASS [expected TIMEOUT] subtest: Navigate a frame via anchor with javascript:-urls w/ default policy in report-only mode.
    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in enforcing mode.
      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

    • FAIL [expected NOTRUN] subtest: Navigate a window via anchor with javascript:-urls w/ a default policy throwing an exception in report-only mode.
      promise_test: Unhandled rejection with value: "Unexpected message received: \"No securitypolicyviolation reported!\""
      

  • CRASH [expected ERROR] /wasm/webapi/empty-body.any.serviceworker.html
  • CRASH [expected TIMEOUT] /wasm/webapi/empty-body.any.worker.html
  • CRASH [expected OK] /websockets/unload-a-document/003.html
Stable unexpected results that are known to be intermittent (29)
  • TIMEOUT /FileAPI/url/url-in-tags-revoke.window.html (#19978)
    • TIMEOUT [expected PASS] subtest: Fetching a blob URL immediately before revoking it works in <script> tags.
      Test timed out
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor
      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbcursor-continuePrimaryKey-exceptions.any.worker.html (#39277)
    • FAIL [expected PASS] subtest: IDBCursor continuePrimaryKey() on object store cursor
      assert_throws_dom: continuePrimaryKey() should throw if source is not an index function "function() {
              cursor.continuePrimaryKey(2, 2);
            }" threw object "TypeError: cursor.continuePrimaryKey is not a function" that is not a DOMException InvalidAccessError: property "code" is equal to undefined, expected 15
      

  • OK /IndexedDB/idbobjectstore_delete.any.worker.html (#39069)
    • PASS [expected FAIL] subtest: delete() key doesn't match any records
  • OK /IndexedDB/idbobjectstore_getAll.any.html (#39276)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbobjectstore_getAll.any.worker.html (#39400)
    • PASS [expected FAIL] subtest: Get all values with transaction.commit()
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.html (#38895)
    • FAIL [expected PASS] subtest: indexedDB.delete called from upgradeneeded handler
      assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
      

    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/idbrequest-onupgradeneeded.any.worker.html (#38971)
    • FAIL [expected PASS] subtest: indexedDB.delete called from upgradeneeded handler
      assert_array_equals: lengths differ, expected array ["Upgrade", "Open Success"] length 2, got ["Upgrade"] length 1
      

    • PASS [expected FAIL] subtest: transaction oncomplete ordering relative to open request onsuccess
  • OK /IndexedDB/key-conversion-exceptions.any.html (#39305)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys
      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys
      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • OK /IndexedDB/key-conversion-exceptions.any.worker.html (#39284)
    • FAIL [expected PASS] subtest: IDBCursor continue() method with throwing/invalid keys
      assert_throws_exactly: key conversion with throwing getter should rethrow function "() => {
            receiver[method](key);
          }" threw object "TypeError: receiver[method] is not a function" but we expected it to throw object "getter: throwing from getter"
      

    • FAIL [expected PASS] subtest: IDBCursor update() method with throwing/invalid keys
      assert_throws_exactly: throwing getter should rethrow during clone function "() => {
            cursor.update(value);
          }" threw object "TypeError: cursor.update is not a function" but we expected it to throw object "getter: throwing from getter"
      

  • FAIL [expected PASS] /_mozilla/mozilla/sslfail.html (#10760)
  • TIMEOUT [expected OK] /_mozilla/mozilla/window_resize_event.html (#36741)
    • TIMEOUT [expected PASS] subtest: Popup onresize event fires after resizeTo
      Test timed out
      

  • OK /_webgl/conformance/textures/misc/texture-upload-size.html (#21770)
    • PASS [expected FAIL] subtest: WebGL test #45
    • PASS [expected FAIL] subtest: WebGL test #47
    • PASS [expected FAIL] subtest: WebGL test #49
    • PASS [expected FAIL] subtest: WebGL test #51
    • FAIL [expected PASS] subtest: WebGL test #53
      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #55
      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #57
      assert_true: Texture was smaller than the expected size 2x2 expected true got false
      

    • FAIL [expected PASS] subtest: WebGL test #59
      assert_true: getError expected: INVALID_VALUE. Was NO_ERROR : when calling texSubImage2D with the same texture upload with offset 1, 1 expected true got false
      

    • PASS [expected FAIL] subtest: WebGL test #61
    • PASS [expected FAIL] subtest: WebGL test #63
    • And 10 more unexpected results...
  • OK /css/css-fonts/generic-family-keywords-001.html (#37467)
    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(fangsong)
      assert_equals: quoted generic(fangsong) matches  @font-face rule expected 50 but got 30
      

    • FAIL [expected PASS] subtest: @font-face matching for quoted and unquoted generic(khmer-mul)
      assert_equals: quoted generic(khmer-mul) matches  @font-face rule expected 50 but got 30
      

  • OK /fetch/metadata/generated/css-font-face.https.sub.tentative.html (#32732)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Cross-site
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/generated/css-font-face.sub.tentative.html (#34624)
    • FAIL [expected PASS] subtest: sec-fetch-storage-access - Not sent to non-trustworthy same-site destination
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • CRASH [expected OK] /fetch/metadata/generated/element-iframe.https.sub.html (#40341)
  • OK /fetch/metadata/generated/element-img-environment-change.https.sub.html (#30111)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same-Origin -> Same Origin, no attributes
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Origin -> Cross-Site, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-site - Same-Site -> Same Origin, no attributes
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-site - Same-Site -> Same-Site, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - no attributes
    • PASS [expected FAIL] subtest: sec-fetch-dest - no attributes
  • OK /fetch/metadata/generated/element-img-environment-change.sub.html (#30111)
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy same-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-site - Not sent to non-trustworthy cross-site destination, no attributes
    • FAIL [expected PASS] subtest: sec-fetch-mode - Not sent to non-trustworthy same-origin destination, no attributes
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

    • PASS [expected FAIL] subtest: sec-fetch-mode - Not sent to non-trustworthy same-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-mode - Not sent to non-trustworthy cross-site destination, no attributes
    • PASS [expected FAIL] subtest: sec-fetch-dest - Not sent to non-trustworthy cross-site destination, no attributes
  • ERROR /fetch/metadata/generated/serviceworker.https.sub.html (#36247)
    • FAIL [expected PASS] subtest: sec-fetch-site - Same origin, no options - registration
      promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
      

  • OK /fetch/metadata/window-open.https.sub.html (#40339)
    • FAIL [expected PASS] subtest: Same-site window, forced, reloaded
      The operation is insecure.
      

  • TIMEOUT [expected CRASH] /html/anonymous-iframe/indexeddb.tentative.https.window.html (#39254)
  • OK /html/browsers/history/the-history-interface/traverse_the_history_4.html (#21383)
    • PASS [expected FAIL] subtest: Multiple history traversals, last would be aborted
  • OK [expected ERROR] /html/infrastructure/common-dom-interfaces/collections/domstringlist.html (#40665)
  • TIMEOUT [expected OK] /html/interaction/focus/the-autofocus-attribute/supported-elements.html (#24145)
    • TIMEOUT [expected FAIL] subtest: Element with tabindex should support autofocus
      Test timed out
      

    • NOTRUN [expected FAIL] subtest: Host element with delegatesFocus should support autofocus
    • NOTRUN [expected FAIL] subtest: Host element with delegatesFocus including no focusable descendants should be skipped
    • NOTRUN [expected FAIL] subtest: Area element should support autofocus
  • OK /navigation-timing/test-navigation-type-reload.html (#33334)
    • PASS [expected FAIL] subtest: Reload domComplete > Original domComplete
    • PASS [expected FAIL] subtest: Reload domContentLoadedEventStart > Original domContentLoadedEventStart
    • PASS [expected FAIL] subtest: Reload domInteractive > Original domInteractive
    • PASS [expected FAIL] subtest: Reload fetchStart > Original fetchStart
    • PASS [expected FAIL] subtest: Reload loadEventEnd > Original loadEventEnd
    • PASS [expected FAIL] subtest: Reload loadEventStart > Original loadEventStart
  • OK /preload/preload-error.sub.html (#37177)
    • FAIL [expected PASS] subtest: success (fetch): main
      assert_greater_than: http://web-platform.test:8000/preload/resources/dummy.xml?label=fetch should be loaded expected a number greater than 0 but got 0
      

    • PASS [expected FAIL] subtest: 404 (fetch): main
    • FAIL [expected PASS] subtest: CORS (fetch): main
      assert_greater_than: http://not-web-platform.test:8000/preload/resources/dummy.xml?pipe=header%28Access-Control-Allow-Origin%2C*%29&label=fetch should be loaded expected a number greater than 0 but got 0
      

  • TIMEOUT [expected OK] /webstorage/localstorage-about-blank-3P-iframe-opens-3P-window.partitioned.html (#29053)
    • TIMEOUT [expected PASS] subtest: StorageKey: test 3P about:blank window opened from a 3P iframe
      Test timed out
      

  • OK [expected ERROR] /webxr/render_state_update.https.html (#27535)
Stable unexpected results (15)
  • OK /IndexedDB/delete-request-queue.any.html
    • FAIL [expected PASS] subtest: Deletes are processed as a FIFO queue
      saw is not a function
      

  • OK /IndexedDB/delete-request-queue.any.worker.html
    • FAIL [expected PASS] subtest: Deletes are processed as a FIFO queue
      saw is not a function
      

  • OK /IndexedDB/idbdatabase-createObjectStore-exception-order.any.html
    • PASS [expected FAIL] subtest: IDBDatabase.createObjectStore exception order: TransactionInactiveError vs. SyntaxError
  • OK /IndexedDB/idbdatabase-createObjectStore-exception-order.any.worker.html
    • PASS [expected FAIL] subtest: IDBDatabase.createObjectStore exception order: TransactionInactiveError vs. SyntaxError
  • OK /IndexedDB/idbdatabase-deleteObjectStore-exception-order.any.html
    • PASS [expected FAIL] subtest: IDBDatabase.deleteObjectStore exception order: TransactionInactiveError vs. NotFoundError
  • OK /IndexedDB/idbdatabase-deleteObjectStore-exception-order.any.worker.html
    • PASS [expected FAIL] subtest: IDBDatabase.deleteObjectStore exception order: TransactionInactiveError vs. NotFoundError
  • TIMEOUT [expected OK] /IndexedDB/idbfactory_open.any.html
    • FAIL [expected PASS] subtest: IDBFactory.open() - no version opens current database
      assert_unreached: Unexpected upgradeneeded Reached unreachable code
      

    • TIMEOUT [expected PASS] subtest: Calling open() with version argument 1.5 should not throw.
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - upgradeneeded gets VersionChangeEvent
      assert_equals: oldVersion expected 0 but got 9
      

  • TIMEOUT [expected OK] /IndexedDB/idbfactory_open.any.worker.html
    • FAIL [expected PASS] subtest: IDBFactory.open() - no version opens current database
      assert_unreached: Unexpected upgradeneeded Reached unreachable code
      

    • TIMEOUT [expected FAIL] subtest: Calling open() with version argument 1.5 should not throw.
      Test timed out
      

    • FAIL [expected PASS] subtest: IDBFactory.open() - upgradeneeded gets VersionChangeEvent
      assert_equals: oldVersion expected 0 but got 9
      

  • OK /IndexedDB/idbobjectstore_delete.any.html
    • PASS [expected FAIL] subtest: delete() key doesn't match any records
  • OK /IndexedDB/idbobjectstore_get.any.worker.html
    • PASS [expected FAIL] subtest: Attempts to retrieve a record that doesn't exist
  • OK /IndexedDB/idbtransaction-oncomplete.any.html
    • PASS [expected FAIL] subtest: IDBTransaction - complete event
  • OK /IndexedDB/idbtransaction-oncomplete.any.worker.html
    • PASS [expected FAIL] subtest: IDBTransaction - complete event
  • TIMEOUT [expected CRASH] /IndexedDB/open-request-queue.any.html
    • TIMEOUT [expected PASS] subtest: IndexedDB: open and delete requests are processed as a FIFO queue
      Test timed out
      

  • TIMEOUT [expected CRASH] /IndexedDB/open-request-queue.any.worker.html
    • TIMEOUT [expected PASS] subtest: IndexedDB: open and delete requests are processed as a FIFO queue
      Test timed out
      

  • OK /IndexedDB/worker-termination-aborts-upgrade.window.html
    • FAIL [expected PASS] subtest: Worker Termination Aborts a Pending Upgrade
      promise_test: Unhandled rejection with value: object "Error: indexedDB.open should not succeed without creating a versionchange transaction"
      

github-actions[bot] avatar Dec 05 '25 17:12 github-actions[bot]

⚠️ Try run (#19970159612) failed.

github-actions[bot] avatar Dec 05 '25 17:12 github-actions[bot]

Current status re tests:

/IndexedDB/delete-request-queue.any.html saw is not a function

If I remove the this from the below:

https://github.com/servo/servo/blob/1e8d1cf08184336cbfa137d55bd5cb5dfe32f39e/tests/wpt/tests/IndexedDB/delete-request-queue.any.js#L10

The test passes.

My changes remove a task queueing(because we are already in a task); I have tried to re-introduce it but the test still fails. Don't know what could have changed the behavior of this. cc @jdm

/IndexedDB/idbfactory_open.any.html

This one goes to the hearth of our lack of db connections. The test does a close, which currently is a sync operation that deletes the database, but the spec reads: to clone the connection, not the db.

I have debugged it and confirmed the problem: Test passes if I remove the code handling the close, and have added a TODO and updated the WPT expectations.

EDIT: the above is not completely correct. The current code does not delete the database, it only deletes the IndexedDBEnvironment, and so even if a new one is created, it re-uses the same underlying physical database. The test fails after my changes because I assume that if no IndexedDBEnvironment is found, then the we hit the "db is null" part of the spec. But in fact there is no way to know whether the db is physically present or not. I've added a beginning of tracking that state.

All other tests that are new fails: I have only looked at their names and they all seem to involve the same problem of not managing transactions lifecycle. So I have updated them all to the results noted above.

There are new passes: I have updated them as well but haven't looked into the details of why they are passing. Could be a case of "if you change anything, some tests will pass".

gterzian avatar Dec 08 '25 14:12 gterzian

So I've marked this one as ready for review, taking into account:

  • The WPT regressions should be seen in the light of their explanation and the follow-ups noted at https://github.com/servo/servo/issues/40983(which are unblocked once this first refactoring merges).
  • Various data structures introduced in this PR will probably be merged into more coherent ones as part of the various items in https://github.com/servo/servo/issues/40983. Example: pending_upgrades: HashMap<(String, u64), PendingUpgrade>, the tuple is not ideal, but the thing is that I don't even know yet exactly what this will look like when we move it to a full transaction lifecyle, and so it doesn't seem worth sweating it now.
  • I've tried to make the smallest change possible while still having something that basically works(example: async open and upgrade, but a full transaction lifecyle is left as a follow-up, hence many WPT regressions because previously open/upgrade was done as one blocking step).
  • the problem with this mentioned above is the one WPT regression I don't understand. I think it's a script context/realm thing...

cc @janvarga @Taym95 @jdm

gterzian avatar Dec 09 '25 12:12 gterzian

:warning: JUnit XML file not found

The CLI was unable to find any JUnit XML files to upload. For more help, visit our troubleshooting guide.

codecov-commenter avatar Dec 09 '25 15:12 codecov-commenter

Setting this back to draft because there are a few things with the failing WPT tests that I still want to check out.

gterzian avatar Dec 09 '25 18:12 gterzian

Ok I ended fixing what were various simple bugs in the new architecture.

There are still a few WPT regressions:

  • Calling open() with version argument 1.5 should not throw. I think this is about implementing abort as part of the new async architecture.
  • Deletes are processed as a FIFO queue: request/transaction lifecyle.
  • open and delete requests are processed as a FIFO queue: request/transaction lifecyle.
  • Worker Termination Aborts a Pending Upgrade: request/transaction lifecyle.

The regressions are I think a result of moving to an async workflow, which requires more bookkeeping than the blocking equivalent.

Ready for review.

gterzian avatar Dec 09 '25 19:12 gterzian

@Taym95 @arihant2math Thanks for the reviews.

gterzian avatar Dec 10 '25 15:12 gterzian

I'll take a look today as well, although I already said that this makes sense from a high level point of view.

janvarga avatar Dec 10 '25 15:12 janvarga

@janvarga thanks for the review.

gterzian avatar Dec 11 '25 12:12 gterzian