diff --git a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html.ini deleted file mode 100644 index 575e16729cb..00000000000 --- a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-navigation.tentative.https.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-partition-navigation.tentative.https.html] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-worker-creation.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-worker-creation.tentative.https.html.ini deleted file mode 100644 index 06d580aa061..00000000000 --- a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition-worker-creation.tentative.https.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-partition-worker-creation.tentative.https.html] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition.tentative.https.html.ini b/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition.tentative.https.html.ini deleted file mode 100644 index 5f8ed6cf262..00000000000 --- a/tests/wpt/meta-legacy-layout/FileAPI/BlobURL/cross-partition.tentative.https.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[cross-partition.tentative.https.html] - expected: TIMEOUT diff --git a/tests/wpt/meta-legacy-layout/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/meta-legacy-layout/FileAPI/url/url-in-tags-revoke.window.js.ini index 35fe4fd6e0d..282ab0b2525 100644 --- a/tests/wpt/meta-legacy-layout/FileAPI/url/url-in-tags-revoke.window.js.ini +++ b/tests/wpt/meta-legacy-layout/FileAPI/url/url-in-tags-revoke.window.js.ini @@ -14,6 +14,3 @@ [Opening a blob URL in a new window by clicking an tag works immediately before revoking the URL.] expected: TIMEOUT - - [Fetching a blob URL immediately before revoking it works in - - - diff --git a/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.any.js b/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.any.js new file mode 100644 index 00000000000..6c521bd7eee --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.any.js @@ -0,0 +1,23 @@ +// META: title=IndexedDB: IDBIndex getAllKeys() uses [EnforceRange] +// META: global=window,worker +// META: script=resources/support.js +// Spec: "https://w3c.github.io/IndexedDB/#index-interface" + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + const index = store.createIndex('index', 'keyPath'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + const index = store.index('index'); + [NaN, Infinity, -Infinity, -1, -Number.MAX_SAFE_INTEGER].forEach( + count => { + assert_throws_js(TypeError, () => { + index.getAllKeys(null, count); + }, `getAllKeys with count ${count} count should throw TypeError`); + }); + t.done(); + }, + 'IDBIndex.getAllKeys() should enforce valid range constraints.'); diff --git a/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.html b/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.html deleted file mode 100644 index 22c19ece4e3..00000000000 --- a/tests/wpt/tests/IndexedDB/idbindex-getAllKeys-enforcerange.html +++ /dev/null @@ -1,27 +0,0 @@ - - -IndexedDB: IDBIndex getAllKeys() uses [EnforceRange] - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.any.js b/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.any.js new file mode 100644 index 00000000000..fba456df5c6 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.any.js @@ -0,0 +1,23 @@ +// META: title=IndexedDB: objectStore SameObject +// META: global=window,worker +// META: script=resources/support.js +// Spec: "https://w3c.github.io/IndexedDB/#dom-idbindex-objectstore" + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + const index = store.createIndex('index', 'keyPath'); + assert_equals( + index.objectStore, index.objectStore, + 'Attribute should yield the same object each time'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + const index = store.index('index'); + assert_equals( + index.objectStore, index.objectStore, + 'Attribute should yield the same object each time'); + t.done(); + }, + 'IDBIndex.objectStore should return same object each time.'); diff --git a/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.html b/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.html deleted file mode 100644 index 186d0f052fe..00000000000 --- a/tests/wpt/tests/IndexedDB/idbindex-objectStore-SameObject.html +++ /dev/null @@ -1,28 +0,0 @@ - - -IndexedDB: Verify [SameObject] behavior of IDBIndex's objectStore attribute - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.any.js new file mode 100644 index 00000000000..259b8a3c909 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.any.js @@ -0,0 +1,24 @@ +// META: global=window,worker +// META: title=IndexedDB: IDBObjectStore getAll() uses [EnforceRange] +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#object-store-interface + +'use strict'; + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + [NaN, Infinity, -Infinity, -1, -Number.MAX_SAFE_INTEGER].forEach( + count => { + assert_throws_js(TypeError, () => { + store.getAll(null, count); + }, `getAll with count ${count} count should throw TypeError`); + }); + t.done(); + }, + `IDBObjectStore.getAll() uses [EnforceRange]`); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.html b/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.html deleted file mode 100644 index 4ead24d36a9..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore-getAll-enforcerange.html +++ /dev/null @@ -1,25 +0,0 @@ - - -IndexedDB: IDBObjectStore getAll() uses [EnforceRange] - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.any.js new file mode 100644 index 00000000000..62a0ed97918 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.any.js @@ -0,0 +1,24 @@ +// META: global=window,worker +// META: title=IndexedDB: IDBIObjectStore getAllKeys() uses [EnforceRange] +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#object-store-interface + +'use strict'; + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + [NaN, Infinity, -Infinity, -1, -Number.MAX_SAFE_INTEGER].forEach( + count => { + assert_throws_js(TypeError, () => { + store.getAllKeys(null, count); + }, `getAllKeys with count ${count} count should throw TypeError`); + }); + t.done(); + }, + `IDBObjectStore.getAllKeys() uses [EnforceRange]`); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.html b/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.html deleted file mode 100644 index 527be11565e..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore-getAllKeys-enforcerange.html +++ /dev/null @@ -1,25 +0,0 @@ - - -IndexedDB: IDBIObjectStore getAllKeys() uses [EnforceRange] - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.any.js new file mode 100644 index 00000000000..d25ce91043d --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.any.js @@ -0,0 +1,23 @@ +// META: global=window,worker +// META: title=IndexedDB: IDBObjectStore index() when transaction is finished +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#dom-idbobjectstore-index + +'use strict'; + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + store.createIndex('index', 'key_path'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + tx.abort(); + assert_throws_dom( + 'InvalidStateError', () => store.index('index'), + 'index() should throw if transaction is finished'); + t.done(); + }, + 'IDBObjectStore index() behavior when transaction is finished'); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.html b/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.html deleted file mode 100644 index be7fe22d75d..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore-index-finished.html +++ /dev/null @@ -1,26 +0,0 @@ - - -IndexedDB: IDBObjectStore index() when transaction is finished - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.any.js new file mode 100644 index 00000000000..8b48a3a61c7 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.any.js @@ -0,0 +1,39 @@ +// META: global=window,worker +// META: title=IndexedDB: The source of requests made against object stores +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#dom-idbrequest-source + +'use strict'; + +[ + store => store.put(0), + store => store.add(0), + store => store.delete(0), + store => store.clear(), + + store => store.get(0), + store => store.getKey(0), + store => store.getAll(), + store => store.getAllKeys(), + store => store.count(), + + store => store.openCursor(), + store => store.openKeyCursor() + +].forEach( + func => indexeddb_test( + (t, db) => { + db.createObjectStore('store', {autoIncrement: true}); + }, + (t, db) => { + const tx = db.transaction('store', 'readwrite'); + const store = tx.objectStore('store'); + + assert_equals( + func(store).source, store, + `${func}.source should be the object store itself`); + t.done(); + }, + `The source of the request from ${ + func} is the object store itself`)); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.html b/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.html deleted file mode 100644 index a710bf52700..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore-request-source.html +++ /dev/null @@ -1,39 +0,0 @@ - - -IndexedDB: The source of requests made against object stores - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.any.js new file mode 100644 index 00000000000..c1e8d80267e --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.any.js @@ -0,0 +1,24 @@ +// META: global=window,worker +// META: title=IndexedDB: Verify [SameObject] behavior of IDBObjectStore's transaction attribute +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#dom-idbobjectstore-transaction + +'use strict'; + +indexeddb_test( + (t, db) => { + const store = db.createObjectStore('store'); + assert_equals( + store.transaction, store.transaction, + 'Attribute should yield the same object each time'); + }, + (t, db) => { + const tx = db.transaction('store', 'readonly'); + const store = tx.objectStore('store'); + assert_equals( + store.transaction, store.transaction, + 'Attribute should yield the same object each time'); + t.done(); + }, + 'IDBObjectStore.transaction [SameObject]'); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.html b/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.html deleted file mode 100644 index 39a954018f3..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore-transaction-SameObject.html +++ /dev/null @@ -1,26 +0,0 @@ - - -IndexedDB: Verify [SameObject] behavior of IDBObjectStore's transaction attribute - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_index.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore_index.any.js new file mode 100644 index 00000000000..e9e68bac326 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore_index.any.js @@ -0,0 +1,24 @@ +// META: global=window,worker +// META: title=IDBObjectStore.index() - returns an index +// META: script=resources/support.js + +'use strict'; + +async_test(t => { + let db; + + let open_rq = createdb(t); + open_rq.onupgradeneeded = t.step_func(e => { + db = e.target.result; + + db.createObjectStore('store').createIndex('index', 'indexedProperty'); + }); + + open_rq.onsuccess = t.step_func(e => { + let index = + db.transaction('store', 'readonly').objectStore('store').index('index'); + + assert_true(index instanceof IDBIndex, 'instanceof IDBIndex'); + t.done(); + }); +}); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_index.htm b/tests/wpt/tests/IndexedDB/idbobjectstore_index.htm deleted file mode 100644 index 3b693f79e70..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore_index.htm +++ /dev/null @@ -1,31 +0,0 @@ - - -IDBObjectStore.index() - returns an index - - - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.any.js new file mode 100644 index 00000000000..0aa9836e764 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.any.js @@ -0,0 +1,35 @@ +// META: global=window,worker +// META: title=IDBObjectStore.openCursor() - iterate through 100 objects +// META: script=resources/support.js + +'use strict'; + +async_test(t => { + let db; + const open_rq = createdb(t); + + open_rq.onupgradeneeded = t.step_func(e => { + db = e.target.result; + let store = db.createObjectStore('store'); + + for (let i = 0; i < 100; i++) + store.add('record_' + i, i); + }); + + open_rq.onsuccess = t.step_func(e => { + let count = 0; + let txn = db.transaction('store', 'readonly'); + + txn.objectStore('store').openCursor().onsuccess = t.step_func(function(e) { + if (e.target.result) { + count += 1; + e.target.result.continue(); + } + }) + + txn.oncomplete = t.step_func(function() { + assert_equals(count, 100); + t.done(); + }) + }); +}); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.htm b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.htm deleted file mode 100644 index e144aa5e7f6..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor.htm +++ /dev/null @@ -1,42 +0,0 @@ - -IDBObjectStore.openCursor() - iterate through 100 objects - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.any.js new file mode 100644 index 00000000000..e2f33af4870 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.any.js @@ -0,0 +1,34 @@ +// META: global=window,worker +// META: title=IDBObjectStore.openCursor() - invalid +// META: script=resources/support.js + +'use strict'; + +indexeddb_test( + function(t, db, tx) { + let objStore = db.createObjectStore('test'); + objStore.createIndex('index', ''); + + objStore.add('data', 1); + objStore.add('data2', 2); + }, + function(t, db, tx) { + let idx = + db.transaction('test', 'readonly').objectStore('test').index('index'); + + assert_throws_dom('DataError', function() { + idx.openCursor({lower: 'a'}); + }); + + assert_throws_dom('DataError', function() { + idx.openCursor({lower: 'a', lowerOpen: false}); + }); + + assert_throws_dom('DataError', function() { + idx.openCursor( + {lower: 'a', lowerOpen: false, upper: null, upperOpen: false}); + }); + + t.done(); + }, + 'IDBObjectStore.openCursor() - invalid - pass something other than number'); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.htm b/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.htm deleted file mode 100644 index d40e115d47c..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore_openCursor_invalid.htm +++ /dev/null @@ -1,33 +0,0 @@ - -IDBObjectStore.openCursor() - invalid - - - - - diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.any.js b/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.any.js new file mode 100644 index 00000000000..8530e3e6918 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.any.js @@ -0,0 +1,134 @@ +// META: global=window,worker +// META: title=IDBObjectStore.openKeyCursor() +// META: script=resources/support.js + +'use strict'; + +function store_test(func, name) { + indexeddb_test( + function(t, db, tx) { + let objectStore = db.createObjectStore('store'); + for (let i = 0; i < 10; ++i) { + objectStore.put('value: ' + i, i); + } + }, + function(t, db) { + let tx = db.transaction('store', 'readonly'); + let objectStore = tx.objectStore('store'); + func(t, db, tx, objectStore); + }, + name); +} + +store_test(function(t, db, tx, objectStore) { + let expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; + let actual = []; + let request = objectStore.openKeyCursor(); + request.onsuccess = t.step_func(function() { + let cursor = request.result; + if (!cursor) + return; + assert_equals(cursor.direction, 'next'); + assert_false('value' in cursor); + assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0); + actual.push(cursor.key); + cursor.continue(); + }); + + tx.onabort = t.unreached_func('transaction aborted'); + tx.oncomplete = t.step_func(function() { + assert_array_equals(expected, actual, 'keys should match'); + t.done(); + }); +}, 'IDBObjectStore.openKeyCursor() - forward iteration'); + +store_test(function(t, db, tx, objectStore) { + let expected = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; + let actual = []; + let request = objectStore.openKeyCursor(null, 'prev'); + request.onsuccess = t.step_func(function() { + let cursor = request.result; + if (!cursor) + return; + assert_equals(cursor.direction, 'prev'); + assert_false('value' in cursor); + assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0); + actual.push(cursor.key); + cursor.continue(); + }); + + tx.onabort = t.unreached_func('transaction aborted'); + tx.oncomplete = t.step_func(function() { + assert_array_equals(expected, actual, 'keys should match'); + t.done(); + }); +}, 'IDBObjectStore.openKeyCursor() - reverse iteration'); + +store_test(function(t, db, tx, objectStore) { + let expected = [4, 5, 6]; + let actual = []; + let request = objectStore.openKeyCursor(IDBKeyRange.bound(4, 6)); + request.onsuccess = t.step_func(function() { + let cursor = request.result; + if (!cursor) + return; + assert_equals(cursor.direction, 'next'); + assert_false('value' in cursor); + assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0); + actual.push(cursor.key); + cursor.continue(); + }); + + tx.onabort = t.unreached_func('transaction aborted'); + tx.oncomplete = t.step_func(function() { + assert_array_equals(expected, actual, 'keys should match'); + t.done(); + }); +}, 'IDBObjectStore.openKeyCursor() - forward iteration with range'); + +store_test(function(t, db, tx, objectStore) { + let expected = [6, 5, 4]; + let actual = []; + let request = objectStore.openKeyCursor(IDBKeyRange.bound(4, 6), 'prev'); + request.onsuccess = t.step_func(function() { + let cursor = request.result; + if (!cursor) + return; + assert_equals(cursor.direction, 'prev'); + assert_false('value' in cursor); + assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0); + actual.push(cursor.key); + cursor.continue(); + }); + + tx.onabort = t.unreached_func('transaction aborted'); + tx.oncomplete = t.step_func(function() { + assert_array_equals(expected, actual, 'keys should match'); + t.done(); + }); +}, 'IDBObjectStore.openKeyCursor() - reverse iteration with range'); + +store_test(function(t, db, tx, objectStore) { + assert_throws_dom('DataError', function() { + objectStore.openKeyCursor(NaN); + }, 'openKeyCursor should throw on invalid number key'); + assert_throws_dom('DataError', function() { + objectStore.openKeyCursor(new Date(NaN)); + }, 'openKeyCursor should throw on invalid date key'); + assert_throws_dom('DataError', function() { + let cycle = []; + cycle.push(cycle); + objectStore.openKeyCursor(cycle); + }, 'openKeyCursor should throw on invalid array key'); + assert_throws_dom('DataError', function() { + objectStore.openKeyCursor({}); + }, 'openKeyCursor should throw on invalid key type'); + setTimeout( + t.step_func(function() { + assert_throws_dom('TransactionInactiveError', function() { + objectStore.openKeyCursor(); + }, 'openKeyCursor should throw if transaction is inactive'); + t.done(); + }), + 0); +}, 'IDBObjectStore.openKeyCursor() - invalid inputs'); diff --git a/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.htm b/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.htm deleted file mode 100644 index b03cc9b7458..00000000000 --- a/tests/wpt/tests/IndexedDB/idbobjectstore_openKeyCursor.htm +++ /dev/null @@ -1,133 +0,0 @@ - -IDBObjectStore.openKeyCursor() - - - - diff --git a/tests/wpt/tests/IndexedDB/idbversionchangeevent.any.js b/tests/wpt/tests/IndexedDB/idbversionchangeevent.any.js new file mode 100644 index 00000000000..506e011dca3 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/idbversionchangeevent.any.js @@ -0,0 +1,92 @@ +// META: title=IDBVersionChangeEvent +// META: global=window,worker +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#events + +'use strict'; + +async_test(t => { + let db; + const dbname = location + '-' + t.name; + + indexedDB.deleteDatabase(dbname); + + const openrq = indexedDB.open(dbname, 3); + + openrq.onupgradeneeded = t.step_func((e) => { + assert_equals(e.oldVersion, 0, 'old version (upgradeneeded)'); + assert_equals(e.newVersion, 3, 'new version (upgradeneeded)'); + assert_true( + e instanceof IDBVersionChangeEvent, + 'upgradeneeded instanceof IDBVersionChangeEvent'); + }); + + openrq.onsuccess = t.step_func((e) => { + db = e.target.result; + + db.onversionchange = t.step_func((e) => { + assert_equals(e.oldVersion, 3, 'old version (versionchange)'); + assert_equals(e.newVersion, null, 'new version (versionchange)'); + assert_true( + e instanceof IDBVersionChangeEvent, + 'versionchange instanceof IDBVersionChangeEvent'); + db.close(); + }); + + // Errors + db.onerror = fail(t, 'db.error'); + db.onabort = fail(t, 'db.abort'); + + setTimeout(t.step_func(deleteDB), 10); + }); + + // Errors + openrq.onerror = fail(t, 'open.error'); + openrq.onblocked = fail(t, 'open.blocked'); + + function deleteDB(e) { + const deleterq = indexedDB.deleteDatabase(dbname); + + deleterq.onsuccess = t.step_func((e) => { + assert_equals( + e.result, undefined, 'result (delete.success for nonexistent db)'); + assert_equals(e.oldVersion, 3, 'old version (delete.success)'); + assert_equals(e.newVersion, null, 'new version (delete.success)'); + assert_true( + e instanceof IDBVersionChangeEvent, + 'delete.success instanceof IDBVersionChangeEvent'); + + setTimeout(deleteNonExistentDB, 10); + }); + + // Errors + deleterq.onerror = fail(t, 'delete.error'); + deleterq.onblocked = fail(t, 'delete.blocked'); + } + + function deleteNonExistentDB(e) { + const deleterq = indexedDB.deleteDatabase('db-does-not-exist'); + + deleterq.onsuccess = t.step_func((e) => { + assert_equals( + e.result, undefined, 'result (delete.success for nonexistent db)'); + assert_equals( + e.oldVersion, 0, 'old version (delete.success for nonexistent db)'); + assert_equals( + e.newVersion, null, + 'new version (delete.success for nonexistent db)'); + assert_true( + e instanceof IDBVersionChangeEvent, + 'delete.success instanceof IDBVersionChangeEvent'); + + setTimeout(function() { + t.done(); + }, 10); + }); + + // Errors + deleterq.onerror = fail(t, 'delete.error'); + deleterq.onblocked = fail(t, 'delete.blocked'); + } +}, 'IDBVersionChangeEvent fired in upgradeneeded, versionchange and deleteDatabase'); diff --git a/tests/wpt/tests/IndexedDB/idbversionchangeevent.htm b/tests/wpt/tests/IndexedDB/idbversionchangeevent.htm deleted file mode 100644 index 9ea7e6d4914..00000000000 --- a/tests/wpt/tests/IndexedDB/idbversionchangeevent.htm +++ /dev/null @@ -1,87 +0,0 @@ - -IDBVersionChangeEvent fired in upgradeneeded, versionchange and deleteDatabase - - - - - - - - -
- - diff --git a/tests/wpt/tests/IndexedDB/index_sort_order.any.js b/tests/wpt/tests/IndexedDB/index_sort_order.any.js new file mode 100644 index 00000000000..8d98d6c8834 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/index_sort_order.any.js @@ -0,0 +1,43 @@ +// META: title= IDBIndex Key sort order +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +async_test(t => { + let db; + const d = new Date(); + const records = [{foo: d}, {foo: 'test'}, {foo: 1}, {foo: 2.55}]; + const expectedKeyOrder = [1, 2.55, d.valueOf(), 'test']; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = t.step_func((e) => { + db = e.target.result; + const objStore = db.createObjectStore('store', {autoIncrement: true}); + objStore.createIndex('index', 'foo'); + + for (let i = 0; i < records.length; i++) { + objStore.add(records[i]); + } + }); + + open_rq.onsuccess = t.step_func((e) => { + let actual_keys = []; + const rq = db.transaction('store', 'readonly') + .objectStore('store') + .index('index') + .openCursor(); + + rq.onsuccess = t.step_func((e) => { + const cursor = e.target.result; + + if (cursor) { + actual_keys.push(cursor.key.valueOf()); + cursor.continue(); + } else { + assert_array_equals(actual_keys, expectedKeyOrder); + t.done(); + } + }); + }); +}, 'Verify IDBIndex key sort order is \'number < Date < DOMString\''); diff --git a/tests/wpt/tests/IndexedDB/index_sort_order.htm b/tests/wpt/tests/IndexedDB/index_sort_order.htm deleted file mode 100644 index 5af8e6f865e..00000000000 --- a/tests/wpt/tests/IndexedDB/index_sort_order.htm +++ /dev/null @@ -1,51 +0,0 @@ - - -Verify key sort order in an index is 'number < Date < DOMString' - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/interleaved-cursors-large.any.js b/tests/wpt/tests/IndexedDB/interleaved-cursors-large.any.js new file mode 100644 index 00000000000..cb79569b207 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/interleaved-cursors-large.any.js @@ -0,0 +1,9 @@ +// META: title=IndexedDB: Interleaved iteration of multiple cursors +// META: global=window,worker +// META: script=resources/support-promises.js +// META: script=resources/interleaved-cursors-common.js +// META: timeout=long + +'use strict'; + +cursorTest(250); diff --git a/tests/wpt/tests/IndexedDB/interleaved-cursors-large.html b/tests/wpt/tests/IndexedDB/interleaved-cursors-large.html deleted file mode 100644 index 9e17f9e1124..00000000000 --- a/tests/wpt/tests/IndexedDB/interleaved-cursors-large.html +++ /dev/null @@ -1,12 +0,0 @@ - - - -IndexedDB: Interleaved iteration of multiple cursors - - - - - - diff --git a/tests/wpt/tests/IndexedDB/interleaved-cursors-small.any.js b/tests/wpt/tests/IndexedDB/interleaved-cursors-small.any.js new file mode 100644 index 00000000000..452f7c62f54 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/interleaved-cursors-small.any.js @@ -0,0 +1,11 @@ +// META: title=IndexedDB: Interleaved iteration of multiple cursors +// META: global=window,worker +// META: script=resources/support-promises.js +// META: script=resources/interleaved-cursors-common.js +// META: timeout=long + +'use strict'; + +cursorTest(1); +cursorTest(10); +cursorTest(100); diff --git a/tests/wpt/tests/IndexedDB/interleaved-cursors-small.html b/tests/wpt/tests/IndexedDB/interleaved-cursors-small.html deleted file mode 100644 index 2751113f5f7..00000000000 --- a/tests/wpt/tests/IndexedDB/interleaved-cursors-small.html +++ /dev/null @@ -1,14 +0,0 @@ - - - -IndexedDB: Interleaved iteration of multiple cursors - - - - - - diff --git a/tests/wpt/tests/IndexedDB/large-requests-abort.html b/tests/wpt/tests/IndexedDB/large-requests-abort.any.js similarity index 62% rename from tests/wpt/tests/IndexedDB/large-requests-abort.html rename to tests/wpt/tests/IndexedDB/large-requests-abort.any.js index 38c73ff4069..c9728e8a9e8 100644 --- a/tests/wpt/tests/IndexedDB/large-requests-abort.html +++ b/tests/wpt/tests/IndexedDB/large-requests-abort.any.js @@ -1,13 +1,10 @@ - - - -IndexedDB: transactions with large request results are aborted correctly - - - - - - diff --git a/tests/wpt/tests/IndexedDB/list_ordering.any.js b/tests/wpt/tests/IndexedDB/list_ordering.any.js new file mode 100644 index 00000000000..e5cbacfcfb2 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/list_ordering.any.js @@ -0,0 +1,66 @@ +// META: title=ObjectStoreNames and indexNames ordering +// META: global=window,worker +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#dom-idbdatabase-objectstorenames + +'use strict'; + +function list_order(desc, unsorted, expected) { + let objStore; + let db; + let t = async_test( + 'Validate ObjectStoreNames and indexNames list order - ' + desc); + const open_rq = createdb(t); + open_rq.onupgradeneeded = t.step_func((e) => { + db = e.target.result; + for (let i = 0; i < unsorted.length; i++) + objStore = db.createObjectStore(unsorted[i]); + + assert_equals( + db.objectStoreNames.length, expected.length, 'objectStoreNames length'); + for (let i = 0; i < expected.length; i++) + assert_equals( + db.objectStoreNames[i], expected[i], 'objectStoreNames[' + i + ']'); + + for (let i = 0; i < unsorted.length; i++) + objStore.createIndex(unsorted[i], 'length'); + + assert_equals( + objStore.indexNames.length, expected.length, 'indexNames length'); + for (let i = 0; i < expected.length; i++) + assert_equals( + objStore.indexNames[i], expected[i], 'indexNames[' + i + ']'); + }); + + open_rq.onsuccess = t.step_func((e) => { + assert_equals( + db.objectStoreNames.length, expected.length, 'objectStoreNames length'); + for (let i = 0; i < expected.length; i++) + assert_equals( + db.objectStoreNames[i], expected[i], 'objectStoreNames[' + i + ']'); + + assert_equals( + objStore.indexNames.length, expected.length, 'indexNames length'); + for (let i = 0; i < expected.length; i++) + assert_equals( + objStore.indexNames[i], expected[i], 'indexNames[' + i + ']'); + + t.done(); + }); +} + +list_order( + 'numbers', [123456, -12345, -123, 123, 1234, -1234, 0, 12345, -123456], [ + '-123', '-1234', '-12345', '-123456', '0', '123', '1234', '12345', + '123456' + ]); + +list_order( + 'numbers \'overflow\'', [9, 1, 1000000000, 200000000000000000], + ['1', '1000000000', '200000000000000000', '9']); + +list_order( + 'lexigraphical string sort', + ['cc', 'c', 'aa', 'a', 'bb', 'b', 'ab', '', 'ac'], + ['', 'a', 'aa', 'ab', 'ac', 'b', 'bb', 'c', 'cc']); diff --git a/tests/wpt/tests/IndexedDB/list_ordering.htm b/tests/wpt/tests/IndexedDB/list_ordering.htm deleted file mode 100644 index a3c36de3891..00000000000 --- a/tests/wpt/tests/IndexedDB/list_ordering.htm +++ /dev/null @@ -1,61 +0,0 @@ - - -objectStoreNames and indexNames order - - - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/name-scopes.any.js b/tests/wpt/tests/IndexedDB/name-scopes.any.js new file mode 100644 index 00000000000..59afb890d6e --- /dev/null +++ b/tests/wpt/tests/IndexedDB/name-scopes.any.js @@ -0,0 +1,133 @@ +// META: title=IndexedDB: scoping for database / object store / index names, and index keys +// META: global=window,worker +// META: script=resources/support-promises.js + +// Spec: https://w3c.github.io/IndexedDB/#constructs + +'use strict'; + +// Creates the structure inside a test database. +// +// The structure includes two stores with identical indexes and nearly-similar +// records. The records differ in the "path" attribute values, which are used to +// verify that IndexedDB returns the correct records when queried. +// +// databaseName appears redundant, but we don't want to rely on database.name. +const buildStores = (database, databaseName, useUniqueKeys) => { + for (let storeName of ['x', 'y']) { + const store = database.createObjectStore( + storeName, {keyPath: 'pKey', autoIncrement: true}); + for (let indexName of ['x', 'y']) { + store.createIndex(indexName, `${indexName}Key`, {unique: useUniqueKeys}); + } + + for (let xKeyRoot of ['x', 'y']) { + for (let yKeyRoot of ['x', 'y']) { + let xKey, yKey; + if (useUniqueKeys) { + xKey = `${xKeyRoot}${yKeyRoot}`; + yKey = `${yKeyRoot}${xKeyRoot}`; + } else { + xKey = xKeyRoot; + yKey = yKeyRoot; + } + const path = `${databaseName}-${storeName}-${xKeyRoot}-${yKeyRoot}`; + store.put({xKey: xKey, yKey: yKey, path: path}); + } + } + } +}; + +// Creates two databases with identical structures. +const buildDatabases = (testCase, useUniqueKeys) => { + return createNamedDatabase( + testCase, 'x', + database => buildStores(database, 'x', useUniqueKeys)) + .then(database => database.close()) + .then( + () => createNamedDatabase( + testCase, 'y', + database => buildStores(database, 'y', useUniqueKeys))) + .then(database => database.close()); +}; + +// Reads all the store's values using an index. +// +// Returns a Promise that resolves with an array of values. +const readIndex = + (testCase, index) => { + return new Promise((resolve, reject) => { + const results = []; + const request = index.openCursor(IDBKeyRange.bound('a', 'z'), 'next'); + request.onsuccess = testCase.step_func(() => { + const cursor = request.result; + if (cursor) { + results.push(cursor.value); + cursor.continue(); + } else { + resolve(results); + } + }); + }); + } + +// Verifies that a database contains the expected records. +const checkDatabaseContent = + (testCase, database, databaseName, usedUniqueKeys) => { + const promises = []; + const transaction = database.transaction(['x', 'y'], 'readonly'); + for (let storeName of ['x', 'y']) { + const store = transaction.objectStore(storeName); + for (let indexName of ['x', 'y']) { + const index = store.index(indexName); + + const promise = readIndex(testCase, index).then((results) => { + assert_array_equals( + results.map(result => `${result.path}:${result.pKey}`).sort(), + [ + `${databaseName}-${storeName}-x-x:1`, + `${databaseName}-${storeName}-x-y:2`, + `${databaseName}-${storeName}-y-x:3`, + `${databaseName}-${storeName}-y-y:4` + ], + 'The results should include all records put into the store'); + + let expectedKeys = (usedUniqueKeys) ? + ['xx:xx', 'xy:yx', 'yx:xy', 'yy:yy'] : + ['x:x', 'x:y', 'y:x', 'y:y']; + assert_array_equals( + results.map(result => `${result.xKey}:${result.yKey}`).sort(), + expectedKeys, + 'The results should include all the index keys put in the store'); + + assert_array_equals( + results.map(result => result[`${indexName}Key`]), + results.map(result => result[`${indexName}Key`]).sort(), + 'The results should be sorted by the index key'); + }); + promises.push(promise); + } + } + + return Promise.all(promises).then(() => database); + } + +promise_test(testCase => { + return buildDatabases(testCase, false) + .then(() => openNamedDatabase(testCase, 'x', 1)) + .then(database => checkDatabaseContent(testCase, database, 'x', false)) + .then(database => database.close()) + .then(() => openNamedDatabase(testCase, 'y', 1)) + .then(database => checkDatabaseContent(testCase, database, 'y', false)) + .then(database => database.close()); +}, 'Non-unique index keys'); + +promise_test(testCase => { + return buildDatabases(testCase, true) + .then(() => openNamedDatabase(testCase, 'x', 1)) + .then(database => checkDatabaseContent(testCase, database, 'x', true)) + .then(database => database.close()) + .then(() => openNamedDatabase(testCase, 'y', 1)) + .then(database => checkDatabaseContent(testCase, database, 'y', true)) + .then(database => database.close()); +}, 'Unique index keys'); diff --git a/tests/wpt/tests/IndexedDB/name-scopes.html b/tests/wpt/tests/IndexedDB/name-scopes.html deleted file mode 100644 index d92f706e0a7..00000000000 --- a/tests/wpt/tests/IndexedDB/name-scopes.html +++ /dev/null @@ -1,134 +0,0 @@ - - - - IndexedDB: scoping for database / object store / index names, and index keys - - - - - - - diff --git a/tests/wpt/tests/IndexedDB/objectstore_keyorder.any.js b/tests/wpt/tests/IndexedDB/objectstore_keyorder.any.js new file mode 100644 index 00000000000..e8ee3d1e88e --- /dev/null +++ b/tests/wpt/tests/IndexedDB/objectstore_keyorder.any.js @@ -0,0 +1,39 @@ +// META: title=IDBObjectStore key sort order +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +async_test(t => { + let db; + const d = new Date(); + const records = [{key: d}, {key: 'test'}, {key: 1}, {key: 2.55}]; + const expectedKeyOrder = [1, 2.55, d.valueOf(), 'test']; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = t.step_func((e) => { + db = e.target.result; + const objStore = db.createObjectStore('store', {keyPath: 'key'}); + + for (let i = 0; i < records.length; i++) + objStore.add(records[i]); + }); + + open_rq.onsuccess = t.step_func((e) => { + let actual_keys = []; + const rq = + db.transaction('store', 'readonly').objectStore('store').openCursor(); + + rq.onsuccess = t.step_func((e) => { + const cursor = e.target.result; + + if (cursor) { + actual_keys.push(cursor.key.valueOf()); + cursor.continue(); + } else { + assert_array_equals(actual_keys, expectedKeyOrder); + t.done(); + } + }); + }); +}, 'Verify key sort order in an object store is \'number < Date < DOMString\' '); diff --git a/tests/wpt/tests/IndexedDB/objectstore_keyorder.htm b/tests/wpt/tests/IndexedDB/objectstore_keyorder.htm deleted file mode 100644 index f3f5ae76e7c..00000000000 --- a/tests/wpt/tests/IndexedDB/objectstore_keyorder.htm +++ /dev/null @@ -1,49 +0,0 @@ - - -Verify key sort order in an object store is 'number < Date < DOMString' - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/open-request-queue.any.js b/tests/wpt/tests/IndexedDB/open-request-queue.any.js new file mode 100644 index 00000000000..69b53a29b0c --- /dev/null +++ b/tests/wpt/tests/IndexedDB/open-request-queue.any.js @@ -0,0 +1,54 @@ +// META: title=IndexedDB: open and delete request queues +// META: global=window,worker +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#connection-queues + +'use strict'; + +async_test(t => { + const db_name = 'db' + self.location.pathname + '-' + t.name; + indexedDB.deleteDatabase(db_name); + + // Open and hold connection while other requests are queued up. + const r = indexedDB.open(db_name, 1); + r.onerror = t.unreached_func('open should succeed'); + r.onsuccess = t.step_func(e => { + const db = r.result; + + const saw = expect(t, [ + 'open1 success', 'open1 versionchange', 'delete1 blocked', + 'delete1 success', 'open2 success', 'open2 versionchange', + 'delete2 blocked', 'delete2 success' + ]); + + function open(token, version) { + const r = indexedDB.open(db_name, version); + r.onsuccess = t.step_func(e => { + saw(token + ' success'); + const db = r.result; + db.onversionchange = t.step_func(e => { + saw(token + ' versionchange'); + setTimeout(t.step_func(() => db.close()), 0); + }); + }); + r.onblocked = t.step_func(e => saw(token + ' blocked')); + r.onerror = t.unreached_func('open should succeed'); + } + + function deleteDatabase(token) { + const r = indexedDB.deleteDatabase(db_name); + r.onsuccess = t.step_func(e => saw(token + ' success')); + r.onblocked = t.step_func(e => saw(token + ' blocked')); + r.onerror = t.unreached_func('deleteDatabase should succeed'); + } + + open('open1', 2); + deleteDatabase('delete1'); + open('open2', 3); + deleteDatabase('delete2'); + + // Now unblock the queue. + db.close(); + }); +}, 'IndexedDB: open and delete requests are processed as a FIFO queue'); diff --git a/tests/wpt/tests/IndexedDB/open-request-queue.html b/tests/wpt/tests/IndexedDB/open-request-queue.html deleted file mode 100644 index b4371f2a2ee..00000000000 --- a/tests/wpt/tests/IndexedDB/open-request-queue.html +++ /dev/null @@ -1,63 +0,0 @@ - - -IndexedDB: open and delete requests are processed as a FIFO queue - - - - - diff --git a/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.any.js b/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.any.js new file mode 100644 index 00000000000..d938ef05dc5 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.any.js @@ -0,0 +1,47 @@ +// META: title=IndexedDB: Parallel iteration of cursors in upgradeneeded +// META: global=window,worker +// META: script=resources/support-promises.js +// META: timeout=long + +'use strict'; + +for (const cursorCount of [2, 20, 200, 2000]) { + promise_test(testCase => { + return createDatabase(testCase, (database, transaction) => { + const store = + database.createObjectStore('cache', {keyPath: 'key'}); + store.put({key: '42'}); + + const promises = []; + + for (let j = 0; j < 2; j += 1) { + const promise = new Promise((resolve, reject) => { + let request = null; + for (let i = 0; i < cursorCount / 2; i += 1) { + request = store.openCursor(); + } + + let continued = false; + request.onsuccess = testCase.step_func(() => { + const cursor = request.result; + + if (!continued) { + assert_equals(cursor.key, '42'); + assert_equals(cursor.value.key, '42'); + continued = true; + cursor.continue(); + } else { + assert_equals(cursor, null); + resolve(); + } + }); + request.onerror = () => reject(request.error); + }); + promises.push(promise); + } + return Promise.all(promises); + }).then(database => { + database.close(); + }); + }, `${cursorCount} cursors`); +} diff --git a/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.html b/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.html deleted file mode 100644 index 99ea65d9d60..00000000000 --- a/tests/wpt/tests/IndexedDB/parallel-cursors-upgrade.html +++ /dev/null @@ -1,52 +0,0 @@ - - - -IndexedDB: Parallel iteration of cursors in upgradeneeded - - - - - diff --git a/tests/wpt/tests/IndexedDB/string-list-ordering.any.js b/tests/wpt/tests/IndexedDB/string-list-ordering.any.js new file mode 100644 index 00000000000..ab88bc5503c --- /dev/null +++ b/tests/wpt/tests/IndexedDB/string-list-ordering.any.js @@ -0,0 +1,68 @@ +// META: title=IndexedDB string list ordering +// META: global=window,worker +// META: script=resources/support.js + +// Spec: https://w3c.github.io/IndexedDB/#dom-idbdatabase-objectstorenames + +'use strict'; + +async_test(t => { + let expectedOrder = [ + '', '\x00', // 'NULL' (U+0000) + '0', '1', 'A', 'B', 'a', 'b', '\x7F', // 'DELETE' (U+007F) + '\xC0', // 'LATIN CAPITAL LETTER A WITH GRAVE' (U+00C0) + '\xC1', // 'LATIN CAPITAL LETTER A WITH ACUTE' (U+00C1) + '\xE0', // 'LATIN SMALL LETTER A WITH GRAVE' (U+00E0) + '\xE1', // 'LATIN SMALL LETTER A WITH ACUTE' (U+00E1) + '\xFF', // 'LATIN SMALL LETTER Y WITH DIAERESIS' (U+00FF) + '\u0100', // 'LATIN CAPITAL LETTER A WITH MACRON' (U+0100) + '\u1000', // 'MYANMAR LETTER KA' (U+1000) + '\uD834\uDD1E', // 'MUSICAL SYMBOL G-CLEF' (U+1D11E), UTF-16 surrogate + // pairs + '\uFFFD' // 'REPLACEMENT CHARACTER' (U+FFFD) + ]; + + let i; + let tmp; + const permutedOrder = expectedOrder.slice(); + permutedOrder.reverse(); + for (i = 0; i < permutedOrder.length - 2; i += 2) { + tmp = permutedOrder[i]; + permutedOrder[i] = permutedOrder[i + 1]; + permutedOrder[i + 1] = tmp; + } + + let objStore; + let db; + + // Check that the expected order is the canonical JS sort order. + const sortedOrder = expectedOrder.slice(); + sortedOrder.sort(); + assert_array_equals(sortedOrder, expectedOrder); + + const request = createdb(t); + + request.onupgradeneeded = t.step_func((e) => { + db = e.target.result; + + // Object stores. + for (let i = 0; i < permutedOrder.length; i++) { + objStore = db.createObjectStore(permutedOrder[i]); + } + assert_array_equals(db.objectStoreNames, expectedOrder); + + // Indexes. + for (let i = 0; i < permutedOrder.length; i++) { + objStore.createIndex(permutedOrder[i], 'keyPath'); + } + assert_array_equals(objStore.indexNames, expectedOrder); + }); + + request.onsuccess = t.step_func((e) => { + // Object stores. + assert_array_equals(db.objectStoreNames, expectedOrder); + // Indexes. + assert_array_equals(objStore.indexNames, expectedOrder); + t.done(); + }); +}, 'Test string list ordering in IndexedDB'); diff --git a/tests/wpt/tests/IndexedDB/string-list-ordering.htm b/tests/wpt/tests/IndexedDB/string-list-ordering.htm deleted file mode 100644 index ddbbc3036fb..00000000000 --- a/tests/wpt/tests/IndexedDB/string-list-ordering.htm +++ /dev/null @@ -1,85 +0,0 @@ - - - - - -Test string list ordering in IndexedDB - - - - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/value_recursive.any.js b/tests/wpt/tests/IndexedDB/value_recursive.any.js new file mode 100644 index 00000000000..9be6404adf3 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/value_recursive.any.js @@ -0,0 +1,51 @@ +// META: title=IndexedDB: recursive value +// META: global=window,worker +// META: script=resources/support.js + +'use strict'; + +function recursive_value(desc, value) { + let db; + const t = async_test('Recursive value - ' + desc); + + createdb(t).onupgradeneeded = t.step_func((e) => { + db = e.target.result; + db.createObjectStore('store').add(value, 1); + + e.target.onsuccess = t.step_func((e) => { + db.transaction('store', 'readonly') + .objectStore('store') + .get(1) + .onsuccess = t.step_func((e) => { + try { + JSON.stringify(value); + assert_unreached( + 'The test case is incorrect. It must provide a recursive value that JSON cannot stringify.'); + } catch (e) { + if (e.name == 'TypeError') { + try { + JSON.stringify(e.target.result); + assert_unreached( + 'Expected a non-JSON-serializable value back, didn\'t get that.'); + } catch (e) { + t.done(); + return; + } + } else + throw e; + } + }); + }); + }); +} + +const recursive = []; +recursive.push(recursive); +recursive_value('array directly contains self', recursive); + +const recursive2 = []; +recursive2.push([recursive2]); +recursive_value('array indirectly contains self', recursive2); + +const recursive3 = [recursive]; +recursive_value('array member contains self', recursive3); diff --git a/tests/wpt/tests/IndexedDB/value_recursive.htm b/tests/wpt/tests/IndexedDB/value_recursive.htm deleted file mode 100644 index 29325a59094..00000000000 --- a/tests/wpt/tests/IndexedDB/value_recursive.htm +++ /dev/null @@ -1,66 +0,0 @@ - - -Recursive value - - - - - - - -
diff --git a/tests/wpt/tests/IndexedDB/writer-starvation.any.js b/tests/wpt/tests/IndexedDB/writer-starvation.any.js new file mode 100644 index 00000000000..a116e4f52f2 --- /dev/null +++ b/tests/wpt/tests/IndexedDB/writer-starvation.any.js @@ -0,0 +1,91 @@ +// META: title=IndexedDB writer starvation test +// META: global=window,worker +// META: script=resources/support.js +// META: timeout=long + +'use strict'; + +async_test(t => { + let db; + let read_request_count = 0; + let read_success_count = 0; + let write_request_count = 0; + let write_success_count = 0; + const RQ_COUNT = 25; + + const open_rq = createdb(t); + open_rq.onupgradeneeded = t.step_func((e) => { + db = e.target.result; + db.createObjectStore('s').add('1', 1); + }); + + open_rq.onsuccess = t.step_func((e) => { + let i = 0; + + // Pre-fill some read requests. + for (i = 0; i < RQ_COUNT; i++) { + read_request_count++; + + db.transaction('s', 'readonly').objectStore('s').get(1).onsuccess = + t.step_func((e) => { + read_success_count++; + assert_equals(e.target.transaction.mode, 'readonly'); + }); + } + + t.step(loop); + + function loop() { + read_request_count++; + + db.transaction('s', 'readonly').objectStore('s').get(1).onsuccess = + t.step_func((e) => { + read_success_count++; + assert_equals(e.target.transaction.mode, 'readonly'); + + if (read_success_count >= RQ_COUNT && write_request_count == 0) { + write_request_count++; + + db.transaction('s', 'readwrite') + .objectStore('s') + .add('written', read_request_count) + .onsuccess = t.step_func((e) => { + write_success_count++; + assert_equals(e.target.transaction.mode, 'readwrite'); + assert_equals( + e.target.result, read_success_count, + 'write cb came before later read cb\'s'); + }); + + // Reads done after the write. + for (i = 0; i < 5; i++) { + read_request_count++; + + db.transaction('s', 'readonly') + .objectStore('s') + .get(1) + .onsuccess = t.step_func((e) => { + read_success_count++; + }); + } + } + }); + + if (read_success_count < RQ_COUNT + 5) { + step_timeout(t.step_func(loop), write_request_count ? 1000 : 100); + } else { + // This runs finish() once `read_success_count` >= RQ_COUNT + 5. + db.transaction('s', 'readonly').objectStore('s').count().onsuccess = + t.step_func(() => { + step_timeout(t.step_func(finish), 100); + }); + } + } + }); + + function finish() { + assert_equals(read_request_count, read_success_count, 'read counts'); + assert_equals(write_request_count, write_success_count, 'write counts'); + t.done(); + } +}, 'IDB read requests should not starve write requests'); diff --git a/tests/wpt/tests/IndexedDB/writer-starvation.htm b/tests/wpt/tests/IndexedDB/writer-starvation.htm deleted file mode 100644 index e382139b87d..00000000000 --- a/tests/wpt/tests/IndexedDB/writer-starvation.htm +++ /dev/null @@ -1,105 +0,0 @@ - - -Writer starvation - - - - - - - - -
diff --git a/tests/wpt/tests/ai/translator/ai_translator_bad_input.tentative.https.any.js b/tests/wpt/tests/ai/translator/ai_translator_bad_input.tentative.https.any.js index adc7043849b..980d3c0f697 100644 --- a/tests/wpt/tests/ai/translator/ai_translator_bad_input.tentative.https.any.js +++ b/tests/wpt/tests/ai/translator/ai_translator_bad_input.tentative.https.any.js @@ -8,8 +8,16 @@ 'use strict'; promise_test(async t => { - const translatorFactory = ai.translator; - assert_not_equals(translatorFactory, null); - await promise_rejects_dom(t, 'InvalidStateError',translatorFactory.create(/*empty options*/), - 'No options are provided.'); -}); + await promise_rejects_js( + t, TypeError, ai.translator.create(/*empty options*/)); +}, 'AITranslatorFactory.create rejects with TypeError if no options are passed.'); + +promise_test(async t => { + await promise_rejects_js( + t, TypeError, ai.translator.create({sourceLanguage: 'en'})); +}, 'AITranslatorFactory.create rejects with TypeError targetLanguage is not provided.'); + +promise_test(async t => { + await promise_rejects_js( + t, TypeError, ai.translator.create({targetLanguage: 'en'})); +}, 'AITranslatorFactory.create rejects with TypeError sourceLanguage is not provided.'); diff --git a/tests/wpt/tests/ai/translator/ai_translator_translate.tentative.https.any.js b/tests/wpt/tests/ai/translator/ai_translator_translate.tentative.https.any.js index 1066a9cff61..2041ad82b5a 100644 --- a/tests/wpt/tests/ai/translator/ai_translator_translate.tentative.https.any.js +++ b/tests/wpt/tests/ai/translator/ai_translator_translate.tentative.https.any.js @@ -81,3 +81,31 @@ promise_test(async t => { return translator.translate('hello', {signal}); }); }, 'Aborting AITranslator.translate().'); + +promise_test(async t => { + let monitorCalled = false; + const progressEvents = []; + function monitor(m) { + monitorCalled = true; + + m.addEventListener('downloadprogress', e => { + progressEvents.push(e); + }); + } + + await ai.translator.create( + {sourceLanguage: 'en', targetLanguage: 'ja', monitor}); + + // Monitor callback must be called. + assert_true(monitorCalled); + + // Must have at least 2 progress events, one for 0 and one for 1. + assert_greater_than_equal(progressEvents.length, 2); + assert_equals(progressEvents.at(0).loaded, 0); + assert_equals(progressEvents.at(1).loaded, 1); + + // All progress events must have a total of 1. + for (const progressEvent of progressEvents) { + assert_equals(progressEvent.total, 1); + } +}, 'AITranslatorFactory.create() monitor option is called correctly.'); diff --git a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-absent-getAvailability.https.window.js b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-absent-getAvailability.https.window.js similarity index 75% rename from tests/wpt/tests/bluetooth/legacy/adapter/adapter-absent-getAvailability.https.window.js rename to tests/wpt/tests/bluetooth/bidi/adapter/adapter-absent-getAvailability.https.window.js index 55f4a675da1..419a9d411df 100644 --- a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-absent-getAvailability.https.window.js +++ b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-absent-getAvailability.https.window.js @@ -1,4 +1,4 @@ -// META: script=/resources/testdriver.js +// META: script=/resources/testdriver.js?feature=bidi // META: script=/resources/testdriver-vendor.js // META: script=/bluetooth/resources/bluetooth-test.js // META: script=/bluetooth/resources/bluetooth-fake-devices.js @@ -6,8 +6,8 @@ const test_desc = 'getAvailability() resolves with false if the system does ' + 'not have an adapter.'; -bluetooth_test(async () => { - await navigator.bluetooth.test.simulateCentral({state: 'absent'}); +bluetooth_bidi_test(async () => { + await test_driver.bidi.bluetooth.simulate_adapter({state: "absent"}); let availability = await navigator.bluetooth.getAvailability(); assert_false( availability, diff --git a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-off-getAvailability.https.window.js b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-off-getAvailability.https.window.js similarity index 76% rename from tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-off-getAvailability.https.window.js rename to tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-off-getAvailability.https.window.js index 1ffcd3bb096..9bf10801bb7 100644 --- a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-off-getAvailability.https.window.js +++ b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-off-getAvailability.https.window.js @@ -1,4 +1,4 @@ -// META: script=/resources/testdriver.js +// META: script=/resources/testdriver.js?feature=bidi // META: script=/resources/testdriver-vendor.js // META: script=/bluetooth/resources/bluetooth-test.js // META: script=/bluetooth/resources/bluetooth-fake-devices.js @@ -6,8 +6,8 @@ const test_desc = 'getAvailability() resolves with true if the Bluetooth ' + 'radio is powered off, but the platform that supports Bluetooth LE.'; -bluetooth_test(async () => { - await navigator.bluetooth.test.simulateCentral({state: 'powered-off'}); +bluetooth_bidi_test(async () => { + await test_driver.bidi.bluetooth.simulate_adapter({state: "powered-off"}); let availability = await navigator.bluetooth.getAvailability(); assert_true( availability, diff --git a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-on-getAvailability.https.window.js b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-on-getAvailability.https.window.js similarity index 77% rename from tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-on-getAvailability.https.window.js rename to tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-on-getAvailability.https.window.js index 84c7982d214..6ffba254d8a 100644 --- a/tests/wpt/tests/bluetooth/legacy/adapter/adapter-powered-on-getAvailability.https.window.js +++ b/tests/wpt/tests/bluetooth/bidi/adapter/adapter-powered-on-getAvailability.https.window.js @@ -1,4 +1,4 @@ -// META: script=/resources/testdriver.js +// META: script=/resources/testdriver.js?feature=bidi // META: script=/resources/testdriver-vendor.js // META: script=/bluetooth/resources/bluetooth-test.js // META: script=/bluetooth/resources/bluetooth-fake-devices.js @@ -6,8 +6,8 @@ const test_desc = 'getAvailability() resolves with true if the Bluetooth ' + 'radio is powered on and the platform supports Bluetooth LE.'; -bluetooth_test(async () => { - await navigator.bluetooth.test.simulateCentral({state: 'powered-on'}); +bluetooth_bidi_test(async () => { + await test_driver.bidi.bluetooth.simulate_adapter({state: "powered-on"}); let availability = await navigator.bluetooth.getAvailability(); assert_true( availability, diff --git a/tests/wpt/tests/bluetooth/legacy/adapter/cross-origin-iframe-getAvailability.sub.https.window.js b/tests/wpt/tests/bluetooth/bidi/adapter/cross-origin-iframe-getAvailability.sub.https.window.js similarity index 85% rename from tests/wpt/tests/bluetooth/legacy/adapter/cross-origin-iframe-getAvailability.sub.https.window.js rename to tests/wpt/tests/bluetooth/bidi/adapter/cross-origin-iframe-getAvailability.sub.https.window.js index 54abfbb5cef..fd638b55561 100644 --- a/tests/wpt/tests/bluetooth/legacy/adapter/cross-origin-iframe-getAvailability.sub.https.window.js +++ b/tests/wpt/tests/bluetooth/bidi/adapter/cross-origin-iframe-getAvailability.sub.https.window.js @@ -1,4 +1,4 @@ -// META: script=/resources/testdriver.js +// META: script=/resources/testdriver.js?feature=bidi // META: script=/resources/testdriver-vendor.js // META: script=/bluetooth/resources/bluetooth-test.js // META: script=/bluetooth/resources/bluetooth-fake-devices.js @@ -9,8 +9,8 @@ const cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' + '/bluetooth/resources/health-thermometer-iframe.html' let iframe = document.createElement('iframe'); -bluetooth_test(async () => { - await navigator.bluetooth.test.simulateCentral({state: 'powered-on'}); +bluetooth_bidi_test(async () => { + await test_driver.bidi.bluetooth.simulate_adapter({state: "powered-on"}); await new Promise(resolve => { iframe.src = cross_origin_src; document.body.appendChild(iframe); diff --git a/tests/wpt/tests/bluetooth/resources/bluetooth-test.js b/tests/wpt/tests/bluetooth/resources/bluetooth-test.js index e98fb454c9d..a771abbd51b 100644 --- a/tests/wpt/tests/bluetooth/resources/bluetooth-test.js +++ b/tests/wpt/tests/bluetooth/resources/bluetooth-test.js @@ -89,6 +89,26 @@ function bluetooth_test( }, name, properties); } +/** + * These tests rely on the User Agent providing an implementation of the + * WebDriver-Bidi for testing Web Bluetooth + * https://webbluetoothcg.github.io/web-bluetooth/#automated-testing + * @param {function{*}: Promise<*>} test_function The Web Bluetooth test to run. + * @param {string} name The name or description of the test. + * @param {object} properties An object containing extra options for the test. + * @param {Boolean} validate_response_consumed Whether to validate all response + * consumed or not. + * @returns {Promise} Resolves if Web Bluetooth test ran successfully, or + * rejects if the test failed. + */ +function bluetooth_bidi_test( + test_function, name, properties, validate_response_consumed = true) { +return promise_test(async (t) => { + assert_implements(navigator.bluetooth, 'missing navigator.bluetooth'); + await test_function(t); +}, name, properties); +} + /** * Test Helpers */ diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-001.html b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-001.html index 6d77cf9a9d4..7c2cbbb6795 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-001.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-001.html @@ -1,7 +1,7 @@ Tests that getComputedStyle() resolves anchor functions - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-002.html b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-002.html index a3e00d50485..23ac69ee759 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-002.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-002.html @@ -1,7 +1,7 @@ Tests getComputedStyle() resolving anchor() in fragmentation context - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-003.html b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-003.html index d23558aef5b..cce88dd8421 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-003.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-getComputedStyle-003.html @@ -1,7 +1,7 @@ Tests that getComputedStyle() returns used position fallback style - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-scroll-004.html b/tests/wpt/tests/css/css-anchor-position/anchor-scroll-004.html index e21507acb64..f551d3ba337 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-scroll-004.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-scroll-004.html @@ -1,7 +1,7 @@ Tests anchor positioned scrolling with relatively positioned inline containers - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html b/tests/wpt/tests/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html index 8a53ae24e5b..5cf17919e8d 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-scroll-composited-scrolling-006.html @@ -1,7 +1,7 @@ Tests anchor-positioned element paint order in composited scrolling - + +
+
+ diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-transition-attr.html b/tests/wpt/tests/css/css-anchor-position/anchor-transition-attr.html index 50f1154532e..540ab893efc 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-transition-attr.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-transition-attr.html @@ -1,6 +1,6 @@ CSS Anchor Positioning: Transition when the anchor attribute changes - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-transition-default.html b/tests/wpt/tests/css/css-anchor-position/anchor-transition-default.html index 1bee0cbbe4c..e5576e6ad34 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-transition-default.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-transition-default.html @@ -1,6 +1,6 @@ CSS Anchor Positioning: Transition when position-anchor changes - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-transition-eval.html b/tests/wpt/tests/css/css-anchor-position/anchor-transition-eval.html index cf65742b2dc..ef4cccc2794 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-transition-eval.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-transition-eval.html @@ -1,6 +1,6 @@ CSS Anchor Positioning: Transition when the result of anchor()/anchor-size() changes - + diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-transition-name.html b/tests/wpt/tests/css/css-anchor-position/anchor-transition-name.html index ea7b403e612..8dae70ccdcc 100644 --- a/tests/wpt/tests/css/css-anchor-position/anchor-transition-name.html +++ b/tests/wpt/tests/css/css-anchor-position/anchor-transition-name.html @@ -1,6 +1,6 @@ CSS Anchor Positioning: Transition when the dereferenced anchor name changes - + diff --git a/tests/wpt/tests/css/css-anchor-position/position-anchor-003.html b/tests/wpt/tests/css/css-anchor-position/position-anchor-003.html index 6117027e220..e3640795e5f 100644 --- a/tests/wpt/tests/css/css-anchor-position/position-anchor-003.html +++ b/tests/wpt/tests/css/css-anchor-position/position-anchor-003.html @@ -1,6 +1,6 @@ Tests that layout is updated on position-anchor value changes - + diff --git a/tests/wpt/tests/css/css-anchor-position/position-area-scrolling-004.tentative.html b/tests/wpt/tests/css/css-anchor-position/position-area-scrolling-004.tentative.html new file mode 100644 index 00000000000..49b5ab03ee9 --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-area-scrolling-004.tentative.html @@ -0,0 +1,17 @@ + +Avoid negative IMCB correctly when scrolled past the anchor + + + +

Test passes if there is a filled green square and no red.

+
+
+ +
+
+ diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-001.html b/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-001.html new file mode 100644 index 00000000000..b41e326800c --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-001.html @@ -0,0 +1,10 @@ + +position-try-fallbacks:flip-block on bottom:anchor(outside) + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
diff --git a/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-002.html b/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-002.html new file mode 100644 index 00000000000..800a6dc6a35 --- /dev/null +++ b/tests/wpt/tests/css/css-anchor-position/position-try-fallbacks-002.html @@ -0,0 +1,10 @@ + +position-try-fallbacks:flip-block on bottom:anchor(inside) + + + +

Test passes if there is a filled green square and no red.

+
+
+
+
diff --git a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-computed.html b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-computed.html index c238ddfb969..402c4b6659e 100644 --- a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-computed.html +++ b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-computed.html @@ -11,9 +11,18 @@
diff --git a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-invalid.html b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-invalid.html index 51f8e05700a..490b8613945 100644 --- a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-invalid.html +++ b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-invalid.html @@ -11,8 +11,12 @@ diff --git a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-valid.html b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-valid.html index 62ee2630ace..61005759d12 100644 --- a/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-valid.html +++ b/tests/wpt/tests/css/css-borders/tentative/parsing/corner-shape-valid.html @@ -9,10 +9,31 @@ diff --git a/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo-ref.html b/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo-ref.html new file mode 100644 index 00000000000..ffd970fb3c1 --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo-ref.html @@ -0,0 +1,31 @@ + +Container-relative units in ::selection (ref) + + +
+
+ Some text +
+
+ + diff --git a/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo.html b/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo.html new file mode 100644 index 00000000000..361f888ceff --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/container-units-selection-pseudo.html @@ -0,0 +1,35 @@ + +Container-relative units in ::selection + + + +
+
+ Some text +
+
+ + diff --git a/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/WEB_FEATURES.yml b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/WEB_FEATURES.yml new file mode 100644 index 00000000000..9ea6ae9549c --- /dev/null +++ b/tests/wpt/tests/css/css-conditional/container-queries/scroll-state/WEB_FEATURES.yml @@ -0,0 +1,3 @@ +features: +- name: container-scroll-state-queries + files: "**" diff --git a/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-computed.html b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-computed.html new file mode 100644 index 00000000000..3dd52b33574 --- /dev/null +++ b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-computed.html @@ -0,0 +1,16 @@ + +CSS Display: getComputedStyle().readingOrder + + + + + + +
+ + diff --git a/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-invalid.html b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-invalid.html new file mode 100644 index 00000000000..8dcb0d407fc --- /dev/null +++ b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-invalid.html @@ -0,0 +1,20 @@ + +CSS Display: parsing reading-order with invalid values + + + + + + + + diff --git a/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-valid.html b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-valid.html new file mode 100644 index 00000000000..d2cbe956b80 --- /dev/null +++ b/tests/wpt/tests/css/css-display/reading-flow/tentative/reading-order-valid.html @@ -0,0 +1,15 @@ + +CSS Display: parsing reading-order with valid values + + + + + + + + diff --git a/tests/wpt/tests/css/css-easing/linear-timing-functions-syntax.html b/tests/wpt/tests/css/css-easing/linear-timing-functions-syntax.html index 3b8e106b6aa..0c949e9ea7d 100644 --- a/tests/wpt/tests/css/css-easing/linear-timing-functions-syntax.html +++ b/tests/wpt/tests/css/css-easing/linear-timing-functions-syntax.html @@ -15,9 +15,17 @@ diff --git a/tests/wpt/tests/css/css-easing/timing-functions-syntax-computed.html b/tests/wpt/tests/css/css-easing/timing-functions-syntax-computed.html index b03d2a0e233..243b2938505 100644 --- a/tests/wpt/tests/css/css-easing/timing-functions-syntax-computed.html +++ b/tests/wpt/tests/css/css-easing/timing-functions-syntax-computed.html @@ -21,14 +21,18 @@ test_computed_value("animation-timing-function", "ease-in-out"); test_computed_value("animation-timing-function", "cubic-bezier(0.1, 0.2, 0.8, 0.9)"); test_computed_value("animation-timing-function", "cubic-bezier(0, -2, 1, 3)"); test_computed_value("animation-timing-function", "cubic-bezier(0, 0.7, 1, 1.3)"); - +test_computed_value("animation-timing-function", "cubic-bezier(calc(-2), calc(0.7 / 2), calc(1.5), calc(0))", "cubic-bezier(0, 0.35, 1, 0)",); test_computed_value("animation-timing-function", "steps(4, start)"); test_computed_value("animation-timing-function", "steps(2, end)", "steps(2)"); +test_computed_value("animation-timing-function", "steps( 2, end )", "steps(2)"); test_computed_value("animation-timing-function", "steps(2, jump-start)"); test_computed_value("animation-timing-function", "steps(2, jump-end)", "steps(2)"); test_computed_value("animation-timing-function", "steps(2, jump-both)"); test_computed_value("animation-timing-function", "steps(2, jump-none)"); +test_computed_value("animation-timing-function", "steps(calc(-10), start)", "steps(1, start)"); +test_computed_value("animation-timing-function", "steps(calc(5 / 2), start)", "steps(3, start)"); +test_computed_value("animation-timing-function", "steps(calc(1), jump-none)", "steps(2, jump-none)"); test_computed_value("animation-timing-function", "linear, ease, linear"); diff --git a/tests/wpt/tests/css/css-easing/timing-functions-syntax-invalid.html b/tests/wpt/tests/css/css-easing/timing-functions-syntax-invalid.html index b279369b3bd..1b748782ff6 100644 --- a/tests/wpt/tests/css/css-easing/timing-functions-syntax-invalid.html +++ b/tests/wpt/tests/css/css-easing/timing-functions-syntax-invalid.html @@ -18,9 +18,12 @@ test_invalid_value("animation-timing-function", "cubic-bezier(1, 2, 3, infinite) test_invalid_value("animation-timing-function", "cubic-bezier(1, 2, 3, 4, 5)"); test_invalid_value("animation-timing-function", "cubic-bezier(-0.1, 0.1, 0.5, 0.9)"); test_invalid_value("animation-timing-function", "cubic-bezier(0.5, 0.1, 1.1, 0.9)"); - test_invalid_value("animation-timing-function", "initial, cubic-bezier(0, -2, 1, 3)"); test_invalid_value("animation-timing-function", "cubic-bezier(0, -2, 1, 3), initial"); +test_invalid_value("animation-timing-function", "steps(1, jump-none)"); +test_invalid_value("animation-timing-function", "steps(-100, jump-none)"); +test_invalid_value("animation-timing-function", "steps(0, start)"); +test_invalid_value("animation-timing-function", "steps(-100, start)"); diff --git a/tests/wpt/tests/css/css-easing/timing-functions-syntax-valid.html b/tests/wpt/tests/css/css-easing/timing-functions-syntax-valid.html index 07f2c2cfb96..b858f45f4a4 100644 --- a/tests/wpt/tests/css/css-easing/timing-functions-syntax-valid.html +++ b/tests/wpt/tests/css/css-easing/timing-functions-syntax-valid.html @@ -20,7 +20,7 @@ test_valid_value("animation-timing-function", "ease-in-out"); test_valid_value("animation-timing-function", "cubic-bezier(0.1, 0.2, 0.8, 0.9)"); test_valid_value("animation-timing-function", "cubic-bezier(0, -2, 1, 3)"); test_valid_value("animation-timing-function", "cubic-bezier(0, 0.7, 1, 1.3)"); - +test_valid_value("animation-timing-function", "cubic-bezier(calc(-2), calc(0.7 / 2), calc(1.5), calc(0))", "cubic-bezier(calc(-2), calc(0.35), calc(1.5), calc(0))"); test_valid_value("animation-timing-function", "steps(4, start)"); test_valid_value("animation-timing-function", "steps(2, end)", "steps(2)"); @@ -29,6 +29,9 @@ test_valid_value("animation-timing-function", "steps(2, jump-start)"); test_valid_value("animation-timing-function", "steps(2, jump-end)", "steps(2)"); test_valid_value("animation-timing-function", "steps(2, jump-both)"); test_valid_value("animation-timing-function", "steps(2, jump-none)"); +test_valid_value("animation-timing-function", "steps(calc(-10), start)"); +test_valid_value("animation-timing-function", "steps(calc(5 / 2), start)", "steps(calc(2.5), start)"); +test_valid_value("animation-timing-function", "steps(calc(1), jump-none)"); test_valid_value("animation-timing-function", "linear, ease, linear"); diff --git a/tests/wpt/tests/css/css-flexbox/flexbox-vert-lr-with-img.html b/tests/wpt/tests/css/css-flexbox/flexbox-vert-lr-with-img.html new file mode 100644 index 00000000000..789a2280e18 --- /dev/null +++ b/tests/wpt/tests/css/css-flexbox/flexbox-vert-lr-with-img.html @@ -0,0 +1,15 @@ + + + + + + + + + +

Test passes if there is a filled green square.

+
+ +
+ + diff --git a/tests/wpt/tests/css/css-fonts/animations/font-style-interpolation.html b/tests/wpt/tests/css/css-fonts/animations/font-style-interpolation.html index 452b5215ec4..4666025d545 100644 --- a/tests/wpt/tests/css/css-fonts/animations/font-style-interpolation.html +++ b/tests/wpt/tests/css/css-fonts/animations/font-style-interpolation.html @@ -46,7 +46,7 @@ test_interpolation({ }, [ {at: -2, expect: 'oblique -20deg'}, {at: -0.25, expect: 'oblique -2.5deg'}, - {at: 0, expect: 'oblique 0deg'}, + {at: 0, expect: 'normal'}, {at: 0.3, expect: 'oblique 3deg'}, {at: 0.6, expect: 'oblique 6deg'}, {at: 1, expect: 'oblique 10deg'}, @@ -74,7 +74,7 @@ test_interpolation({ }, [ { at: -2, expect: 'oblique -40deg' }, { at: -0.25, expect: 'oblique -5deg' }, - { at: 0, expect: 'oblique 0deg' }, + { at: 0, expect: 'normal' }, { at: 0.3, expect: 'oblique 6deg' }, { at: 0.6, expect: 'oblique 12deg' }, { at: 1, expect: 'oblique 20deg' }, @@ -89,7 +89,7 @@ test_interpolation({ { at: -1, expect: 'oblique 40deg' }, { at: 0, expect: 'oblique 20deg' }, { at: 0.5, expect: 'oblique 10deg' }, - { at: 1, expect: 'oblique 0deg' }, + { at: 1, expect: 'normal' }, { at: 1.5, expect: 'oblique -10deg' }, ]); @@ -101,7 +101,7 @@ test_interpolation({ { at: -2, expect: 'oblique -90deg' }, { at: -1, expect: 'oblique -90deg' }, { at: 0, expect: 'oblique -90deg' }, - { at: 0.5, expect: 'oblique 0deg' }, + { at: 0.5, expect: 'normal' }, { at: 1, expect: 'oblique 90deg' }, { at: 1.5, expect: 'oblique 90deg' }, ]); diff --git a/tests/wpt/tests/css/css-fonts/font-face-style-normal.html b/tests/wpt/tests/css/css-fonts/font-face-style-normal.html new file mode 100644 index 00000000000..440661b82bb --- /dev/null +++ b/tests/wpt/tests/css/css-fonts/font-face-style-normal.html @@ -0,0 +1,54 @@ + + + + +CSS Fonts: parsing 'normal' in the font-style descriptor + + + + + + + + + + + diff --git a/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only-ref.html b/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only-ref.html new file mode 100644 index 00000000000..31b49789edd --- /dev/null +++ b/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only-ref.html @@ -0,0 +1,20 @@ + + + +CSS font-synthesis-style:oblique-only reference + + + +
A
+
A
+
A
+
A
+
A
diff --git a/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only.html b/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only.html new file mode 100644 index 00000000000..11a5aa075a1 --- /dev/null +++ b/tests/wpt/tests/css/css-fonts/font-synthesis-style-oblique-only.html @@ -0,0 +1,40 @@ + + + +CSS font-synthesis-style:oblique-only test + + + + + + + + + +
A
+ + +
B
+ + +
B
+ + +
B
+ + +
A
diff --git a/tests/wpt/tests/css/css-fonts/font-variant-caps-invalidation-container-sizing.html b/tests/wpt/tests/css/css-fonts/font-variant-caps-invalidation-container-sizing.html new file mode 100644 index 00000000000..54a00dc360f --- /dev/null +++ b/tests/wpt/tests/css/css-fonts/font-variant-caps-invalidation-container-sizing.html @@ -0,0 +1,25 @@ + + + + + + + + + +
+ X +
+ + + diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-style-computed.html b/tests/wpt/tests/css/css-fonts/parsing/font-style-computed.html index fde74150080..acb870cdc1f 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-style-computed.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-style-computed.html @@ -28,9 +28,13 @@ test_computed_value('font-style', 'normal'); test_computed_value('font-style', 'italic'); test_computed_value('font-style', 'oblique'); +test_computed_value('font-style', 'oblique 0deg', 'normal'); +test_computed_value('font-style', 'oblique calc(10deg - 10deg)', 'normal'); + test_computed_value('font-style', 'oblique 10deg'); test_computed_value('font-style', 'oblique -10deg'); -test_computed_value('font-style', 'oblique 0deg'); +test_computed_value('font-style', 'oblique 14deg', 'oblique'); +test_computed_value('font-style', 'oblique -14deg'); test_computed_value('font-style', 'oblique -90deg'); test_computed_value('font-style', 'oblique 90deg'); test_computed_value('font-style', 'oblique 10grad', 'oblique 9deg'); diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-style-valid.html b/tests/wpt/tests/css/css-fonts/parsing/font-style-valid.html index e26733aaddd..95c5af3c416 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-style-valid.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-style-valid.html @@ -15,9 +15,13 @@ test_valid_value('font-style', 'normal'); test_valid_value('font-style', 'italic'); test_valid_value('font-style', 'oblique'); +test_valid_value('font-style', 'oblique 0deg', 'normal'); +test_valid_value('font-style', 'oblique calc(10deg - 10deg)', 'oblique calc(0deg)'); + test_valid_value('font-style', 'oblique 10deg'); test_valid_value('font-style', 'oblique -10deg'); -test_valid_value('font-style', 'oblique 0deg'); +test_valid_value('font-style', 'oblique 14deg', 'oblique'); +test_valid_value('font-style', 'oblique -14deg'); test_valid_value('font-style', 'oblique -90deg'); test_valid_value('font-style', 'oblique 90deg'); test_valid_value('font-style', 'oblique 10grad'); diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-computed.html b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-computed.html index b7f121c067e..80dc3575075 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-computed.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-computed.html @@ -4,6 +4,7 @@ CSS Fonts Module: getComputedStyle().fontSynthesis + @@ -15,17 +16,24 @@ test_computed_value('font-synthesis', 'none'); test_computed_value('font-synthesis', 'weight'); test_computed_value('font-synthesis', 'style'); +test_computed_value('font-synthesis', 'oblique-only'); test_computed_value('font-synthesis', 'small-caps'); test_computed_value('font-synthesis', 'position'); test_computed_value('font-synthesis', 'small-caps position'); test_computed_value('font-synthesis', 'style small-caps'); test_computed_value('font-synthesis', 'style position'); test_computed_value('font-synthesis', 'style small-caps position'); +test_computed_value('font-synthesis', 'oblique-only small-caps'); +test_computed_value('font-synthesis', 'oblique-only position'); +test_computed_value('font-synthesis', 'oblique-only small-caps position'); test_computed_value('font-synthesis', 'weight small-caps'); test_computed_value('font-synthesis', 'weight style'); +test_computed_value('font-synthesis', 'weight oblique-only'); test_computed_value('font-synthesis', 'weight position'); test_computed_value('font-synthesis', 'weight style small-caps'); test_computed_value('font-synthesis', 'weight style small-caps position'); +test_computed_value('font-synthesis', 'weight oblique-only small-caps'); +test_computed_value('font-synthesis', 'weight oblique-only small-caps position'); diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-invalid.html b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-invalid.html index e68c07bcbac..6293d2d34e9 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-invalid.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-invalid.html @@ -4,7 +4,8 @@ CSS Fonts Module: parsing font-synthesis with invalid values - + + @@ -14,8 +15,12 @@ test_invalid_value('font-synthesis', 'auto'); test_invalid_value('font-synthesis', 'none weight'); test_invalid_value('font-synthesis', 'none style'); +test_invalid_value('font-synthesis', 'none oblique-only'); test_invalid_value('font-synthesis', 'none position'); test_invalid_value('font-synthesis', 'style none'); +test_invalid_value('font-synthesis', 'style oblique-only'); +test_invalid_value('font-synthesis', 'oblique-only style'); +test_invalid_value('font-synthesis', 'oblique-only none'); test_invalid_value('font-synthesis', 'none small-caps'); test_invalid_value('font-synthesis', 'small-caps none'); test_invalid_value('font-synthesis', 'position none'); diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html index e0fc0f4a2a9..b16a75caf0f 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-invalid.html @@ -3,8 +3,9 @@ CSS Fonts Module Level 4: parsing font-synthesis-style with invalid values - - + + + @@ -13,6 +14,8 @@ diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-valid.html b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-valid.html index 5b1c01561a6..4dac2ef7f4f 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-valid.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-style-valid.html @@ -3,8 +3,9 @@ CSS Fonts Module Level 4: parsing font-synthesis-style with valid values - - + + + @@ -13,6 +14,7 @@ diff --git a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-valid.html b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-valid.html index 84663e8a3e9..f1e2d21bf2d 100644 --- a/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-valid.html +++ b/tests/wpt/tests/css/css-fonts/parsing/font-synthesis-valid.html @@ -4,7 +4,7 @@ CSS Fonts Module: parsing font-synthesis with valid values - + @@ -14,17 +14,26 @@ test_valid_value('font-synthesis', 'none'); test_valid_value('font-synthesis', 'weight'); test_valid_value('font-synthesis', 'style'); +test_valid_value('font-synthesis', 'oblique-only'); test_valid_value('font-synthesis', 'small-caps'); test_valid_value('font-synthesis', 'position'); test_valid_value('font-synthesis', 'style weight', 'weight style'); +test_valid_value('font-synthesis', 'oblique-only weight', 'weight oblique-only'); test_valid_value('font-synthesis', 'small-caps weight', 'weight small-caps'); test_valid_value('font-synthesis', 'small-caps style', 'style small-caps'); +test_valid_value('font-synthesis', 'small-caps oblique-only', 'oblique-only small-caps'); test_valid_value('font-synthesis', 'style weight small-caps', 'weight style small-caps'); test_valid_value('font-synthesis', 'style small-caps weight ', 'weight style small-caps'); test_valid_value('font-synthesis', 'small-caps style weight ', 'weight style small-caps'); +test_valid_value('font-synthesis', 'oblique-only weight small-caps', 'weight oblique-only small-caps'); +test_valid_value('font-synthesis', 'oblique-only small-caps weight ', 'weight oblique-only small-caps'); +test_valid_value('font-synthesis', 'small-caps oblique-only weight ', 'weight oblique-only small-caps'); test_valid_value('font-synthesis', 'position style', 'style position'); +test_valid_value('font-synthesis', 'position oblique-only', 'oblique-only position'); test_valid_value('font-synthesis', 'position weight style', 'weight style position'); +test_valid_value('font-synthesis', 'position weight oblique-only', 'weight oblique-only position'); test_valid_value('font-synthesis', 'position weight small-caps style', 'weight style small-caps position'); +test_valid_value('font-synthesis', 'position weight small-caps oblique-only', 'weight oblique-only small-caps position'); diff --git a/tests/wpt/tests/css/css-fonts/variations/at-font-face-font-matching.html b/tests/wpt/tests/css/css-fonts/variations/at-font-face-font-matching.html index e56334f2da7..ba18f9d5ab2 100644 --- a/tests/wpt/tests/css/css-fonts/variations/at-font-face-font-matching.html +++ b/tests/wpt/tests/css/css-fonts/variations/at-font-face-font-matching.html @@ -126,7 +126,7 @@ } function createFontFaceRules(fontFaceFamily, descriptorName, expectedMatch, unexpectedMatch) { dynamicStyles.innerHTML = - "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-100-kerned.ttf'); "+ descriptorName + ": " + expectedMatch + "; }" + + "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-100-kerned.ttf'); " + descriptorName + ": " + expectedMatch + "; }" + "@font-face { font-family: " + fontFaceFamily + "; src: url('./resources/csstest-weights-200-kerned.ttf'); " + descriptorName + ": " + unexpectedMatch + "; }"; return Promise.all([ @@ -179,8 +179,8 @@ ]); testDescriptor("font-style", [ - { value: "normal", testDescriptors: ["normal", "oblique 0deg", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, - { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique 0deg", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, + { value: "normal", testDescriptors: ["normal", "oblique 10deg 40deg", "oblique 20deg 30deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, + { value: "italic", testDescriptors: ["italic", "oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 5deg 10deg", "oblique 5deg", "normal", "oblique -60deg -30deg", "oblique -50deg -40deg" ] }, { value: "oblique 20deg", testDescriptors: ["oblique 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 21deg", testDescriptors: ["oblique 21deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "oblique 20deg", "oblique 10deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, { value: "oblique 10deg", testDescriptors: ["oblique 10deg", "oblique 5deg", "oblique 15deg 20deg", "oblique 30deg 60deg", "oblique 40deg 50deg", "italic", "oblique 0deg", "oblique -50deg -20deg", "oblique -40deg -30deg" ] }, diff --git a/tests/wpt/tests/css/css-fonts/variations/font-style-parsing.html b/tests/wpt/tests/css/css-fonts/variations/font-style-parsing.html index 1d22caa2dec..bc315932e87 100644 --- a/tests/wpt/tests/css/css-fonts/variations/font-style-parsing.html +++ b/tests/wpt/tests/css/css-fonts/variations/font-style-parsing.html @@ -14,7 +14,7 @@ { style: "italic 20deg", expectedResult: false, message: "'italic' followed by angle is invalid" }, { style: "italic a", expectedResult: false, message: "'italic' followed by non-number is invalid" }, { style: "oblique", expectedResult: true, message: "'oblique' is valid" }, - { style: "oblique 0deg", expectedResult: true, message: "'oblique' followed by zero degrees is valid" }, + { style: "oblique 0deg", expectedResult: true, message: "'oblique' followed by zero degrees is valid", expectedValue: "normal" }, { style: "oblique 20deg", expectedResult: true, message: "'oblique' followed by positive angle in degrees is valid" }, { style: "oblique 0.5rad", expectedResult: true, message: "'oblique' followed by positive angle in radians is valid", expectedValue: /^oblique 28\.\d*deg$/ }, { style: "oblique 20grad", expectedResult: true, message: "'oblique' followed by positive angle in gradians is valid", expectedValue: "oblique 18deg" }, diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-computed.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-computed.html new file mode 100644 index 00000000000..0490428f3e7 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-computed.html @@ -0,0 +1,24 @@ + + + + + CSS Gaps: *-rule-break getComputedStyle() + + + + + + + + +
+ + + diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-invalid.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-invalid.html new file mode 100644 index 00000000000..a6eb68a1644 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-invalid.html @@ -0,0 +1,21 @@ + + + + + CSS Gaps: parsing *-rule-break with invalid values + + + + + + + +
+ + + diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-valid.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-valid.html new file mode 100644 index 00000000000..02f33880619 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-break-valid.html @@ -0,0 +1,23 @@ + + + + + CSS Gaps: parsing *-rule-break with valid values + + + + + + + +
+ + + diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-computed.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-computed.html new file mode 100644 index 00000000000..dd59018ccf5 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-computed.html @@ -0,0 +1,30 @@ + + + + + CSS Gaps: *-rule-outset getComputedStyle() + + + + + + + + +
+ + + + diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-invalid.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-invalid.html new file mode 100644 index 00000000000..f39139ade83 --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-invalid.html @@ -0,0 +1,21 @@ + + + + + CSS Gaps: parsing *-rule-outset with invalid values + + + + + + + +
+ + + diff --git a/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-valid.html b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-valid.html new file mode 100644 index 00000000000..6ad45bbc7ac --- /dev/null +++ b/tests/wpt/tests/css/css-gaps/tentative/parsing/rule-outset-valid.html @@ -0,0 +1,22 @@ + + + + + CSS Gaps: parsing *-rule-outset with valid values + + + + + + + +
+ + + diff --git a/tests/wpt/tests/css/css-images/gradient/linear-gradient-relative-currentcolor-stop.html b/tests/wpt/tests/css/css-images/gradient/linear-gradient-relative-currentcolor-stop.html new file mode 100644 index 00000000000..901b0894e15 --- /dev/null +++ b/tests/wpt/tests/css/css-images/gradient/linear-gradient-relative-currentcolor-stop.html @@ -0,0 +1,25 @@ + +linear-gradient() with relative color stops referencing currentcolor + + + + +
+
+
+
diff --git a/tests/wpt/tests/css/css-mixins/at-function-cssom.tentative.html b/tests/wpt/tests/css/css-mixins/at-function-cssom.tentative.html index c8c3ee475bf..dbf157b3c2f 100644 --- a/tests/wpt/tests/css/css-mixins/at-function-cssom.tentative.html +++ b/tests/wpt/tests/css/css-mixins/at-function-cssom.tentative.html @@ -185,6 +185,34 @@ test(t => { assert_array_equals(Array.from(descriptors), ['--x', 'result']);; }, 'Indexed property getter'); +// Conditional rules + +test(t => { + let sheet = new CSSStyleSheet(); + sheet.replaceSync(` + @function --foo() { + @supports (width: 100px) { + result: 100px; + } + result: 200px; + } + `); + assert_equals(sheet.cssRules.length, 1); + let functionRule = sheet.cssRules[0]; + assert_true(functionRule instanceof CSSFunctionRule); + assert_equals(functionRule.cssRules.length, 2); + let supportsRule = functionRule.cssRules[0]; + assert_true(supportsRule instanceof CSSSupportsRule); + assert_true(supportsRule.cssRules[0] instanceof CSSFunctionDeclarations); + assert_equals(supportsRule.cssRules[0].style?.result, '100px'); + + let declarationsRule = functionRule.cssRules[1]; + assert_true(declarationsRule instanceof CSSFunctionDeclarations); + let descriptors = declarationsRule.style; + assert_true(descriptors instanceof CSSFunctionDescriptors); + assert_equals(descriptors.result, '200px'); +}, '@supports in body'); + // CSSFunctionRule test(t => { diff --git a/tests/wpt/tests/css/css-mixins/dashed-function-cycles.tentative.html b/tests/wpt/tests/css/css-mixins/dashed-function-cycles.tentative.html new file mode 100644 index 00000000000..3eddd42801c --- /dev/null +++ b/tests/wpt/tests/css/css-mixins/dashed-function-cycles.tentative.html @@ -0,0 +1,312 @@ + +Custom Functions: Handling cycles + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/wpt/tests/css/css-mixins/dashed-function-eval.html b/tests/wpt/tests/css/css-mixins/dashed-function-eval.html index 8213201eff8..7726e832e02 100644 --- a/tests/wpt/tests/css/css-mixins/dashed-function-eval.html +++ b/tests/wpt/tests/css/css-mixins/dashed-function-eval.html @@ -425,6 +425,204 @@ resolves: https://github.com/w3c/csswg-drafts/issues/10954 --> + + + + + + + + + + + + + + + + + + + + + +