diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/web-nfc/resources/nfc-helpers.js | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/web-nfc/resources/nfc-helpers.js')
-rw-r--r-- | testing/web-platform/tests/web-nfc/resources/nfc-helpers.js | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/testing/web-platform/tests/web-nfc/resources/nfc-helpers.js b/testing/web-platform/tests/web-nfc/resources/nfc-helpers.js new file mode 100644 index 0000000000..35154e287d --- /dev/null +++ b/testing/web-platform/tests/web-nfc/resources/nfc-helpers.js @@ -0,0 +1,232 @@ +'use strict'; +// These tests rely on the User Agent providing an implementation of +// platform nfc backends. +// +// In Chromium-based browsers this implementation is provided by a polyfill +// in order to reduce the amount of test-only code shipped to users. To enable +// these tests the browser must be run with these options: +// +// --enable-blink-features=MojoJS,MojoJSTest + +async function loadChromiumResources() { + await loadScript('/resources/testdriver.js'); + await loadScript('/resources/testdriver-vendor.js'); + await import('/resources/chromium/nfc-mock.js'); +} + +async function initialize_nfc_tests() { + if (typeof WebNFCTest === 'undefined') { + const script = document.createElement('script'); + script.src = '/resources/test-only-api.js'; + script.async = false; + const p = new Promise((resolve, reject) => { + script.onload = () => { resolve(); }; + script.onerror = e => { reject(e); }; + }) + document.head.appendChild(script); + await p; + + if (isChromiumBased) { + await loadChromiumResources(); + } + } + assert_implements( WebNFCTest, 'WebNFC testing interface is unavailable.'); + let NFCTest = new WebNFCTest(); + await NFCTest.initialize(); + return NFCTest; +} + +function nfc_test(func, name, properties) { + promise_test(async t => { + let NFCTest = await initialize_nfc_tests(); + t.add_cleanup(async () => { + await NFCTest.reset(); + }); + await func(t, NFCTest.getMockNFC()); + }, name, properties); +} + +const test_text_data = 'Test text data.'; +const test_text_byte_array = new TextEncoder('utf-8').encode(test_text_data); +const test_number_data = 42; +const test_json_data = {level: 1, score: 100, label: 'Game'}; +const test_url_data = 'https://w3c.github.io/web-nfc/'; +const test_message_origin = 'https://127.0.0.1:8443'; +const test_buffer_data = new ArrayBuffer(test_text_byte_array.length); +const test_buffer_view = new Uint8Array(test_buffer_data); +test_buffer_view.set(test_text_byte_array); +const fake_tag_serial_number = 'c0:45:00:02'; +const test_record_id = '/test_path/test_id'; + +const NFCHWStatus = {}; +// OS-level NFC setting is ON +NFCHWStatus.ENABLED = 1; +// no NFC chip +NFCHWStatus.NOT_SUPPORTED = NFCHWStatus.ENABLED + 1; +// OS-level NFC setting OFF +NFCHWStatus.DISABLED = NFCHWStatus.NOT_SUPPORTED + 1; + +function encodeTextToArrayBuffer(string, encoding) { + // Only support 'utf-8', 'utf-16', 'utf-16be', and 'utf-16le'. + assert_true( + encoding === 'utf-8' || encoding === 'utf-16' || + encoding === 'utf-16be' || encoding === 'utf-16le'); + + if (encoding === 'utf-8') { + return new TextEncoder().encode(string).buffer; + } + + if (encoding === 'utf-16') { + let uint16array = new Uint16Array(string.length); + for (let i = 0; i < string.length; i++) { + uint16array[i] = string.codePointAt(i); + } + return uint16array.buffer; + } + + const littleEndian = encoding === 'utf-16le'; + const buffer = new ArrayBuffer(string.length * 2); + const view = new DataView(buffer); + for (let i = 0; i < string.length; i++) { + view.setUint16(i * 2, string.codePointAt(i), littleEndian); + } + return buffer; +} + +function createMessage(records) { + if (records !== undefined) { + let message = {}; + message.records = records; + return message; + } +} + +function createRecord(recordType, data, id, mediaType, encoding, lang) { + let record = {}; + if (recordType !== undefined) + record.recordType = recordType; + if (id !== undefined) + record.id = id; + if (mediaType !== undefined) + record.mediaType = mediaType; + if (encoding !== undefined) + record.encoding = encoding; + if (lang !== undefined) + record.lang = lang; + if (data !== undefined) + record.data = data; + return record; +} + +function createTextRecord(data, encoding, lang) { + return createRecord('text', data, test_record_id, undefined, encoding, lang); +} + +function createMimeRecordFromJson(json) { + return createRecord( + 'mime', new TextEncoder('utf-8').encode(JSON.stringify(json)), + test_record_id, 'application/json'); +} + +function createMimeRecord(buffer) { + return createRecord( + 'mime', buffer, test_record_id, 'application/octet-stream'); +} + +function createUnknownRecord(buffer) { + return createRecord('unknown', buffer, test_record_id); +} + +function createUrlRecord(url, isAbsUrl) { + if (isAbsUrl) { + return createRecord('absolute-url', url, test_record_id); + } + return createRecord('url', url, test_record_id); +} + +// Compares NDEFMessageSource that was provided to the API +// (e.g. NDEFReader.write), and NDEFMessage that was received by the +// mock NFC service. +function assertNDEFMessagesEqual(providedMessage, receivedMessage) { + // If simple data type is passed, e.g. String or ArrayBuffer or + // ArrayBufferView, convert it to NDEFMessage before comparing. + // https://w3c.github.io/web-nfc/#dom-ndefmessagesource + let provided = providedMessage; + if (providedMessage instanceof ArrayBuffer || + ArrayBuffer.isView(providedMessage)) + provided = createMessage([createRecord( + 'mime', providedMessage, undefined /* id */, + 'application/octet-stream')]); + else if (typeof providedMessage === 'string') + provided = createMessage([createRecord('text', providedMessage)]); + + assert_equals(provided.records.length, receivedMessage.data.length, + 'NDEFMessages must have same number of NDEFRecords'); + + // Compare contents of each individual NDEFRecord + for (let i = 0; i < provided.records.length; ++i) + compareNDEFRecords(provided.records[i], receivedMessage.data[i]); +} + +// Used to compare two NDEFMessage, one that is received from +// NDEFReader.onreading() EventHandler and another that is provided to mock NFC +// service. +function assertWebNDEFMessagesEqual(message, expectedMessage) { + assert_equals(message.records.length, expectedMessage.records.length); + + for(let i in message.records) { + let record = message.records[i]; + let expectedRecord = expectedMessage.records[i]; + assert_equals(record.recordType, expectedRecord.recordType); + assert_equals(record.mediaType, expectedRecord.mediaType); + assert_equals(record.id, expectedRecord.id); + assert_equals(record.encoding, expectedRecord.encoding); + assert_equals(record.lang, expectedRecord.lang); + // Compares record data + assert_array_equals(new Uint8Array(record.data), + new Uint8Array(expectedRecord.data)); + } +} + +function testMultiScanOptions(message, scanOptions, unmatchedScanOptions, desc) { + nfc_test(async (t, mockNFC) => { + const ndef1 = new NDEFReader(); + const ndef2 = new NDEFReader(); + const controller = new AbortController(); + + // Reading from unmatched ndef will not be triggered + ndef1.onreading = t.unreached_func("reading event should not be fired."); + unmatchedScanOptions.signal = controller.signal; + await ndef1.scan(unmatchedScanOptions); + + const ndefWatcher = new EventWatcher(t, ndef2, ["reading", "readingerror"]); + const promise = ndefWatcher.wait_for("reading").then(event => { + controller.abort(); + assertWebNDEFMessagesEqual(event.message, new NDEFMessage(message)); + }); + scanOptions.signal = controller.signal; + await ndef2.scan(scanOptions); + + mockNFC.setReadingMessage(message); + await promise; + }, desc); +} + +function testMultiMessages(message, scanOptions, unmatchedMessage, desc) { + nfc_test(async (t, mockNFC) => { + const ndef = new NDEFReader(); + const controller = new AbortController(); + const ndefWatcher = new EventWatcher(t, ndef, ["reading", "readingerror"]); + const promise = ndefWatcher.wait_for("reading").then(event => { + controller.abort(); + assertWebNDEFMessagesEqual(event.message, new NDEFMessage(message)); + }); + scanOptions.signal = controller.signal; + await ndef.scan(scanOptions); + + // Unmatched message will not be read + mockNFC.setReadingMessage(unmatchedMessage); + mockNFC.setReadingMessage(message); + await promise; + }, desc); +} |